ソースを参照

Merge branch 'master' into maint

Bastien Guerry 13 年 前
コミット
9167cba326

+ 37 - 40
EXPERIMENTAL/org-e-latex.el

@@ -24,7 +24,7 @@
 
 
 ;; To test it, run
 ;; To test it, run
 ;;
 ;;
-;;   M-: (org-export-to-buffer 'e-latex "*Test e-LaTeX") RET
+;;   M-: (org-export-to-buffer 'e-latex "*Test e-LaTeX*") RET
 ;;
 ;;
 ;; in an org-mode buffer then switch to the buffer to see the LaTeX
 ;; in an org-mode buffer then switch to the buffer to see the LaTeX
 ;; export.  See contrib/lisp/org-export.el for more details on how
 ;; export.  See contrib/lisp/org-export.el for more details on how
@@ -588,7 +588,7 @@ If there's no caption nor label, return the empty string.
 For non-floats, see `org-e-latex--wrap-label'."
 For non-floats, see `org-e-latex--wrap-label'."
   (let ((caption-str (and caption
   (let ((caption-str (and caption
 			  (org-export-secondary-string
 			  (org-export-secondary-string
-			   caption 'latex info)))
+			   caption 'e-latex info)))
 	(label-str (if label (format "\\label{%s}" label) "")))
 	(label-str (if label (format "\\label{%s}" label) "")))
     (cond
     (cond
      ((and (not caption-str) (not label)) "")
      ((and (not caption-str) (not label)) "")
@@ -670,7 +670,7 @@ This function shouldn't be used for floats. See
 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 ((title (org-export-secondary-string
   (let ((title (org-export-secondary-string
-		(plist-get info :title) 'latex info)))
+		(plist-get info :title) 'e-latex info)))
     (concat
     (concat
      ;; 1. Time-stamp.
      ;; 1. Time-stamp.
      (and (plist-get info :time-stamp-file)
      (and (plist-get info :time-stamp-file)
@@ -699,10 +699,10 @@ holding export options."
      (let ((author (and (plist-get info :with-author)
      (let ((author (and (plist-get info :with-author)
 			(let ((auth (plist-get info :author)))
 			(let ((auth (plist-get info :author)))
 			  (and auth (org-export-secondary-string
 			  (and auth (org-export-secondary-string
-				     auth 'latex info)))))
+				     auth 'e-latex info)))))
 	   (email (and (plist-get info :with-email)
 	   (email (and (plist-get info :with-email)
 		       (org-export-secondary-string
 		       (org-export-secondary-string
-			(plist-get info :email) 'latex info))))
+			(plist-get info :email) 'e-latex info))))
        (cond ((and author email (not (string= "" email)))
        (cond ((and author email (not (string= "" email)))
 	      (format "\\author{%s\\thanks{%s}}\n" author email))
 	      (format "\\author{%s\\thanks{%s}}\n" author email))
 	     (author (format "\\author{%s}\n" author))
 	     (author (format "\\author{%s}\n" author))
@@ -881,27 +881,24 @@ CONTENTS is nil. INFO is a plist holding contextual information."
      org-e-latex-footnote-separator)
      org-e-latex-footnote-separator)
    ;; Use \footnotemark if the footnote has already been defined.
    ;; Use \footnotemark if the footnote has already been defined.
    ;; Otherwise, define it with \footnote command.
    ;; Otherwise, define it with \footnote command.
-   (let* ((all-seen (plist-get info :seen-footnote-labels))
+   (cond
-	  (label (org-element-get-property :label footnote-reference))
+    ((not (org-export-footnote-first-reference-p footnote-reference info))
-	  ;; Anonymous footnotes are always new footnotes.
+     (format "\\footnotemark[%s]"
-	  (seenp (and label (member label all-seen)))
+	     (org-export-get-footnote-number footnote-reference info)))
-	  (inline-def-p (org-element-get-property
+    ;; Inline definitions are secondary strings.
-			 :inline-definition footnote-reference)))
+    ((eq (org-element-get-property :type footnote-reference) 'inline)
-     (cond
+     (format "\\footnote{%s}"
-      (seenp (format "\\footnotemark[%s]" (length seenp)))
+	     (org-trim
-      ;; Inline definitions are secondary strings.
+	      (org-export-secondary-string
-      (inline-def-p
+	       (org-export-get-footnote-definition footnote-reference info)
-       (format "\\footnote{%s}"
+	       'e-latex info))))
-	       (org-trim
+    ;; Non-inline footnotes definitions are full Org data.
-		(org-export-secondary-string inline-def-p 'latex info))))
+    (t
-      ;; Non-inline footnotes necessarily contain a label.  Retrieve
+     (format "\\footnote{%s}"
-      ;; match definition in `:footnotes-labels-alist'.
+	     (org-trim
-      (t
+	      (org-export-data
-       (format "\\footnote{%s}"
+	       (org-export-get-footnote-definition footnote-reference info)
-	       (org-trim
+	       'e-latex info)))))))
-		(org-export-data
-		 (cdr (assoc label (plist-get info :footnotes-labels-alist)))
-		 'latex info))))))))
 
 
 
 
 ;;;; Headline
 ;;;; Headline
@@ -940,12 +937,12 @@ holding contextual information."
 		  (concat (car sec) "\n%s" (nth 1 sec))
 		  (concat (car sec) "\n%s" (nth 1 sec))
 		(concat (nth 2 sec) "\n%s" (nth 3 sec)))))))
 		(concat (nth 2 sec) "\n%s" (nth 3 sec)))))))
 	 (text (org-export-secondary-string
 	 (text (org-export-secondary-string
-		(org-element-get-property :title headline) 'latex info))
+		(org-element-get-property :title headline) 'e-latex info))
 	 (todo (and (plist-get info :with-todo-keywords)
 	 (todo (and (plist-get info :with-todo-keywords)
 		    (let ((todo (org-element-get-property
 		    (let ((todo (org-element-get-property
 				 :todo-keyword headline)))
 				 :todo-keyword headline)))
 		      (and todo
 		      (and todo
-			   (org-export-secondary-string todo 'latex info)))))
+			   (org-export-secondary-string todo 'e-latex info)))))
 	 (todo-type (and todo (org-element-get-property :todo-type headline)))
 	 (todo-type (and todo (org-element-get-property :todo-type headline)))
 	 (tags (and (plist-get info :with-tags)
 	 (tags (and (plist-get info :with-tags)
 		    (org-element-get-property :tags headline)))
 		    (org-element-get-property :tags headline)))
@@ -1065,12 +1062,12 @@ contextual information."
 CONTENTS holds the contents of the block.  INFO is a plist
 CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
 holding contextual information."
   (let ((title (org-export-secondary-string
   (let ((title (org-export-secondary-string
-	       (org-element-get-property :title inlinetask) 'latex info))
+	       (org-element-get-property :title inlinetask) 'e-latex info))
 	(todo (and (plist-get info :with-todo-keywords)
 	(todo (and (plist-get info :with-todo-keywords)
 		   (let ((todo (org-element-get-property
 		   (let ((todo (org-element-get-property
 				:todo-keyword inlinetask)))
 				:todo-keyword inlinetask)))
 		     (and todo
 		     (and todo
-			  (org-export-secondary-string todo 'latex info)))))
+			  (org-export-secondary-string todo 'e-latex info)))))
 	(todo-type (org-element-get-property :todo-type inlinetask))
 	(todo-type (org-element-get-property :todo-type inlinetask))
 	(tags (and (plist-get info :with-tags)
 	(tags (and (plist-get info :with-tags)
 		   (org-element-get-property :tags inlinetask)))
 		   (org-element-get-property :tags inlinetask)))
@@ -1122,7 +1119,7 @@ contextual information."
 	 (tag (let ((tag (org-element-get-property :tag item)))
 	 (tag (let ((tag (org-element-get-property :tag item)))
 		(and tag
 		(and tag
 		     (format "[%s]" (org-export-secondary-string
 		     (format "[%s]" (org-export-secondary-string
-				     tag 'latex info))))))
+				     tag 'e-latex info))))))
     (concat counter "\\item" tag " " checkbox contents)))
     (concat counter "\\item" tag " " checkbox contents)))
 
 
 
 
@@ -1153,7 +1150,7 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 	 ((string= "figures" value) "\\listoffigures")
 	 ((string= "figures" value) "\\listoffigures")
 	 ((string= "listings" value) "\\listoflistings"))))
 	 ((string= "listings" value) "\\listoflistings"))))
      ((string= key "include")
      ((string= key "include")
-      (org-export-included-file keyword 'latex info)))))
+      (org-export-included-file keyword 'e-latex info)))))
 
 
 
 
 ;;;; Latex Environment
 ;;;; Latex Environment
@@ -1251,7 +1248,7 @@ INFO is a plist holding contextual information. See
 	 ;; Ensure DESC really exists, or set it to nil.
 	 ;; Ensure DESC really exists, or set it to nil.
 	 (desc (and (not (string= desc "")) desc))
 	 (desc (and (not (string= desc "")) desc))
 	 (imagep (org-export-inline-image-p
 	 (imagep (org-export-inline-image-p
-		  link desc org-e-latex-inline-image-extensions))
+		  link org-e-latex-inline-image-extensions))
 	 (path (cond
 	 (path (cond
 		((member type '("http" "https" "ftp" "mailto"))
 		((member type '("http" "https" "ftp" "mailto"))
 		 (concat type ":" raw-path))
 		 (concat type ":" raw-path))
@@ -1277,7 +1274,7 @@ INFO is a plist holding contextual information. See
      ((member type '("custom-id" "target" "radio"))
      ((member type '("custom-id" "target" "radio"))
       (format "\\hyperref[%s]{%s}"
       (format "\\hyperref[%s]{%s}"
 	      (org-export-solidify-link-text path)
 	      (org-export-solidify-link-text path)
-	      (or desc (org-export-secondary-string path 'latex info))))
+	      (or desc (org-export-secondary-string path 'e-latex info))))
      ;; Fuzzy: With the help of `org-export-resolve-fuzzy-link', find
      ;; Fuzzy: With the help of `org-export-resolve-fuzzy-link', find
      ;; the destination of the link.
      ;; the destination of the link.
      ((string= type "fuzzy")
      ((string= type "fuzzy")
@@ -1289,20 +1286,20 @@ INFO is a plist holding contextual information. See
 		  (org-export-solidify-link-text destination)
 		  (org-export-solidify-link-text destination)
 		  (or desc
 		  (or desc
 		      (org-export-secondary-string
 		      (org-export-secondary-string
-		       (org-element-get-property :raw-link link) 'latex info))))
+		       (org-element-get-property :raw-link link) 'e-latex info))))
 	 ;; Headline match.
 	 ;; Headline match.
 	 ((integerp destination)
 	 ((integerp destination)
 	  (format "\\hyperref[headline-%d]{%s}"
 	  (format "\\hyperref[headline-%d]{%s}"
 		  destination
 		  destination
 		  (or desc
 		  (or desc
 		      (org-export-secondary-string
 		      (org-export-secondary-string
-		       (org-element-get-property :raw-link link) 'latex info))))
+		       (org-element-get-property :raw-link link) 'e-latex info))))
 	 ;; No match.
 	 ;; No match.
 	 (t (format "\\texttt{%s}"
 	 (t (format "\\texttt{%s}"
 		    (or desc
 		    (or desc
 			(org-export-secondary-string
 			(org-export-secondary-string
 			 (org-element-get-property :raw-link link)
 			 (org-element-get-property :raw-link link)
-			 'latex info)))))))
+			 'e-latex 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.
      ((string= type "coderef")
      ((string= type "coderef")
@@ -1522,7 +1519,7 @@ contextual information."
 	    (caption-str (and caption
 	    (caption-str (and caption
 			      (org-export-secondary-string
 			      (org-export-secondary-string
 			       (org-element-get-property :caption src-block)
 			       (org-element-get-property :caption src-block)
-			       'latex info))))
+			       'e-latex info))))
 	(concat (format "\\lstset{%s}\n"
 	(concat (format "\\lstset{%s}\n"
 			(org-e-latex--make-option-string
 			(org-e-latex--make-option-string
 			 (append org-e-latex-listings-options
 			 (append org-e-latex-listings-options
@@ -1728,7 +1725,7 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 			  (org-element-parse-secondary-string
 			  (org-element-parse-secondary-string
 			   cell
 			   cell
 			   (cdr (assq 'table org-element-string-restrictions)))
 			   (cdr (assq 'table org-element-string-restrictions)))
-			  'latex info))
+			  'e-latex info))
 		       (org-split-string row "[ \t]*|[ \t]*"))))
 		       (org-split-string row "[ \t]*|[ \t]*"))))
 		  (org-split-string clean-table "\n"))
 		  (org-split-string clean-table "\n"))
 		 `(:tstart nil :tend nil
 		 `(:tstart nil :tend nil
@@ -1834,7 +1831,7 @@ CONTENTS is nil. INFO is a plist holding contextual information."
 		      (org-remove-indentation
 		      (org-remove-indentation
 		       (org-export-secondary-string
 		       (org-export-secondary-string
 			(org-element-get-property :value verse-block)
 			(org-element-get-property :value verse-block)
-			'latex info)))))
+			'e-latex info)))))
      (while (string-match "^[ \t]+" contents)
      (while (string-match "^[ \t]+" contents)
        (let ((new-str (format "\\hspace*{%dem}"
        (let ((new-str (format "\\hspace*{%dem}"
 			      (length (match-string 0 contents)))))
 			      (length (match-string 0 contents)))))

+ 44 - 5
Makefile

@@ -16,10 +16,15 @@ EMACS=emacs
 # Where local software is found
 # Where local software is found
 prefix=/usr/local
 prefix=/usr/local
 
 
-# Where local lisp files go.
+# Where local lisp files go
 lispdir   = $(prefix)/share/emacs/site-lisp
 lispdir   = $(prefix)/share/emacs/site-lisp
 
 
-# Where info files go.
+# Where data files go
+# $(datadir) contains auxiliary files for use with ODT exporter.
+# See comments under DATAFILES.
+datadir = $(prefix)/share/emacs/etc
+
+# Where info files go
 infodir = $(prefix)/share/info
 infodir = $(prefix)/share/info
 
 
 ##----------------------------------------------------------------------
 ##----------------------------------------------------------------------
@@ -29,7 +34,7 @@ infodir = $(prefix)/share/info
 # Using emacs in batch mode.
 # Using emacs in batch mode.
 
 
 BATCH=$(EMACS) -batch -q -no-site-file -eval                             			\
 BATCH=$(EMACS) -batch -q -no-site-file -eval                             			\
-  "(setq load-path (cons (expand-file-name \"./lisp/\") (cons \"$(lispdir)\" load-path)))"
+  "(setq load-path (cons (expand-file-name \"./lisp/\") (cons \"$(lispdir)\" load-path)))" $(BATCH_EXTRA)
 
 
 # Specify the byte-compiler for compiling org-mode files
 # Specify the byte-compiler for compiling org-mode files
 ELC= $(BATCH) -f batch-byte-compile
 ELC= $(BATCH) -f batch-byte-compile
@@ -48,7 +53,7 @@ TEXI2HTML = makeinfo --html --number-sections
 TEXI2HTMLNOPSLIT = makeinfo --html --no-split --number-sections
 TEXI2HTMLNOPSLIT = makeinfo --html --no-split --number-sections
 
 
 # How to copy the lisp files and elc files to their distination.
 # How to copy the lisp files and elc files to their distination.
-CP = cp -p
+CP = cp -pr
 
 
 # Name of the program to install info files
 # Name of the program to install info files
 INSTALL_INFO=install-info
 INSTALL_INFO=install-info
@@ -85,6 +90,7 @@ LISPF      = 	org.el			\
 		org-footnote.el		\
 		org-footnote.el		\
 		org-freemind.el		\
 		org-freemind.el		\
 		org-gnus.el		\
 		org-gnus.el		\
+		org-eshell.el		\
 		org-habit.el		\
 		org-habit.el		\
 		org-html.el		\
 		org-html.el		\
 		org-icalendar.el	\
 		org-icalendar.el	\
@@ -176,6 +182,26 @@ CARDFILES   = doc/orgcard.tex doc/orgcard.pdf doc/orgcard_letter.pdf
 TEXIFILES   = doc/org.texi
 TEXIFILES   = doc/org.texi
 INFOFILES   = doc/org
 INFOFILES   = doc/org
 
 
+# etc/styles contains OpenDocument style files.  These files *must* be
+# installed for the ODT exporter to function.  These files are
+# distirbuted with GNU ELPA as well as with stock Emacs >= 24.1.
+
+# contrib/odt/etc/schema contains OpenDocument schema files.  It is
+# *desirable* but *not* mandatory that these files be installed.
+# These files are not distributed with stock Emacs.  This is because
+# the terms under which OASIS distributes these files are not
+# agreeable to FSF.
+
+# BasicODConverter-x.y.z.oxt is a LibreOffice extension for converting
+# OpenDocument files to numerous other formats.  It is similar to
+# unoconv and is implemented in StarBasic.  It is *desirable* but
+# *not* *mandatory* that the converter be installed.  It is
+# distributed under the same license as GNU Emacs.  This file is *not*
+# part of GNU Emacs.
+DATAFILES   = etc/styles \
+	      # contrib/odt/BasicODConverter/BasicODConverter*.oxt \
+	      # contrib/odt/etc/schema \
+
 # Package Manager (ELPA)
 # Package Manager (ELPA)
 PKG_TAG = $(shell date +%Y%m%d)
 PKG_TAG = $(shell date +%Y%m%d)
 PKG_DOC = "Outline-based notes management and organizer"
 PKG_DOC = "Outline-based notes management and organizer"
@@ -211,7 +237,7 @@ update:
 
 
 compile: $(ELCFILES0) $(ELCBFILES)
 compile: $(ELCFILES0) $(ELCBFILES)
 
 
-install: install-lisp
+install: install-lisp install-data
 
 
 doc: doc/org.html doc/org.pdf doc/orgcard.pdf doc/orgcard_letter.pdf doc/orgguide.pdf doc/orgcard.txt
 doc: doc/org.html doc/org.pdf doc/orgcard.pdf doc/orgcard_letter.pdf doc/orgguide.pdf doc/orgcard.txt
 
 
@@ -221,6 +247,15 @@ p:
 g:
 g:
 	${MAKE} pdf && open doc/orgguide.pdf
 	${MAKE} pdf && open doc/orgguide.pdf
 
 
+# Always force re-compilation of org-odt
+lisp/org-odt.elc: org-odt-data-dir
+org-odt-data-dir:
+
+# Sleight of hand to "hard code" the value of $(datadir) in
+# org-odt.el.  See variables `org-odt-styles-dir-list' and
+# `org-odt-schema-dir-list'.
+install-lisp: BATCH_EXTRA = -eval "(setq org-odt-data-dir (expand-file-name \"$(datadir)\"))"
+
 install-lisp: $(LISPFILES) $(ELCFILES)
 install-lisp: $(LISPFILES) $(ELCFILES)
 	if [ ! -d $(lispdir) ]; then $(MKDIR) $(lispdir); else true; fi ;
 	if [ ! -d $(lispdir) ]; then $(MKDIR) $(lispdir); else true; fi ;
 	$(CP) $(LISPFILES)  $(lispdir)
 	$(CP) $(LISPFILES)  $(lispdir)
@@ -231,6 +266,10 @@ install-info: $(INFOFILES)
 	$(CP) $(INFOFILES) $(infodir)
 	$(CP) $(INFOFILES) $(infodir)
 	$(INSTALL_INFO) --infodir=$(infodir) $(INFOFILES)
 	$(INSTALL_INFO) --infodir=$(infodir) $(INFOFILES)
 
 
+install-data: $(DATAFILES)
+	if [ ! -d $(datadir) ]; then $(MKDIR) $(datadir); else true; fi ;
+	$(CP) $(DATAFILES) $(datadir)
+
 autoloads: lisp/org-install.el
 autoloads: lisp/org-install.el
 
 
 lisp/org-install.el: $(LISPFILES0) Makefile
 lisp/org-install.el: $(LISPFILES0) Makefile

+ 34 - 34
contrib/babel/library-of-babel.org

@@ -1,22 +1,23 @@
 #+title:    The Library of Babel
 #+title:    The Library of Babel
 #+author:     Org-mode People
 #+author:     Org-mode People
-#+STARTUP:  oddeven hideblocks
+#+STARTUP:  hideblocks
 
 
 * Introduction
 * Introduction
 
 
-  The Library of Babel is an extensible collection of ready-made and
+The Library of Babel is an extensible collection of ready-made and
-  easily-shortcut-callable source-code blocks for handling common tasks.
+easily-shortcut-callable source-code blocks for handling common tasks.
-  Org-babel comes pre-populated with the source-code blocks located in this
+Org-babel comes pre-populated with the source-code blocks located in
-  file. It is possible to add source-code blocks from any org-mode file to
+this file.  It is possible to add source-code blocks from any org-mode
-  the library by calling =(org-babel-lob-ingest "path/to/file.org")=.
+file to the library by calling =(org-babel-lob-ingest
-  
+"path/to/file.org")=.
-  This file is included in worg mainly less for viewing through the web
+
-  interface, and more for contribution through the worg git repository.  If
+This file is included in worg mainly less for viewing through the web
-  you have code snippets that you think others may find useful please add
+interface, and more for contribution through the worg git repository.
-  them to this file and [[file:~/src/worg/worg-git.org::contribute-to-worg][contribute them]] to worg.
+If you have code snippets that you think others may find useful please
-  
+add them to this file and [[file:~/src/worg/worg-git.org::contribute-to-worg][contribute them]] to worg.
-  The raw Org-mode text of this file can be downloaded at
+
-  [[repofile:contrib/babel/library-of-babel.org][library-of-babel.org]]
+The raw Org-mode text of this file can be downloaded at
+[[repofile:contrib/babel/library-of-babel.org][library-of-babel.org]]
 
 
 * Simple
 * Simple
 
 
@@ -63,7 +64,7 @@ as a table in traditional Org-mode table syntax.
 
 
 ** Remote files
 ** Remote files
 
 
-**** json
+*** json
 
 
 Read local or remote file in [[http://www.json.org/][json]] format into emacs-lisp objects.
 Read local or remote file in [[http://www.json.org/][json]] format into emacs-lisp objects.
 
 
@@ -83,14 +84,14 @@ Read local or remote file in [[http://www.json.org/][json]] format into emacs-li
       (json-read))))
       (json-read))))
 #+end_src
 #+end_src
 
 
-**** Google docs
+*** Google docs
 
 
 The following code blocks make use of the [[http://code.google.com/p/googlecl/][googlecl]] Google command line
 The following code blocks make use of the [[http://code.google.com/p/googlecl/][googlecl]] Google command line
 tool.  This tool provides functionality for accessing Google services
 tool.  This tool provides functionality for accessing Google services
 from the command line, and the following code blocks use /googlecl/
 from the command line, and the following code blocks use /googlecl/
 for reading from and writing to Google docs with Org-mode code blocks.
 for reading from and writing to Google docs with Org-mode code blocks.
 
 
-****** Read a document from Google docs
+**** Read a document from Google docs
 
 
 The =google= command seems to be throwing "Moved Temporarily" errors
 The =google= command seems to be throwing "Moved Temporarily" errors
 when trying to download textual documents, but this is working fine
 when trying to download textual documents, but this is working fine
@@ -120,7 +121,7 @@ document as a string.
 
 
 : #+call: gdoc-read(title="loremi", :format "txt")
 : #+call: gdoc-read(title="loremi", :format "txt")
 
 
-****** Write a document to a Google docs
+**** Write a document to a Google docs
 
 
 Write =data= to a google document named =title=.  If =data= is tabular
 Write =data= to a google document named =title=.  If =data= is tabular
 it will be saved to a spreadsheet, otherwise it will be saved as a
 it will be saved to a spreadsheet, otherwise it will be saved as a
@@ -147,18 +148,18 @@ example usage
 :   (flet ((fib (m) (if (< m 2) 1 (+ (fib (- m 1)) (fib (- m 2))))))
 :   (flet ((fib (m) (if (< m 2) 1 (+ (fib (- m 1)) (fib (- m 2))))))
 :     (mapcar (lambda (el) (list el (fib el))) (number-sequence 0 (- n 1))))
 :     (mapcar (lambda (el) (list el (fib el))) (number-sequence 0 (- n 1))))
 : #+end_src
 : #+end_src
-: 
+:
 : #+call: gdoc-write(title="fibs", data=fibs(n=10))
 : #+call: gdoc-write(title="fibs", data=fibs(n=10))
 
 
 * Plotting code
 * Plotting code
 
 
 ** R
 ** R
 
 
-  Plot column 2 (y axis) against column 1 (x axis). Columns 3 and
+Plot column 2 (y axis) against column 1 (x axis). Columns 3 and
-  beyond, if present, are ignored.
+beyond, if present, are ignored.
 
 
-#+name: R-plot(data=R-plot-example-data)
+#+name: R-plot
-#+begin_src R
+#+begin_src R :var data=R-plot-example-data
 plot(data)
 plot(data)
 #+end_src
 #+end_src
 
 
@@ -275,7 +276,7 @@ are optional.
   %head
   %head
   %foot
   %foot
   %lastfoot
   %lastfoot
-  
+
   %table
   %table
   \\end{longtable}\n"
   \\end{longtable}\n"
    (list
    (list
@@ -296,7 +297,6 @@ are optional.
                    (list :lend " \\\\" :sep " & " :hline hline)))))
                    (list :lend " \\\\" :sep " & " :hline hline)))))
 #+end_src
 #+end_src
 
 
-
 *** booktabs-notes
 *** booktabs-notes
 
 
 This source block builds on [[booktabs]].  It accepts two additional
 This source block builds on [[booktabs]].  It accepts two additional
@@ -350,7 +350,7 @@ span. Note the use of LaTeX, rather than Org-mode, markup.
       )))
       )))
 #+end_src
 #+end_src
 
 
-** Elegant lisp for transposing a matrix.
+** Elegant lisp for transposing a matrix
 
 
 #+tblname: transpose-example
 #+tblname: transpose-example
 | 1 | 2 | 3 |
 | 1 | 2 | 3 |
@@ -405,7 +405,7 @@ span. Note the use of LaTeX, rather than Org-mode, markup.
    :PROPERTIES:
    :PROPERTIES:
    :AUTHOR: Luke Crook
    :AUTHOR: Luke Crook
    :END:
    :END:
-   
+
 This function will attempt to retrieve the entire commit log for the
 This function will attempt to retrieve the entire commit log for the
 file associated with the current buffer and insert this log into the
 file associated with the current buffer and insert this log into the
 export. The function uses the Emacs VC commands to interface to the
 export. The function uses the Emacs VC commands to interface to the
@@ -428,7 +428,7 @@ Git. 'limit' is currently unsupported.
         (setq vc-fileset (vc-deduce-fileset t)) ; FIXME: Why t? --Stef
         (setq vc-fileset (vc-deduce-fileset t)) ; FIXME: Why t? --Stef
         (setq backend (car vc-fileset))
         (setq backend (car vc-fileset))
         (setq files (cadr vc-fileset)))
         (setq files (cadr vc-fileset)))
-      (with-temp-buffer 
+      (with-temp-buffer
         (let ((status (vc-call-backend
         (let ((status (vc-call-backend
                        backend 'print-log files (current-buffer))))
                        backend 'print-log files (current-buffer))))
           (when (and (processp status)   ; Make sure status is a process
           (when (and (processp status)   ; Make sure status is a process
@@ -440,13 +440,13 @@ Git. 'limit' is currently unsupported.
 
 
 ** Trivial python code blocks
 ** Trivial python code blocks
 
 
-#+name: python-identity(a=1)
+#+name: python-identity
-#+begin_src python
+#+begin_src python :var a=1
 a
 a
 #+end_src
 #+end_src
 
 
-#+name: python-add(a=1, b=2)
+#+name: python-add
-#+begin_src python
+#+begin_src python :var a=1 :var b=2
 a + b
 a + b
 #+end_src
 #+end_src
 
 
@@ -476,7 +476,7 @@ a + b
 
 
 The =elispgantt= source block was sent to the mailing list by Eric
 The =elispgantt= source block was sent to the mailing list by Eric
 Fraga.  It was modified slightly by Tom Dye.
 Fraga.  It was modified slightly by Tom Dye.
- 
+
 #+name: elispgantt
 #+name: elispgantt
 #+begin_src emacs-lisp :var table=gantttest
 #+begin_src emacs-lisp :var table=gantttest
   (let ((dates "")
   (let ((dates "")
@@ -580,5 +580,5 @@ Fraga.  It was modified slightly by Tom Dye.
 
 
 ** From Org's contrib/babel/langs
 ** From Org's contrib/babel/langs
 
 
-- ob-oz.el, by Torsten Anders and Eric Schulte 
+- ob-oz.el, by Torsten Anders and Eric Schulte
 - ob-fomus.el, by Torsten Anders
 - ob-fomus.el, by Torsten Anders

+ 115 - 83
contrib/lisp/org-element.el

@@ -15,6 +15,8 @@
 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ;; GNU General Public License for more details.
 ;; GNU General Public License for more details.
 
 
+;; This file is not part of GNU Emacs.
+
 ;; You should have received a copy of the GNU General Public License
 ;; You should have received a copy of the GNU General Public License
 ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
@@ -260,7 +262,7 @@ CONTENTS is the contents of the element."
 
 
 Return a list whose car is `footnote-definition' and cdr is
 Return a list whose car is `footnote-definition' and cdr is
 a plist containing `:label', `:begin' `:end', `:contents-begin',
 a plist containing `:label', `:begin' `:end', `:contents-begin',
-`contents-end' and `:post-blank' keywords."
+`:contents-end' and `:post-blank' keywords."
   (save-excursion
   (save-excursion
     (let* ((f-def (org-footnote-at-definition-p))
     (let* ((f-def (org-footnote-at-definition-p))
 	   (label (car f-def))
 	   (label (car f-def))
@@ -301,8 +303,8 @@ containing `:raw-value', `:title', `:begin', `:end',
 `:pre-blank', `:hiddenp', `:contents-begin' and `:contents-end',
 `:pre-blank', `:hiddenp', `:contents-begin' and `:contents-end',
 `:level', `:priority', `:tags', `:todo-keyword',`:todo-type',
 `:level', `:priority', `:tags', `:todo-keyword',`:todo-type',
 `:scheduled', `:deadline', `:timestamp', `:clock', `:category',
 `:scheduled', `:deadline', `:timestamp', `:clock', `:category',
-`:custom-id', `:id', `:quotedp', `:archivedp', `:commentedp',
+`:quotedp', `:archivedp', `:commentedp' and `:footnote-section-p'
-`:last-sibling-p' and `:footnote-section-p' keywords.
+keywords.
 
 
 The plist also contains any property set in the property drawer,
 The plist also contains any property set in the property drawer,
 with its name in lowercase, the underscores replaced with hyphens
 with its name in lowercase, the underscores replaced with hyphens
@@ -444,8 +446,14 @@ CONTENTS is the contents of the element."
 
 
 Return a list whose car is `inlinetask' and cdr is a plist
 Return a list whose car is `inlinetask' and cdr is a plist
 containing `:raw-value', `:title', `:begin', `:end', `:hiddenp',
 containing `:raw-value', `:title', `:begin', `:end', `:hiddenp',
-`:contents-begin' and `:contents-end', `:level', `:with-priority',
+`:contents-begin' and `:contents-end', `:level', `:priority',
-`tags:', `todo-keyword', `todo-type', and `:post-blank' keywords.
+`:raw-value', `:tags', `:todo-keyword', `:todo-type',
+`:scheduled', `:deadline', `:timestamp', `:clock' and
+`:post-blank' keywords.
+
+The plist also contains any property set in the property drawer,
+with its name in lowercase, the underscores replaced with hyphens
+and colons at the beginning (i.e. `:custom-id').
 
 
 Assume point is at beginning of the inline task."
 Assume point is at beginning of the inline task."
   (save-excursion
   (save-excursion
@@ -456,6 +464,23 @@ Assume point is at beginning of the inline task."
 	   (todo-type (and todo
 	   (todo-type (and todo
 			   (if (member todo org-done-keywords) 'done 'todo)))
 			   (if (member todo org-done-keywords) 'done 'todo)))
 	   (raw-value (nth 4 components))
 	   (raw-value (nth 4 components))
+	   (standard-props (let (plist)
+			     (mapc
+			      (lambda (p)
+				(let ((p-name (downcase (car p))))
+				  (while (string-match "_" p-name)
+				    (setq p-name
+					  (replace-match "-" nil nil p-name)))
+				  (setq p-name (intern (concat ":" p-name)))
+				  (setq plist
+					(plist-put plist p-name (cdr p)))))
+			      (org-entry-properties nil 'standard))
+			     plist))
+	   (time-props (org-entry-properties nil 'special "CLOCK"))
+	   (scheduled (cdr (assoc "SCHEDULED" time-props)))
+	   (deadline (cdr (assoc "DEADLINE" time-props)))
+	   (clock (cdr (assoc "CLOCK" time-props)))
+	   (timestamp (cdr (assoc "TIMESTAMP" time-props)))
 	   (title (org-element-parse-secondary-string
 	   (title (org-element-parse-secondary-string
 		   raw-value
 		   raw-value
 		   (cdr (assq 'inlinetask org-element-string-restrictions))))
 		   (cdr (assq 'inlinetask org-element-string-restrictions))))
@@ -477,11 +502,16 @@ Assume point is at beginning of the inline task."
 			 :contents-begin ,contents-begin
 			 :contents-begin ,contents-begin
 			 :contents-end ,contents-end
 			 :contents-end ,contents-end
 			 :level ,(nth 1 components)
 			 :level ,(nth 1 components)
-			 :with-priority ,(nth 3 components)
+			 :priority ,(nth 3 components)
-			 :with-tags ,(nth 5 components)
+			 :tags ,(nth 5 components)
 			 :todo-keyword ,todo
 			 :todo-keyword ,todo
 			 :todo-type ,todo-type
 			 :todo-type ,todo-type
+			 :scheduled ,scheduled
+			 :deadline ,deadline
+			 :timestamp ,timestamp
+			 :clock ,clock
 			 :post-blank ,(count-lines pos-before-blank end)
 			 :post-blank ,(count-lines pos-before-blank end)
+			 ,@standard-props
 			 ,@(cadr keywords))))))
 			 ,@(cadr keywords))))))
 
 
 (defun org-element-inlinetask-interpreter (inlinetask contents)
 (defun org-element-inlinetask-interpreter (inlinetask contents)
@@ -517,8 +547,9 @@ CONTENTS is the contents of inlinetask."
 STRUCT is the structure of the plain list.
 STRUCT is the structure of the plain list.
 
 
 Return a list whose car is `item' and cdr is a plist containing
 Return a list whose car is `item' and cdr is a plist containing
-`:begin', `:end', `:contents-begin', `:contents-end',
+`:bullet', `:begin', `:end', `:contents-begin', `:contents-end',
-`:checkbox', `:counter', `:tag' and `:hiddenp'.
+`:checkbox', `:counter', `:tag', `:raw-tag', `:structure',
+`:hiddenp' and `:post-blank' keywords.
 
 
 Assume point is at the beginning of the item."
 Assume point is at the beginning of the item."
   (save-excursion
   (save-excursion
@@ -556,13 +587,14 @@ Assume point is at the beginning of the item."
 				(skip-chars-backward " \r\t\n")
 				(skip-chars-backward " \r\t\n")
 				(forward-line)
 				(forward-line)
 				(point))))
 				(point))))
-      ;; Note: CONTENTS-BEGIN and CONTENTS-END can be mixed up in the
-      ;; case of an empty item separated from the next by a blank
-      ;; line.
       (list 'item
       (list 'item
 	    `(:bullet ,bullet
 	    `(:bullet ,bullet
 		      :begin ,begin
 		      :begin ,begin
 		      :end ,end
 		      :end ,end
+		      ;; CONTENTS-BEGIN and CONTENTS-END may be mixed
+		      ;; up in the case of an empty item separated
+		      ;; from the next by a blank line.  Thus, ensure
+		      ;; the former is always the smallest of two.
 		      :contents-begin ,(min contents-begin contents-end)
 		      :contents-begin ,(min contents-begin contents-end)
 		      :contents-end ,(max contents-begin contents-end)
 		      :contents-end ,(max contents-begin contents-end)
 		      :checkbox ,checkbox
 		      :checkbox ,checkbox
@@ -2331,9 +2363,9 @@ regexp matching one object can also match the other object.")
   "List of affiliated keywords as strings.")
   "List of affiliated keywords as strings.")
 
 
 (defconst org-element-keyword-translation-alist
 (defconst org-element-keyword-translation-alist
-  '(("tblname" . "name") ("srcname" . "name") ("resname" . "name")
+  '(("data" . "name")  ("label" . "name") ("resname" . "name")
-    ("source" . "name") ("result" . "results") ("headers" . "header")
+    ("source" . "name") ("srcname" . "name") ("tblname" . "name")
-    ("label" . "name"))
+    ("result" . "results") ("headers" . "header"))
   "Alist of usual translations for keywords.
   "Alist of usual translations for keywords.
 The key is the old name and the value the new one.  The property
 The key is the old name and the value the new one.  The property
 holding their value will be named after the translated name.")
 holding their value will be named after the translated name.")
@@ -2775,7 +2807,7 @@ the current buffer."
     (insert string)
     (insert string)
     (org-element-parse-objects (point-min) (point-max) nil restriction)))
     (org-element-parse-objects (point-min) (point-max) nil restriction)))
 
 
-(defun org-element-map (data types fun &optional options first-match)
+(defun org-element-map (data types fun &optional info first-match)
   "Map a function on selected elements or objects.
   "Map a function on selected elements or objects.
 
 
 DATA is the parsed tree, as returned by, i.e,
 DATA is the parsed tree, as returned by, i.e,
@@ -2785,7 +2817,7 @@ matching element or object.  It must accept two arguments: the
 element or object itself and a plist holding contextual
 element or object itself and a plist holding contextual
 information.
 information.
 
 
-When optional argument OPTIONS is non-nil, it should be a plist
+When optional argument INFO is non-nil, it should be a plist
 holding export options.  In that case, parts of the parse tree
 holding export options.  In that case, parts of the parse tree
 not exportable according to that property list will be skipped
 not exportable according to that property list will be skipped
 and files included through a keyword will be visited.
 and files included through a keyword will be visited.
@@ -2796,9 +2828,8 @@ match for which FUN doesn't return nil, and return that value.
 Nil values returned from FUN are ignored in the result."
 Nil values returned from FUN are ignored in the result."
   ;; Ensure TYPES is a list, even of one element.
   ;; Ensure TYPES is a list, even of one element.
   (unless (listp types) (setq types (list types)))
   (unless (listp types) (setq types (list types)))
-  ;; Recursion depth is determined by TYPE-CATEGORY, to avoid
+  ;; Recursion depth is determined by --CATEGORY.
-  ;; unnecessary steps.
+  (let* ((--category
-  (let* ((type-category
 	  (cond
 	  (cond
 	   ((loop for type in types
 	   ((loop for type in types
 		  always (memq type org-element-greater-elements))
 		  always (memq type org-element-greater-elements))
@@ -2807,97 +2838,98 @@ Nil values returned from FUN are ignored in the result."
 		  always (memq type org-element-all-elements))
 		  always (memq type org-element-all-elements))
 	    'elements)
 	    'elements)
 	   (t 'objects)))
 	   (t 'objects)))
-	 walk-tree                      ; For byte-compiler
+	 walk-tree			; For byte-compiler
-	 acc                            ; Accumulate results into ACC.
+	 --acc
 	 (accumulate-maybe
 	 (accumulate-maybe
 	  (function
 	  (function
-	   ;; Check if TYPE is matching among TYPES.  If so, apply FUN
+	   (lambda (--type types fun --blob --local)
-	   ;; to BLOB and accumulate return value into ACC.  INFO is
+	     ;; Check if TYPE is matching among TYPES.  If so, apply
-	   ;; the communication channel.
+	     ;; FUN to --BLOB and accumulate return value
-	   (lambda (type types fun blob info)
+	     ;; into --ACC.  --LOCAL is the communication channel.
-	     (when (memq type types)
+	     (when (memq --type types)
-	       (let ((result (funcall fun blob info)))
+	       (let ((result (funcall fun --blob --local)))
-		 (cond
+		 (cond ((not result))
-		  ((not result))
+		       (first-match (throw 'first-match result))
-		  (first-match (throw 'first-match result))
+		       (t (push result --acc))))))))
-		  (t (push result acc))))))))
 	 (walk-tree
 	 (walk-tree
 	  (function
 	  (function
-	   ;; Recursively walk DATA.  INFO, if non-nil, is a plist
+	   (lambda (--data --local)
-	   ;; holding contextual information.
+	     ;; Recursively walk DATA.  --LOCAL, if non-nil, is
-	   (lambda (data info)
+	     ;; a plist holding contextual information.
 	     (mapc
 	     (mapc
-	      (lambda (blob)
+	      (lambda (--blob)
-		(let ((type (if (stringp blob) 'plain-text (car blob))))
+		(let ((--type (if (stringp --blob) 'plain-text (car --blob))))
-		  ;; Determine if a recursion into BLOB is possible
+		  ;; Determine if a recursion into --BLOB is
-		  ;; and allowed.
+		  ;; possible and allowed.
 		  (cond
 		  (cond
 		   ;; Element or object not exportable.
 		   ;; Element or object not exportable.
-		   ((and info (org-export-skip-p blob info)))
+		   ((and info (org-export-skip-p --blob info)))
-		   ;; Archived headline: skip it.
+		   ;; Archived headline: Maybe apply fun on it, but
+		   ;; skip contents.
 		   ((and info
 		   ((and info
-			 (eq type 'headline)
+			 (eq --type 'headline)
-			 (and (eq (plist-get info :with-archived-trees)
+			 (eq (plist-get info :with-archived-trees) 'headline)
-				  'headline)
+			 (org-element-get-property :archivedp --blob))
-			      (org-element-get-property :archivedp blob)))
+		    (funcall accumulate-maybe --type types fun --blob --local))
-		    (funcall accumulate-maybe type types fun blob info))
 		   ;; At an include keyword: apply mapping to its
 		   ;; At an include keyword: apply mapping to its
 		   ;; contents.
 		   ;; contents.
-		   ((and info
+		   ((and --local
-			 (eq type 'keyword)
+			 (eq --type 'keyword)
 			 (string=
 			 (string=
-			  (downcase (org-element-get-property :key blob))
+			  (downcase (org-element-get-property :key --blob))
 			  "include"))
 			  "include"))
-		    (funcall accumulate-maybe type types fun blob info)
+		    (funcall accumulate-maybe --type types fun --blob --local)
-		    (let* ((data (org-export-parse-included-file blob info))
+		    (let* ((--data
-			   (value (org-element-get-property :value blob))
+			    (org-export-parse-included-file --blob --local))
-			   (file (and (string-match "^\"\\(\\S-+\\)\"" value)
+			   (--value (org-element-get-property :value --blob))
-				      (match-string 1 value))))
+			   (--file
+			    (and (string-match "^\"\\(\\S-+\\)\"" --value)
+				 (match-string 1 --value))))
 		      (funcall
 		      (funcall
-		       walk-tree
+		       walk-tree --data
-		       data
 		       (org-combine-plists
 		       (org-combine-plists
-			info
+			--local
 			;; Store full path of already included files
 			;; Store full path of already included files
 			;; to avoid recursive file inclusion.
 			;; to avoid recursive file inclusion.
 			`(:included-files
 			`(:included-files
-			  ,(cons (expand-file-name file)
+			  ,(cons (expand-file-name --file)
-				 (plist-get info :included-files))
+				 (plist-get --local :included-files))
 			  ;; Ensure that a top-level headline in the
 			  ;; Ensure that a top-level headline in the
 			  ;; included file becomes a direct child of
 			  ;; included file becomes a direct child of
 			  ;; the current headline in the buffer.
 			  ;; the current headline in the buffer.
 			  :headline-offset
 			  :headline-offset
 			  ,(- (+ (plist-get
 			  ,(- (+ (plist-get
-				  (plist-get info :inherited-properties) :level)
+				  (plist-get --local :inherited-properties)
-				 (or (plist-get info :headline-offset) 0))
+				  :level)
-			      (1- (org-export-get-min-level data info))))))))
+				 (or (plist-get --local :headline-offset) 0))
-		   ;; Limiting recursion to greater elements, and BLOB
+			      (1- (org-export-get-min-level
+				   --data --local))))))))
+		   ;; Limiting recursion to greater elements, and --BLOB
 		   ;; isn't one.
 		   ;; isn't one.
-		   ((and (eq type-category 'greater-elements)
+		   ((and (eq --category 'greater-elements)
-			 (not (memq type org-element-greater-elements)))
+			 (not (memq --type org-element-greater-elements)))
-		    (funcall accumulate-maybe type types fun blob info))
+		    (funcall accumulate-maybe --type types fun --blob --local))
-		   ;; Limiting recursion to elements, and BLOB only
+		   ;; Limiting recursion to elements, and --BLOB only
 		   ;; contains objects.
 		   ;; contains objects.
-		   ((and (eq type-category 'elements) (eq type 'paragraph)))
+		   ((and (eq --category 'elements) (eq --type 'paragraph)))
-		   ;; No limitation on recursion, but BLOB hasn't got
+		   ;; No limitation on recursion, but --BLOB hasn't
-		   ;; a recursive type.
+		   ;; got a recursive type.
-		   ((and (eq type-category 'objects)
+		   ((and (eq --category 'objects)
-			 (not (or (eq type 'paragraph)
+			 (not (or (eq --type 'paragraph)
-				  (memq type org-element-greater-elements)
+				  (memq --type org-element-greater-elements)
-				  (memq type org-element-recursive-objects))))
+				  (memq --type org-element-recursive-objects))))
-		    (funcall accumulate-maybe type types fun blob info))
+		    (funcall accumulate-maybe --type types fun --blob --local))
 		   ;; Recursion is possible and allowed: Update local
 		   ;; Recursion is possible and allowed: Update local
-		   ;; informations and move into BLOB.
+		   ;; information and move into --BLOB.
-		   (t (funcall accumulate-maybe type types fun blob info)
+		   (t (funcall accumulate-maybe --type types fun --blob --local)
 		      (funcall
 		      (funcall
-		       walk-tree
+		       walk-tree --blob
-		       blob
+		       (and info (org-export-update-info --blob --local t)))))))
-		       (and options (org-export-update-info blob info t)))))))
+	      (org-element-get-contents --data))))))
-	      (org-element-get-contents data))))))
     (catch 'first-match
     (catch 'first-match
-      (funcall walk-tree data options)
+      (funcall walk-tree data info)
       ;; Return value in a proper order.
       ;; Return value in a proper order.
-      (reverse acc))))
+      (reverse --acc))))
 
 
 ;; The following functions are internal parts of the parser.  The
 ;; The following functions are internal parts of the parser.  The
 ;; first one, `org-element-parse-elements' acts at the element's
 ;; first one, `org-element-parse-elements' acts at the element's

+ 223 - 87
contrib/lisp/org-export.el

@@ -579,12 +579,25 @@ while every other back-end will ignore it."
 ;;   - category :: option
 ;;   - category :: option
 ;;   - type :: list of strings
 ;;   - type :: list of strings
 
 
-;; + `footnotes-labels-alist' :: Alist between footnote labels and
+;; + `footnote-definition-alist' :: Alist between footnote labels and
-;;      their definition, as parsed data.  Once retrieved, the
+;;     their definition, as parsed data.  Only non-inlined footnotes
-;;      definition should be exported with `org-export-data'.
+;;     are represented in this alist.  Also, every definition isn't
+;;     guaranteed to be referenced in the parse tree.  The purpose of
+;;     this property is to preserve definitions from oblivion
+;;     (i.e. when the parse tree comes from a part of the original
+;;     buffer), it isn't meant for direct use in a back-end.  To
+;;     retrieve a definition relative to a reference, use
+;;     `org-export-get-footnote-definition' instead.
 ;;   - category :: option
 ;;   - category :: option
 ;;   - type :: alist (STRING . LIST)
 ;;   - type :: alist (STRING . LIST)
 
 
+;; + `footnote-seen-labels' :: List of already transcoded footnote
+;;      labels.  It is used to know when a reference appears for the
+;;      first time. (cf. `org-export-footnote-first-reference-p').
+;;   - category :: persistent
+;;   - type :: list of strings
+;;   - update :: `org-export-update-info'
+
 ;; + `genealogy' :: List of current element's parents types.
 ;; + `genealogy' :: List of current element's parents types.
 ;;   - category :: local
 ;;   - category :: local
 ;;   - type :: list of symbols
 ;;   - type :: list of symbols
@@ -620,7 +633,7 @@ while every other back-end will ignore it."
 ;;      the current buffer, through the "#+include:" keyword.  It is
 ;;      the current buffer, through the "#+include:" keyword.  It is
 ;;      mainly used to verify that no infinite recursive inclusion
 ;;      mainly used to verify that no infinite recursive inclusion
 ;;      happens.
 ;;      happens.
-;;   - category :: persistent
+;;   - category :: local
 ;;   - type :: list of strings
 ;;   - type :: list of strings
 
 
 ;; + `inherited-properties' :: Properties of the headline ancestors
 ;; + `inherited-properties' :: Properties of the headline ancestors
@@ -668,24 +681,11 @@ while every other back-end will ignore it."
 ;;   - type :: symbol
 ;;   - type :: symbol
 ;;   - update :: `org-export-update-info'
 ;;   - update :: `org-export-update-info'
 
 
-;; + `previous-section-number' :: Numbering of the previous
-;;      headline.  As it might not be practical for direct use, the
-;;      function `org-export-get-headline-level' is provided
-;;      to extract useful information out of it.
-;;   - category :: local
-;;   - type :: vector
-
 ;; + `section-numbers' :: Non-nil means transcoding should add
 ;; + `section-numbers' :: Non-nil means transcoding should add
 ;;      section numbers to headlines.
 ;;      section numbers to headlines.
 ;;   - category :: option
 ;;   - category :: option
 ;;   - type :: symbol (nil, t)
 ;;   - type :: symbol (nil, t)
 
 
-;; + `seen-footnote-labels' :: List of already transcoded footnote
-;;      labels.
-;;   - category :: persistent
-;;   - type :: list of strings
-;;   - update :: `org-export-update-info'
-
 ;; + `select-tags' :: List of tags enforcing inclusion of sub-trees in
 ;; + `select-tags' :: List of tags enforcing inclusion of sub-trees in
 ;;                    transcoding.  When such a tag is present,
 ;;                    transcoding.  When such a tag is present,
 ;;                    subtrees without it are de facto excluded from
 ;;                    subtrees without it are de facto excluded from
@@ -707,7 +707,7 @@ while every other back-end will ignore it."
 
 
 ;; + `total-loc' :: Contains total lines of code accumulated by source
 ;; + `total-loc' :: Contains total lines of code accumulated by source
 ;;                  blocks with the "+n" option so far.
 ;;                  blocks with the "+n" option so far.
-;;   - category :: option
+;;   - category :: persistent
 ;;   - type :: integer
 ;;   - type :: integer
 ;;   - update :: `org-export-handle-code'
 ;;   - update :: `org-export-handle-code'
 
 
@@ -1037,6 +1037,10 @@ BACKEND is a symbol specifying which back-end should be used."
   "Return a plist with non-optional properties.
   "Return a plist with non-optional properties.
 OPTIONS is the export options plist computed so far."
 OPTIONS is the export options plist computed so far."
   (list
   (list
+   ;; `:macro-date', `:macro-time' and `:macro-property' could as well
+   ;; be initialized as persistent properties, since they don't depend
+   ;; on initial environment.  Though, it may be more logical to keep
+   ;; them close to other ":macro-" properties.
    :macro-date "(eval (format-time-string \"$1\"))"
    :macro-date "(eval (format-time-string \"$1\"))"
    :macro-time "(eval (format-time-string \"$1\"))"
    :macro-time "(eval (format-time-string \"$1\"))"
    :macro-property "(eval (org-entry-get nil \"$1\" 'selective))"
    :macro-property "(eval (org-entry-get nil \"$1\" 'selective))"
@@ -1048,18 +1052,22 @@ OPTIONS is the export options plist computed so far."
 		"))"))
 		"))"))
    :macro-input-file (and (buffer-file-name)
    :macro-input-file (and (buffer-file-name)
 			  (file-name-nondirectory (buffer-file-name)))
 			  (file-name-nondirectory (buffer-file-name)))
-   :footnotes-labels-alist
+   ;; Footnotes definitions must be collected in the original buffer,
+   ;; as there's no insurance that they will still be in the parse
+   ;; tree, due to some narrowing.
+   :footnote-definition-alist
    (let (alist)
    (let (alist)
      (org-with-wide-buffer
      (org-with-wide-buffer
       (goto-char (point-min))
       (goto-char (point-min))
       (while (re-search-forward org-footnote-definition-re nil t)
       (while (re-search-forward org-footnote-definition-re nil t)
 	(let ((def (org-footnote-at-definition-p)))
 	(let ((def (org-footnote-at-definition-p)))
-	  (org-skip-whitespace)
+	  (when def
-	  (push (cons (car def)
+	    (org-skip-whitespace)
-		      (save-restriction
+	    (push (cons (car def)
-			(narrow-to-region (point) (nth 2 def))
+			(save-restriction
-			(org-element-parse-buffer)))
+			  (narrow-to-region (point) (nth 2 def))
-		alist)))
+			  (org-element-parse-buffer)))
+		  alist))))
       alist))))
       alist))))
 
 
 (defvar org-export-allow-BIND-local nil)
 (defvar org-export-allow-BIND-local nil)
@@ -1108,8 +1116,9 @@ retrieved."
 ;; between headlines' beginning position and their numbering.
 ;; between headlines' beginning position and their numbering.
 
 
 (defconst org-export-persistent-properties-list
 (defconst org-export-persistent-properties-list
-  '(:code-refs :headline-alist :headline-offset :headline-offset :parse-tree
+  '(:back-end :code-refs :headline-alist :headline-numbering :headline-offset
-	       :point-max :seen-footnote-labels :total-loc :use-select-tags)
+	      :parse-tree :point-max :footnote-seen-labels :target-list
+	      :total-loc :use-select-tags)
   "List of persistent properties.")
   "List of persistent properties.")
 
 
 (defconst org-export-persistent-properties nil
 (defconst org-export-persistent-properties nil
@@ -1251,7 +1260,8 @@ numbers)."
      data
      data
      'headline
      'headline
      (lambda (headline info)
      (lambda (headline info)
-       (let ((relative-level (1- (org-export-get-relative-level blob info))))
+       (let ((relative-level
+	      (1- (org-export-get-relative-level headline info))))
 	 (cons
 	 (cons
 	  (org-element-get-property :begin headline)
 	  (org-element-get-property :begin headline)
 	  (loop for n across numbering
 	  (loop for n across numbering
@@ -1284,6 +1294,8 @@ When RECURSEP is non-nil, assume the following element or object
 will be inside the current one.
 will be inside the current one.
 
 
 The following properties are updated:
 The following properties are updated:
+`footnote-seen-labels'    List of already parsed footnote
+			  labels (string list)
 `genealogy'               List of current element's parents
 `genealogy'               List of current element's parents
 			  (symbol list).
 			  (symbol list).
 `inherited-properties'    List of inherited properties from
 `inherited-properties'    List of inherited properties from
@@ -1292,8 +1304,6 @@ The following properties are updated:
 			 (plist).
 			 (plist).
 `previous-element'        Previous element's type (symbol).
 `previous-element'        Previous element's type (symbol).
 `previous-object'         Previous object's type (symbol).
 `previous-object'         Previous object's type (symbol).
-`seen-footnote-labels'    List of already parsed footnote
-			  labels (string list)
 
 
 Return the property list."
 Return the property list."
   (let* ((type (and (not (stringp blob)) (car blob))))
   (let* ((type (and (not (stringp blob)) (car blob))))
@@ -1323,12 +1333,12 @@ Return the property list."
       (when (eq type 'footnote-reference)
       (when (eq type 'footnote-reference)
 	(let ((label (org-element-get-property :label blob))
 	(let ((label (org-element-get-property :label blob))
 	      (seen-labels (plist-get org-export-persistent-properties
 	      (seen-labels (plist-get org-export-persistent-properties
-				      :seen-footnote-labels)))
+				      :footnote-seen-labels)))
 	  ;; Store anonymous footnotes (nil label) without checking if
 	  ;; Store anonymous footnotes (nil label) without checking if
 	  ;; another anonymous footnote was seen before.
 	  ;; another anonymous footnote was seen before.
 	  (unless (and label (member label seen-labels))
 	  (unless (and label (member label seen-labels))
 	    (setq info (org-export-set-property
 	    (setq info (org-export-set-property
-			info :seen-footnote-labels (push label seen-labels))))))
+			info :footnote-seen-labels (push label seen-labels))))))
       ;; Set `:previous-element' or `:previous-object' according to
       ;; Set `:previous-element' or `:previous-object' according to
       ;; BLOB.
       ;; BLOB.
       (setq info (cond ((not type)
       (setq info (cond ((not type)
@@ -1908,8 +1918,8 @@ developer-specified filters, if any, are called first."
 ;;; Core functions
 ;;; Core functions
 
 
 ;; This is the room for the main function, `org-export-as', along with
 ;; This is the room for the main function, `org-export-as', along with
-;; its derivative, `org-export-to-buffer'.  They differ only by the
+;; its derivatives, `org-export-to-buffer' and `org-export-to-file'.
-;; way they output the resulting code.
+;; They differ only by the way they output the resulting code.
 
 
 ;; Note that `org-export-as' doesn't really parse the current buffer,
 ;; Note that `org-export-as' doesn't really parse the current buffer,
 ;; but a copy of it (with the same buffer-local variables and
 ;; but a copy of it (with the same buffer-local variables and
@@ -1986,7 +1996,8 @@ Return code as a string."
 	    (org-export-filter-apply-functions
 	    (org-export-filter-apply-functions
 	     org-export-filter-final-output-functions body backend)))))))
 	     org-export-filter-final-output-functions body backend)))))))
 
 
-(defun org-export-to-buffer (backend buffer &optional subtreep visible-only body-only ext-plist)
+(defun org-export-to-buffer (backend buffer &optional subtreep visible-only
+				     body-only ext-plist)
   "Call `org-export-as' with output to a specified buffer.
   "Call `org-export-as' with output to a specified buffer.
 
 
 BACKEND is the back-end used for transcoding, as a symbol.
 BACKEND is the back-end used for transcoding, as a symbol.
@@ -1994,12 +2005,8 @@ BACKEND is the back-end used for transcoding, as a symbol.
 BUFFER is the output buffer.  If it already exists, it will be
 BUFFER is the output buffer.  If it already exists, it will be
 erased first, otherwise, it will be created.
 erased first, otherwise, it will be created.
 
 
-Arguments SUBTREEP, VISIBLE-ONLY and BODY-ONLY are similar to
+Arguments SUBTREEP, VISIBLE-ONLY, BODY-ONLY and EXT-PLIST are
-those used in `org-export-as'.
+similar to those used in `org-export-as', which see.
-
-EXT-PLIST, when provided, is a property list with external
-parameters overriding Org default settings, but still inferior to
-file-local settings.
 
 
 Return buffer."
 Return buffer."
   (let ((out (org-export-as backend subtreep visible-only body-only ext-plist))
   (let ((out (org-export-as backend subtreep visible-only body-only ext-plist))
@@ -2010,6 +2017,42 @@ Return buffer."
       (goto-char (point-min)))
       (goto-char (point-min)))
     buffer))
     buffer))
 
 
+(defun org-export-to-file (backend filename &optional post-process subtreep
+                                   visible-only body-only ext-plist)
+  "Call `org-export-as' with output to a specified file.
+
+BACKEND is the back-end used for transcoding, as a symbol.
+
+FILENAME is the output file name.  If it already exists, it will
+be erased first, unless it isn't writable, in which case an error
+will be returned.  Otherwise, the file will be created.
+
+Optional argument POST-PROCESS, when non-nil, is a function
+applied to the output file.  It expects one argument: the file
+name, as a string.  It can be used to call shell commands on that
+file, display a specific buffer, etc.
+
+Optional arguments SUBTREEP, VISIBLE-ONLY, BODY-ONLY and
+EXT-PLIST are similar to those used in `org-export-as', which
+see.
+
+Return file name."
+  ;; Checks for file and directory permissions.
+  (cond
+   ((not (file-exists-p filename))
+    (let ((dir (or (file-name-directory filename) default-directory)))
+      (unless (file-writable-p dir) (error "Output directory not writable"))))
+   ((not (file-writable-p filename)) (error "Output file not writable")))
+  ;; All checks passed: insert contents to a temporary buffer and
+  ;; write it to the specified file.
+  (let ((out (org-export-as backend subtreep visible-only body-only ext-plist)))
+    (with-temp-buffer
+      (insert out)
+      (write-file filename)))
+  (when post-process (funcall post-process filename))
+  ;; Return value.
+  filename)
+
 (defmacro org-export-with-current-buffer-copy (&rest body)
 (defmacro org-export-with-current-buffer-copy (&rest body)
   "Apply BODY in a copy of the current buffer.
   "Apply BODY in a copy of the current buffer.
 
 
@@ -2047,9 +2090,82 @@ Point is at buffer's beginning when BODY is applied."
 ;; function general enough to have its use across many back-ends
 ;; function general enough to have its use across many back-ends
 ;; should be added here.
 ;; should be added here.
 
 
-;; As of now, functions operating on headlines, include keywords,
+;; As of now, functions operating on footnotes, headlines, include
-;; links, macros, src-blocks, tables and tables of contents are
+;; keywords, links, macros, references, src-blocks, tables and tables
-;; implemented.
+;; of contents are implemented.
+
+;;;; For Footnotes
+
+;; `org-export-collect-footnote-definitions' is a tool to list
+;; actually used footnotes definitions in the whole parse tree, or in
+;; an headline, in order to add footnote listings throughout the
+;; transcoded data.
+
+;; `org-export-footnote-first-reference-p' is a predicate used by some
+;; back-ends, when they need to attach the footnote definition only to
+;; the first occurrence of the corresponding label.
+
+;; `org-export-get-footnote-definition' and
+;; `org-export-get-footnote-number' provide easier access to
+;; additional information relative to a footnote reference.
+
+(defun org-export-collect-footnote-definitions (data info)
+  "Return an alist between footnote numbers, labels and definitions.
+
+DATA is the parse tree from which definitions are collected.
+INFO is the plist used as a communication channel.
+
+Definitions are sorted by order of references.  They either
+appear as Org data \(transcoded with `org-export-data'\) or as
+a secondary string for inlined footnotes \(transcoded with
+`org-export-secondary-string'\).  Unreferenced definitions are
+ignored."
+  (org-element-map
+   data 'footnote-reference
+   (lambda (footnote local)
+     (when (org-export-footnote-first-reference-p footnote local)
+       (list (org-export-get-footnote-number footnote local)
+	     (org-element-get-property :label footnote)
+	     (org-export-get-footnote-definition footnote local))))
+   info))
+
+(defun org-export-footnote-first-reference-p (footnote-reference info)
+  "Non-nil when a footnote reference is the first one for its label.
+
+FOOTNOTE-REFERENCE is the footnote reference being considered.
+INFO is the plist used as a communication channel."
+  (let ((label (org-element-get-property :label footnote-reference)))
+    (not (and label (member label (plist-get info :footnote-seen-labels))))))
+
+(defun org-export-get-footnote-definition (footnote-reference info)
+  "Return definition of FOOTNOTE-REFERENCE as parsed data.
+INFO is the plist used as a communication channel."
+  (let ((label (org-element-get-property :label footnote-reference)))
+    (or (org-element-get-property :inline-definition footnote-reference)
+        (cdr (assoc label (plist-get info :footnote-definition-alist))))))
+
+(defun org-export-get-footnote-number (footnote info)
+  "Return number associated to a footnote.
+
+FOOTNOTE is either a footnote reference or a footnote definition.
+INFO is the plist used as a communication channel."
+  (let ((label (org-element-get-property :label footnote)))
+    (if (eq (car footnote) 'footnote-definition)
+	;; If a footnote definition was provided, first search for
+	;; a relative footnote reference, as only footnote references
+	;; can determine the associated ordinal.
+	(org-element-map
+	 (plist-get info :parse-tree) 'footnote-reference
+	 (lambda (foot-ref local)
+	   (when (string= (org-element-get-property :label foot-ref) label)
+	     (let* ((all-seen (plist-get info :footnote-seen-labels))
+		    (seenp (and label (member label all-seen))))
+	       (if seenp (length seenp) (1+ (length all-seen))))))
+	 info 'first-match)
+      (let* ((all-seen (plist-get info :footnote-seen-labels))
+	     ;; Anonymous footnotes are always new footnotes.
+	     (seenp (and label (member label all-seen))))
+	(if seenp (length seenp) (1+ (length all-seen)))))))
 
 
 
 
 ;;;; For Headlines
 ;;;; For Headlines
@@ -2244,15 +2360,13 @@ PATH is the link path.  DESC is its description."
 	  ((string= desc "") "%s")
 	  ((string= desc "") "%s")
 	  (t desc))))
 	  (t desc))))
 
 
-(defun org-export-inline-image-p (link contents &optional extensions)
+(defun org-export-inline-image-p (link &optional extensions)
   "Non-nil if LINK object points to an inline image.
   "Non-nil if LINK object points to an inline image.
 
 
-CONTENTS is the link description part, as a string, or nil.
-
 When non-nil, optional argument EXTENSIONS is a list of valid
 When non-nil, optional argument EXTENSIONS is a list of valid
 extensions for image files, as strings.  Otherwise, a default
 extensions for image files, as strings.  Otherwise, a default
 list is provided \(cf. `org-image-file-name-regexp'\)."
 list is provided \(cf. `org-image-file-name-regexp'\)."
-  (and (or (not contents) (string= contents ""))
+  (and (not (org-element-get-contents link))
        (string= (org-element-get-property :type link) "file")
        (string= (org-element-get-property :type link) "file")
        (org-file-image-p
        (org-file-image-p
 	(expand-file-name (org-element-get-property :path link))
 	(expand-file-name (org-element-get-property :path link))
@@ -2338,6 +2452,56 @@ INFO is a plist holding export options."
     (format "%s" value)))
     (format "%s" value)))
 
 
 
 
+;;;; For References
+
+;; `org-export-get-ordinal' associates a sequence number to any object
+;; or element.
+
+(defun org-export-get-ordinal (element info &optional within-section predicate)
+  "Return ordinal number of an element or object.
+
+ELEMENT is the element or object considered.  INFO is the plist
+used as a communication channel.
+
+When optional argument WITHIN-SECTION is non-nil, narrow counting
+to the section containing ELEMENT.
+
+Optional argument PREDICATE is a function returning a non-nil
+value if the current element or object should be counted in.  It
+accepts one argument: the element or object being considered.
+This argument allows to count only a certain type of objects,
+like inline images, which are a subset of links \(in that case,
+`org-export-inline-image-p' might be an useful predicate\)."
+  (let ((counter 0)
+        (type (car element))
+        ;; Determine if search should apply to current section, in
+        ;; which case it should be retrieved first, or to full parse
+        ;; tree.  As a special case, an element or object without
+        ;; a parent headline will also trigger a full search,
+        ;; notwithstanding WITHIN-SECTION value.
+        (data
+         (let ((parse-tree (plist-get info :parse-tree)))
+           (if within-section
+               (let ((parent (plist-get (plist-get info :inherited-properties)
+                                        :begin)))
+                 (if (not parent) parse-tree
+                   (org-element-map
+                    parse-tree 'headline
+                    (lambda (el local)
+                      (when (= (org-element-get-property :begin el) parent) el))
+                    info 'first-match)))
+             parse-tree))))
+    ;; Increment counter until ELEMENT is found again.
+    (org-element-map
+     data type
+     (lambda (el local)
+       (cond
+        ((and (functionp predicate) (funcall predicate el)))
+        ((equal element el) (1+ counter))
+        (t (incf counter) nil)))
+     info 'first-match)))
+
+
 ;;;; For Src-Blocks
 ;;;; For Src-Blocks
 
 
 ;; `org-export-handle-code' takes care of line numbering and reference
 ;; `org-export-handle-code' takes care of line numbering and reference
@@ -2555,57 +2719,29 @@ it also."
 
 
 ;;;; For Tables Of Contents
 ;;;; For Tables Of Contents
 
 
-;; `org-export-get-headlines' builds a table of contents in the shape
+;; `org-export-collect-headlines' builds a list of all exportable
-;; of a nested list of cons cells whose car is headline's name and cdr
+;; headline elements, maybe limited to a certain depth.  One can then
-;; an unique identifier.  One can then easily parse it and transcode
+;; easily parse it and transcode it.
-;; it in a back-end.  Identifiers can be used to construct internal
-;; links.
 
 
 ;; Building lists of tables, figures or listings is quite similar.
 ;; Building lists of tables, figures or listings is quite similar.
 ;; Once the generic function `org-export-collect-elements' is defined,
 ;; Once the generic function `org-export-collect-elements' is defined,
 ;; `org-export-collect-tables', `org-export-collect-figures' and
 ;; `org-export-collect-tables', `org-export-collect-figures' and
 ;; `org-export-collect-listings' can be derived from it.
 ;; `org-export-collect-listings' can be derived from it.
 
 
-(defun org-export-get-headlines (backend info &optional n)
+(defun org-export-collect-headlines (info &optional n)
-  "Build a table of contents.
+  "Collect headlines in order to build a table of contents.
-
-BACKEND is the back-end used to transcode headline's name.  INFO
-is a plist holding export options.
 
 
 When non-nil, optional argument N must be an integer.  It
 When non-nil, optional argument N must be an integer.  It
 specifies the depth of the table of contents.
 specifies the depth of the table of contents.
 
 
-Return an alist whose keys are headlines' name and value their
+Return a list of all exportable headlines as parsed elements."
-relative level and an unique identifier that might be used for
-internal links.
-
-For example, on the following tree, where numbers in parens are
-buffer position at beginning of the line:
-
-* Title 1       (1)
-** Sub-title 1  (21)
-** Sub-title 2  (42)
-* Title 2       (62)
-
-the function will return:
-
-\(\(\"Title 1\" 1 1\)
- \(\"Sub-title 1\" 2 21\)
- \(\"Sub-title 2\" 2 42\)
- \(\"Title 2\" 1 62\)\)"
   (org-element-map
   (org-element-map
    (plist-get info :parse-tree)
    (plist-get info :parse-tree)
    'headline
    'headline
-   (lambda (headline local-info)
+   (lambda (headline local)
-     ;; Get HEADLINE's relative level.
+     ;; Strip contents from HEADLINE.
-     (let ((level (+ (or (plist-get local-info :headline-offset) 0)
+     (let ((relative-level (org-export-get-relative-level headline local)))
-		     (org-element-get-property :level headline))))
+       (unless (and n (> relative-level n)) headline)))
-       (unless (and (wholenump n) (> level n))
-	 (list
-	  (org-export-secondary-string
-	   (org-element-get-property :title headline) backend info)
-	  level
-	  (org-element-get-property :begin headline)))))
    info))
    info))
 
 
 (defun org-export-collect-elements (type backend info)
 (defun org-export-collect-elements (type backend info)
@@ -2644,7 +2780,7 @@ Return an alist where key is the caption of the table and value
 an unique identifier that might be used for internal links."
 an unique identifier that might be used for internal links."
   (org-export-collect-elements 'table backend info))
   (org-export-collect-elements 'table backend info))
 
 
-(defun org-export-get-figures (backend info)
+(defun org-export-collect-figures (backend info)
   "Build a list of figures.
   "Build a list of figures.
 
 
 A figure is a paragraph type element with a caption or a name.
 A figure is a paragraph type element with a caption or a name.

+ 3 - 3
contrib/lisp/org-wikinodes.el

@@ -102,7 +102,7 @@ to `directory'."
 
 
 This function goes into `org-open-at-point-functions'."
 This function goes into `org-open-at-point-functions'."
   (and org-wikinodes-active
   (and org-wikinodes-active
-       (not (org-on-heading-p))
+       (not (org-at-heading-p))
        (let (case-fold-search) (org-in-regexp org-wikinodes-camel-regexp))
        (let (case-fold-search) (org-in-regexp org-wikinodes-camel-regexp))
        (progn (org-wikinodes-follow-link (match-string 0)) t)))
        (progn (org-wikinodes-follow-link (match-string 0)) t)))
 
 
@@ -180,7 +180,7 @@ setting of `org-wikinodes-create-targets'."
 
 
 (defun org-wikinodes-clear-cache-when-on-target ()
 (defun org-wikinodes-clear-cache-when-on-target ()
   "When on a headline that is a Wiki target, clear the cache."
   "When on a headline that is a Wiki target, clear the cache."
-  (when (and (org-on-heading-p)
+  (when (and (org-at-heading-p)
 	     (org-in-regexp (format org-complex-heading-regexp-format
 	     (org-in-regexp (format org-complex-heading-regexp-format
 				    org-wikinodes-camel-regexp))
 				    org-wikinodes-camel-regexp))
 	     (org-in-regexp org-wikinodes-camel-regexp))
 	     (org-in-regexp org-wikinodes-camel-regexp))
@@ -280,7 +280,7 @@ with working links."
     (while (re-search-forward re nil t)
     (while (re-search-forward re nil t)
       (org-if-unprotected-at (match-beginning 0)
       (org-if-unprotected-at (match-beginning 0)
 	(unless (save-match-data
 	(unless (save-match-data
-		  (or (org-on-heading-p)
+		  (or (org-at-heading-p)
 		      (org-in-regexp org-bracket-link-regexp)
 		      (org-in-regexp org-bracket-link-regexp)
 		      (org-in-regexp org-plain-link-re)
 		      (org-in-regexp org-plain-link-re)
 		      (org-in-regexp "<<[^<>]+>>")))
 		      (org-in-regexp "<<[^<>]+>>")))

+ 16 - 6
doc/org.texi

@@ -8036,18 +8036,27 @@ Remove the restriction lock on the agenda, if it is currently restricted to a
 file or subtree (@pxref{Agenda files}).
 file or subtree (@pxref{Agenda files}).
 
 
 @tsubheading{Secondary filtering and query editing}
 @tsubheading{Secondary filtering and query editing}
-@cindex filtering, by tag and effort, in agenda
+@cindex filtering, by tag category and effort, in agenda
 @cindex tag filtering, in agenda
 @cindex tag filtering, in agenda
+@cindex category filtering, in agenda
 @cindex effort filtering, in agenda
 @cindex effort filtering, in agenda
 @cindex query editing, in agenda
 @cindex query editing, in agenda
 
 
+@orgcmd{<,org-agenda-filter-by-category}
+@vindex org-agenda-category-filter-preset
+
+Filter the current agenda view with respect to the category of the item at
+point.  Pressing @code{<} another time will remove this filter.  You can add
+a filter preset through the option @code{org-agenda-category-filter-preset}
+(see below.)
+
 @orgcmd{/,org-agenda-filter-by-tag}
 @orgcmd{/,org-agenda-filter-by-tag}
-@vindex org-agenda-filter-preset
+@vindex org-agenda-tag-filter-preset
 Filter the current agenda view with respect to a tag and/or effort estimates.
 Filter the current agenda view with respect to a tag and/or effort estimates.
 The difference between this and a custom agenda command is that filtering is
 The difference between this and a custom agenda command is that filtering is
 very fast, so that you can switch quickly between different filters without
 very fast, so that you can switch quickly between different filters without
 having to recreate the agenda.@footnote{Custom commands can preset a filter by
 having to recreate the agenda.@footnote{Custom commands can preset a filter by
-binding the variable @code{org-agenda-filter-preset} as an option.  This
+binding the variable @code{org-agenda-tag-filter-preset} as an option.  This
 filter will then be applied to the view and persist as a basic filter through
 filter will then be applied to the view and persist as a basic filter through
 refreshes and more secondary filtering.  The filter is a global property of
 refreshes and more secondary filtering.  The filter is a global property of
 the entire agenda view---in a block agenda, you should only set this in the
 the entire agenda view---in a block agenda, you should only set this in the
@@ -9636,10 +9645,11 @@ Insert template with export options, see example below.
 @vindex user-full-name
 @vindex user-full-name
 @vindex user-mail-address
 @vindex user-mail-address
 @vindex org-export-default-language
 @vindex org-export-default-language
+@vindex org-export-date-timestamp-format
 @example
 @example
 #+TITLE:       the title to be shown (default is the buffer name)
 #+TITLE:       the title to be shown (default is the buffer name)
 #+AUTHOR:      the author (default taken from @code{user-full-name})
 #+AUTHOR:      the author (default taken from @code{user-full-name})
-#+DATE:        a date, fixed, or a format string for @code{format-time-string}
+#+DATE:        a date, an Org timestamp@footnote{@code{org-export-date-timestamp-format} defines how this timestamp will be exported.}, or a format string for @code{format-time-string}
 #+EMAIL:       his/her email address (default from @code{user-mail-address})
 #+EMAIL:       his/her email address (default from @code{user-mail-address})
 #+DESCRIPTION: the page description, e.g.@: for the XHTML meta tag
 #+DESCRIPTION: the page description, e.g.@: for the XHTML meta tag
 #+KEYWORDS:    the page keywords, e.g.@: for the XHTML meta tag
 #+KEYWORDS:    the page keywords, e.g.@: for the XHTML meta tag
@@ -9658,8 +9668,8 @@ Insert template with export options, see example below.
 @end example
 @end example
 
 
 @noindent
 @noindent
-The OPTIONS line is a compact@footnote{If you want to configure many options
+The @code{#+OPTIONS} line is a compact@footnote{If you want to configure many options
-this way, you can use several OPTIONS lines.} form to specify export
+this way, you can use several @code{#+OPTIONS} lines.} form to specify export
 settings.  Here you can:
 settings.  Here you can:
 @cindex headline levels
 @cindex headline levels
 @cindex section-numbers
 @cindex section-numbers

+ 12 - 0
etc/styles/OrgOdtStyles.xml

@@ -391,6 +391,12 @@
    <style:graphic-properties text:anchor-type="paragraph" style:wrap="none" style:vertical-pos="top" style:vertical-rel="paragraph" style:horizontal-pos="center" style:horizontal-rel="paragraph"/>
    <style:graphic-properties text:anchor-type="paragraph" style:wrap="none" style:vertical-pos="top" style:vertical-rel="paragraph" style:horizontal-pos="center" style:horizontal-rel="paragraph"/>
   </style:style>
   </style:style>
 
 
+  <style:style style:name="OrgPageImage" style:family="graphic" style:parent-style-name="Graphics">
+   <style:graphic-properties text:anchor-type="page" fo:margin-top="0.21cm" fo:margin-bottom="0.21cm" style:vertical-pos="middle" style:vertical-rel="page" style:horizontal-pos="center" style:horizontal-rel="page" fo:background-color="transparent" style:background-transparency="100%" style:shadow="none" style:mirror="none" fo:clip="rect(0cm, 0cm, 0cm, 0cm)" draw:luminance="0%" draw:contrast="0%" draw:red="0%" draw:green="0%" draw:blue="0%" draw:gamma="100%" draw:color-inversion="false" draw:image-opacity="100%" draw:color-mode="standard">
+    <style:background-image/>
+   </style:graphic-properties>
+  </style:style>
+
   <!-- Captioned Images  -->
   <!-- Captioned Images  -->
   <style:style style:name="OrgCaptionedImage" style:family="graphic" style:parent-style-name="Graphics">
   <style:style style:name="OrgCaptionedImage" style:family="graphic" style:parent-style-name="Graphics">
    <style:graphic-properties style:rel-width="100%" text:anchor-type="paragraph" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0cm" fo:margin-bottom="0cm" style:run-through="foreground" style:wrap="none" style:vertical-pos="from-top" style:vertical-rel="paragraph-content" style:horizontal-pos="from-left" style:horizontal-rel="paragraph-content" fo:padding="0cm" fo:border="none" style:shadow="none"/>
    <style:graphic-properties style:rel-width="100%" text:anchor-type="paragraph" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0cm" fo:margin-bottom="0cm" style:run-through="foreground" style:wrap="none" style:vertical-pos="from-top" style:vertical-rel="paragraph-content" style:horizontal-pos="from-left" style:horizontal-rel="paragraph-content" fo:padding="0cm" fo:border="none" style:shadow="none"/>
@@ -400,6 +406,12 @@
    <style:graphic-properties text:anchor-type="paragraph" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0cm" fo:margin-bottom="0cm" style:wrap="none" style:vertical-pos="top" style:vertical-rel="paragraph" style:horizontal-pos="center" style:horizontal-rel="paragraph" fo:padding="0cm" fo:border="none"/>
    <style:graphic-properties text:anchor-type="paragraph" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0cm" fo:margin-bottom="0cm" style:wrap="none" style:vertical-pos="top" style:vertical-rel="paragraph" style:horizontal-pos="center" style:horizontal-rel="paragraph" fo:padding="0cm" fo:border="none"/>
   </style:style>
   </style:style>
 
 
+  <style:style style:name="OrgPageImageCaptionFrame" style:family="graphic" style:parent-style-name="Frame">
+   <style:graphic-properties text:anchor-type="paragraph" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0.21cm" fo:margin-bottom="0.21cm" style:wrap="none" style:vertical-pos="middle" style:vertical-rel="page" style:horizontal-pos="center" style:horizontal-rel="page" fo:background-color="transparent" style:background-transparency="100%" fo:padding="0cm" fo:border="none" style:shadow="none">
+    <style:background-image/>
+   </style:graphic-properties>
+  </style:style>
+
   <!-- Inlined Images -->
   <!-- Inlined Images -->
   <style:style style:name="OrgInlineImage" style:family="graphic" style:parent-style-name="Graphics">
   <style:style style:name="OrgInlineImage" style:family="graphic" style:parent-style-name="Graphics">
    <style:graphic-properties text:anchor-type="as-char" style:vertical-pos="top" style:vertical-rel="baseline" style:horizontal-pos="center" style:horizontal-rel="paragraph"/>
    <style:graphic-properties text:anchor-type="as-char" style:vertical-pos="top" style:vertical-rel="baseline" style:horizontal-pos="center" style:horizontal-rel="paragraph"/>

+ 23 - 7
lisp/ob-octave.el

@@ -86,13 +86,24 @@ end")
 	  (org-babel-expand-body:generic
 	  (org-babel-expand-body:generic
 	   body params (org-babel-variable-assignments:octave params)))
 	   body params (org-babel-variable-assignments:octave params)))
 	 (result (org-babel-octave-evaluate
 	 (result (org-babel-octave-evaluate
-		  session full-body result-type matlabp)))
+		  session
-    (org-babel-reassemble-table
+		  (if (org-babel-octave-graphical-output-file params)
-     result
+		      (mapconcat 'identity
-     (org-babel-pick-name
+				 (list
-      (cdr (assoc :colname-names params)) (cdr (assoc :colnames params)))
+				  "set (0, \"defaultfigurevisible\", \"off\");"
-     (org-babel-pick-name
+				  full-body
-      (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params))))))
+				  (format "print -dpng %s" (org-babel-octave-graphical-output-file params)))
+				 "\n")
+		    full-body)
+		  result-type matlabp)))
+    (if (org-babel-octave-graphical-output-file params)
+	nil
+      (org-babel-reassemble-table
+       result
+       (org-babel-pick-name
+	(cdr (assoc :colname-names params)) (cdr (assoc :colnames params)))
+       (org-babel-pick-name
+	(cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))))
 
 
 (defun org-babel-prep-session:matlab (session params)
 (defun org-babel-prep-session:matlab (session params)
   "Prepare SESSION according to PARAMS."
   "Prepare SESSION according to PARAMS."
@@ -259,6 +270,11 @@ This removes initial blank and comment lines and then calls
       (match-string 1 string)
       (match-string 1 string)
     string))
     string))
 
 
+(defun org-babel-octave-graphical-output-file (params)
+  "Name of file to which maxima should send graphical output."
+  (and (member "graphics" (cdr (assq :result-params params)))
+       (cdr (assq :file params))))
+
 (provide 'ob-octave)
 (provide 'ob-octave)
 
 
 
 

+ 23 - 7
lisp/ob.el

@@ -1979,6 +1979,12 @@ parameters when merging lists."
      '(results exports tangle noweb padline cache shebang comments))
      '(results exports tangle noweb padline cache shebang comments))
     params))
     params))
 
 
+(defvar *org-babel-use-quick-and-dirty-noweb-expansion* nil
+  "Set to true to use regular expressions to expand noweb references.
+This results in much faster noweb reference expansion but does
+not properly allow code blocks to inherit the \":noweb-ref\"
+header argument from buffer or subtree wide properties.")
+
 (defun org-babel-expand-noweb-references (&optional info parent-buffer)
 (defun org-babel-expand-noweb-references (&optional info parent-buffer)
   "Expand Noweb references in the body of the current source code block.
   "Expand Noweb references in the body of the current source code block.
 
 
@@ -2057,18 +2063,28 @@ block but are passed literally to the \"example-block\"."
 		  (let (expansion)
 		  (let (expansion)
 		    (save-excursion
 		    (save-excursion
 		      (goto-char (point-min))
 		      (goto-char (point-min))
-		      (org-babel-map-src-blocks nil
+		      (if *org-babel-use-quick-and-dirty-noweb-expansion*
-			(let ((i (org-babel-get-src-block-info 'light)))
+			  (while (re-search-forward rx nil t)
-			  (when (equal (or (cdr (assoc :noweb-ref (nth 2 i)))
+			    (let* ((i (org-babel-get-src-block-info 'light))
-					   (nth 4 i))
+				   (body (org-babel-expand-noweb-references i)))
-				       source-name)
-			    (let ((body (org-babel-expand-noweb-references i)))
 			      (if comment
 			      (if comment
 				  ((lambda (cs)
 				  ((lambda (cs)
 				     (concat (c-wrap (car cs)) "\n"
 				     (concat (c-wrap (car cs)) "\n"
 					     body "\n" (c-wrap (cadr cs))))
 					     body "\n" (c-wrap (cadr cs))))
 				   (org-babel-tangle-comment-links i))
 				   (org-babel-tangle-comment-links i))
-				(setq expansion (concat expansion body))))))))
+				(setq expansion (concat expansion body)))))
+			(org-babel-map-src-blocks nil
+			  (let ((i (org-babel-get-src-block-info 'light)))
+			    (when (equal (or (cdr (assoc :noweb-ref (nth 2 i)))
+					     (nth 4 i))
+					 source-name)
+			      (let ((body (org-babel-expand-noweb-references i)))
+				(if comment
+				    ((lambda (cs)
+				       (concat (c-wrap (car cs)) "\n"
+					       body "\n" (c-wrap (cadr cs))))
+				     (org-babel-tangle-comment-links i))
+				  (setq expansion (concat expansion body)))))))))
 		    expansion)
 		    expansion)
 		  ;; possibly raise an error if named block doesn't exist
 		  ;; possibly raise an error if named block doesn't exist
 		  (if (member lang org-babel-noweb-error-langs)
 		  (if (member lang org-babel-noweb-error-langs)

+ 148 - 61
lisp/org-agenda.el

@@ -245,6 +245,10 @@ you can \"misuse\" it to also add other text to the header.  However,
     (const user-defined-up) (const user-defined-down))
     (const user-defined-up) (const user-defined-down))
   "Sorting choices.")
   "Sorting choices.")
 
 
+;; Keep custom values for `org-agenda-filter-preset' compatible with
+;; the new variable `org-agenda-tag-filter-preset'.
+(defvaralias 'org-agenda-filter-preset 'org-agenda-tag-filter-preset)
+
 (defconst org-agenda-custom-commands-local-options
 (defconst org-agenda-custom-commands-local-options
   `(repeat :tag "Local settings for this command. Remember to quote values"
   `(repeat :tag "Local settings for this command. Remember to quote values"
 	   (choice :tag "Setting"
 	   (choice :tag "Setting"
@@ -286,8 +290,14 @@ you can \"misuse\" it to also add other text to the header.  However,
 	    (list :tag "Deadline Warning days"
 	    (list :tag "Deadline Warning days"
 		  (const org-deadline-warning-days)
 		  (const org-deadline-warning-days)
 		  (integer :value 1))
 		  (integer :value 1))
+	    (list :tag "Category filter preset"
+		  (const org-agenda-category-filter-preset)
+		  (list
+		   (const :format "" quote)
+		   (repeat
+		    (string :tag "+category or -category"))))
 	    (list :tag "Tags filter preset"
 	    (list :tag "Tags filter preset"
-		  (const org-agenda-filter-preset)
+		  (const org-agenda-tag-filter-preset)
 		  (list
 		  (list
 		   (const :format "" quote)
 		   (const :format "" quote)
 		   (repeat
 		   (repeat
@@ -1901,7 +1911,7 @@ The following commands are available:
 (org-defkey org-agenda-mode-map "\C-c\C-xp" 'org-agenda-set-property)
 (org-defkey org-agenda-mode-map "\C-c\C-xp" 'org-agenda-set-property)
 (org-defkey org-agenda-mode-map "q" 'org-agenda-quit)
 (org-defkey org-agenda-mode-map "q" 'org-agenda-quit)
 (org-defkey org-agenda-mode-map "x" 'org-agenda-exit)
 (org-defkey org-agenda-mode-map "x" 'org-agenda-exit)
-(org-defkey org-agenda-mode-map "\C-x\C-w" 'org-write-agenda)
+(org-defkey org-agenda-mode-map "\C-x\C-w" 'org-agenda-write)
 (org-defkey org-agenda-mode-map "\C-x\C-s" 'org-save-all-org-buffers)
 (org-defkey org-agenda-mode-map "\C-x\C-s" 'org-save-all-org-buffers)
 (org-defkey org-agenda-mode-map "s" 'org-save-all-org-buffers)
 (org-defkey org-agenda-mode-map "s" 'org-save-all-org-buffers)
 (org-defkey org-agenda-mode-map "P" 'org-agenda-show-priority)
 (org-defkey org-agenda-mode-map "P" 'org-agenda-show-priority)
@@ -1949,6 +1959,7 @@ The following commands are available:
 (org-defkey org-agenda-mode-map "}" 'org-agenda-manipulate-query-subtract-re)
 (org-defkey org-agenda-mode-map "}" 'org-agenda-manipulate-query-subtract-re)
 (org-defkey org-agenda-mode-map "/" 'org-agenda-filter-by-tag)
 (org-defkey org-agenda-mode-map "/" 'org-agenda-filter-by-tag)
 (org-defkey org-agenda-mode-map "\\" 'org-agenda-filter-by-tag-refine)
 (org-defkey org-agenda-mode-map "\\" 'org-agenda-filter-by-tag-refine)
+(org-defkey org-agenda-mode-map "<" 'org-agenda-filter-by-category)
 (org-defkey org-agenda-mode-map ";" 'org-timer-set-timer)
 (org-defkey org-agenda-mode-map ";" 'org-timer-set-timer)
 (define-key org-agenda-mode-map "?" 'org-agenda-show-the-flagging-note)
 (define-key org-agenda-mode-map "?" 'org-agenda-show-the-flagging-note)
 (org-defkey org-agenda-mode-map "\C-c\C-x\C-mg"    'org-mobile-pull)
 (org-defkey org-agenda-mode-map "\C-c\C-x\C-mg"    'org-mobile-pull)
@@ -2015,7 +2026,7 @@ The following commands are available:
       :keys "v A"]
       :keys "v A"]
      "--"
      "--"
      ["Remove Restriction" org-agenda-remove-restriction-lock org-agenda-restrict])
      ["Remove Restriction" org-agenda-remove-restriction-lock org-agenda-restrict])
-    ["Write view to file" org-write-agenda t]
+    ["Write view to file" org-agenda-write t]
     ["Rebuild buffer" org-agenda-redo t]
     ["Rebuild buffer" org-agenda-redo t]
     ["Save all Org-mode Buffers" org-save-all-org-buffers t]
     ["Save all Org-mode Buffers" org-save-all-org-buffers t]
     "--"
     "--"
@@ -2741,7 +2752,7 @@ This ensures the export commands can easily use it."
 	  (while files
 	  (while files
 	    (org-eval-in-environment (append org-agenda-exporter-settings
 	    (org-eval-in-environment (append org-agenda-exporter-settings
 					     opts pars)
 					     opts pars)
-	      (org-write-agenda (expand-file-name (pop files) dir) nil t)))
+	      (org-agenda-write (expand-file-name (pop files) dir) nil t)))
 	  (and (get-buffer org-agenda-buffer-name)
 	  (and (get-buffer org-agenda-buffer-name)
 	       (kill-buffer org-agenda-buffer-name)))))))
 	       (kill-buffer org-agenda-buffer-name)))))))
 (def-edebug-spec org-batch-store-agenda-views (&rest sexp))
 (def-edebug-spec org-batch-store-agenda-views (&rest sexp))
@@ -2757,7 +2768,8 @@ This ensures the export commands can easily use it."
 			 'org-agenda-title-append org-agenda-title-append))))
 			 'org-agenda-title-append org-agenda-title-append))))
 
 
 (defvar org-mobile-creating-agendas)
 (defvar org-mobile-creating-agendas)
-(defun org-write-agenda (file &optional open nosettings)
+(defvar org-agenda-write-buffer-name "Agenda View")
+(defun org-agenda-write (file &optional open nosettings)
   "Write the current buffer (an agenda view) as a file.
   "Write the current buffer (an agenda view) as a file.
 Depending on the extension of the file name, plain text (.txt),
 Depending on the extension of the file name, plain text (.txt),
 HTML (.html or .htm) or Postscript (.ps) is produced.
 HTML (.html or .htm) or Postscript (.ps) is produced.
@@ -2779,7 +2791,7 @@ higher priority settings."
 	 (let ((bs (copy-sequence (buffer-string))) beg)
 	 (let ((bs (copy-sequence (buffer-string))) beg)
 	   (org-agenda-unmark-filtered-text)
 	   (org-agenda-unmark-filtered-text)
 	   (with-temp-buffer
 	   (with-temp-buffer
-	     (rename-buffer "Agenda View" t)
+	     (rename-buffer org-agenda-write-buffer-name t)
 	     (set-buffer-modified-p nil)
 	     (set-buffer-modified-p nil)
 	     (insert bs)
 	     (insert bs)
 	     (org-agenda-remove-marked-text 'org-filtered)
 	     (org-agenda-remove-marked-text 'org-filtered)
@@ -2840,7 +2852,8 @@ higher priority settings."
     (set-buffer org-agenda-buffer-name))
     (set-buffer org-agenda-buffer-name))
   (when open (org-open-file file)))
   (when open (org-open-file file)))
 
 
-(defvar org-agenda-filter-overlays nil)
+(defvar org-agenda-tag-filter-overlays nil)
+(defvar org-agenda-cat-filter-overlays nil)
 
 
 (defun org-agenda-mark-filtered-text ()
 (defun org-agenda-mark-filtered-text ()
   "Mark all text hidden by filtering with a text property."
   "Mark all text hidden by filtering with a text property."
@@ -2851,7 +2864,8 @@ higher priority settings."
 	 (put-text-property
 	 (put-text-property
 	  (overlay-start o) (overlay-end o)
 	  (overlay-start o) (overlay-end o)
 	  'org-filtered t)))
 	  'org-filtered t)))
-     org-agenda-filter-overlays)))
+     (append org-agenda-tag-filter-overlays
+	     org-agenda-cat-filter-overlays))))
 
 
 (defun org-agenda-unmark-filtered-text ()
 (defun org-agenda-unmark-filtered-text ()
   "Remove the filtering text property."
   "Remove the filtering text property."
@@ -3034,9 +3048,10 @@ removed from the entry content.  Currently only `planning' is allowed here."
 (defvar org-pre-agenda-window-conf nil)
 (defvar org-pre-agenda-window-conf nil)
 (defvar org-agenda-columns-active nil)
 (defvar org-agenda-columns-active nil)
 (defvar org-agenda-name nil)
 (defvar org-agenda-name nil)
-(defvar org-agenda-filter nil)
+(defvar org-agenda-tag-filter nil)
-(defvar org-agenda-filter-while-redo nil)
+(defvar org-agenda-category-filter nil)
-(defvar org-agenda-filter-preset nil
+(defvar org-agenda-tag-filter-while-redo nil)
+(defvar org-agenda-tag-filter-preset nil
   "A preset of the tags filter used for secondary agenda filtering.
   "A preset of the tags filter used for secondary agenda filtering.
 This must be a list of strings, each string must be a single tag preceded
 This must be a list of strings, each string must be a single tag preceded
 by \"+\" or \"-\".
 by \"+\" or \"-\".
@@ -3046,13 +3061,25 @@ the entire agenda view.  In a block agenda, it will not work reliably to
 define a filter for one of the individual blocks.  You need to set it in
 define a filter for one of the individual blocks.  You need to set it in
 the global options and expect it to be applied to the entire view.")
 the global options and expect it to be applied to the entire view.")
 
 
+(defvar org-agenda-category-filter-preset nil
+  "A preset of the categeory filter used for secondary agenda filtering.
+This must be a list of strings, each string must be a single category
+preceded by \"+\" or \"-\".
+This variable should not be set directly, but agenda custom commands can
+bind it in the options section.  The preset filter is a global property of
+the entire agenda view.  In a block agenda, it will not work reliably to
+define a filter for one of the individual blocks.  You need to set it in
+the global options and expect it to be applied to the entire view.")
+
 (defun org-prepare-agenda (&optional name)
 (defun org-prepare-agenda (&optional name)
   (setq org-todo-keywords-for-agenda nil)
   (setq org-todo-keywords-for-agenda nil)
   (setq org-done-keywords-for-agenda nil)
   (setq org-done-keywords-for-agenda nil)
   (setq org-drawers-for-agenda nil)
   (setq org-drawers-for-agenda nil)
   (unless org-agenda-persistent-filter
   (unless org-agenda-persistent-filter
-    (setq org-agenda-filter nil))
+    (setq org-agenda-tag-filter nil
-  (put 'org-agenda-filter :preset-filter org-agenda-filter-preset)
+          org-agenda-category-filter nil))
+  (put 'org-agenda-tag-filter :preset-filter org-agenda-tag-filter-preset)
+  (put 'org-agenda-category-filter :preset-filter org-agenda-category-filter-preset)
   (if org-agenda-multi
   (if org-agenda-multi
       (progn
       (progn
 	(setq buffer-read-only nil)
 	(setq buffer-read-only nil)
@@ -3131,8 +3158,10 @@ the global options and expect it to be applied to the entire view.")
 	  (org-habit-insert-consistency-graphs))
 	  (org-habit-insert-consistency-graphs))
       (run-hooks 'org-finalize-agenda-hook)
       (run-hooks 'org-finalize-agenda-hook)
       (setq org-agenda-type (org-get-at-bol 'org-agenda-type))
       (setq org-agenda-type (org-get-at-bol 'org-agenda-type))
-      (when (or org-agenda-filter (get 'org-agenda-filter :preset-filter))
+      (when (or org-agenda-tag-filter (get 'org-agenda-tag-filter :preset-filter))
-	(org-agenda-filter-apply org-agenda-filter))
+	(org-agenda-filter-apply org-agenda-tag-filter 'tag))
+      (when (or org-agenda-category-filter (get 'org-agenda-category-filter :preset-filter))
+	(org-agenda-filter-apply org-agenda-category-filter 'category))
       )))
       )))
 
 
 (defun org-agenda-mark-clocking-task ()
 (defun org-agenda-mark-clocking-task ()
@@ -3666,8 +3695,8 @@ given in `org-agenda-start-on-weekday'."
 	(setq p (plist-put p :tend clocktable-end))
 	(setq p (plist-put p :tend clocktable-end))
 	(setq p (plist-put p :scope 'agenda))
 	(setq p (plist-put p :scope 'agenda))
 	(when (and (eq org-agenda-clockreport-mode 'with-filter)
 	(when (and (eq org-agenda-clockreport-mode 'with-filter)
-		   (setq filter (or org-agenda-filter-while-redo
+		   (setq filter (or org-agenda-tag-filter-while-redo
-				    (get 'org-agenda-filter :preset-filter))))
+				    (get 'org-agenda-tag-filter :preset-filter))))
 	  (setq p (plist-put p :tags (mapconcat (lambda (x)
 	  (setq p (plist-put p :tags (mapconcat (lambda (x)
 						  (if (string-match "[<>=]" x)
 						  (if (string-match "[<>=]" x)
 						      ""
 						      ""
@@ -3911,7 +3940,7 @@ in `org-agenda-text-search-extra-files'."
 					org-agenda-restrict-end)
 					org-agenda-restrict-end)
 		    (widen))
 		    (widen))
 		  (goto-char (point-min))
 		  (goto-char (point-min))
-		  (unless (or (org-on-heading-p)
+		  (unless (or (org-at-heading-p)
 			      (outline-next-heading))
 			      (outline-next-heading))
 		    (throw 'nextfile t))
 		    (throw 'nextfile t))
 		  (goto-char (max (point-min) (1- (point))))
 		  (goto-char (max (point-min) (1- (point))))
@@ -6125,29 +6154,45 @@ in the agenda."
 When this is the global TODO list, a prefix argument will be interpreted."
 When this is the global TODO list, a prefix argument will be interpreted."
   (interactive)
   (interactive)
   (let* ((org-agenda-keep-modes t)
   (let* ((org-agenda-keep-modes t)
-	 (filter org-agenda-filter)
+	 (tag-filter org-agenda-tag-filter)
-	 (preset (get 'org-agenda-filter :preset-filter))
+	 (tag-preset (get 'org-agenda-tag-filter :preset-filter))
-	 (org-agenda-filter-while-redo (or filter preset))
+	 (cat-filter org-agenda-category-filter)
+	 (cat-preset (get 'org-agenda-category-filter :preset-filter))
+	 (org-agenda-tag-filter-while-redo (or tag-filter tag-preset))
 	 (cols org-agenda-columns-active)
 	 (cols org-agenda-columns-active)
 	 (line (org-current-line))
 	 (line (org-current-line))
 	 (window-line (- line (org-current-line (window-start))))
 	 (window-line (- line (org-current-line (window-start))))
 	 (lprops (get 'org-agenda-redo-command 'org-lprops)))
 	 (lprops (get 'org-agenda-redo-command 'org-lprops)))
-    (put 'org-agenda-filter :preset-filter nil)
+    (put 'org-agenda-tag-filter :preset-filter nil)
+    (put 'org-agenda-category-filter :preset-filter nil)
     (and cols (org-columns-quit))
     (and cols (org-columns-quit))
     (message "Rebuilding agenda buffer...")
     (message "Rebuilding agenda buffer...")
     (org-let lprops '(eval org-agenda-redo-command))
     (org-let lprops '(eval org-agenda-redo-command))
     (setq org-agenda-undo-list nil
     (setq org-agenda-undo-list nil
 	  org-agenda-pending-undo-list nil)
 	  org-agenda-pending-undo-list nil)
     (message "Rebuilding agenda buffer...done")
     (message "Rebuilding agenda buffer...done")
-    (put 'org-agenda-filter :preset-filter preset)
+    (put 'org-agenda-tag-filter :preset-filter tag-preset)
-    (and (or filter preset) (org-agenda-filter-apply filter))
+    (put 'org-agenda-category-filter :preset-filter cat-preset)
+    (and (or tag-filter tag-preset) (org-agenda-filter-apply tag-filter 'tag))
+    (and (or cat-filter cat-preset) (org-agenda-filter-apply cat-filter 'category))
     (and cols (org-called-interactively-p 'any) (org-agenda-columns))
     (and cols (org-called-interactively-p 'any) (org-agenda-columns))
     (org-goto-line line)
     (org-goto-line line)
     (recenter window-line)))
     (recenter window-line)))
 
 
-
 (defvar org-global-tags-completion-table nil)
 (defvar org-global-tags-completion-table nil)
 (defvar org-agenda-filter-form nil)
 (defvar org-agenda-filter-form nil)
+
+(defun org-agenda-filter-by-category (strip)
+  "Keep only those lines in the agenda buffer that have a specific category.
+The category is that of the current line."
+  (interactive "P")
+  (if org-agenda-filtered-by-category
+      (org-agenda-filter-show-all-cat)
+    (let ((cat (org-no-properties (get-text-property (point) 'org-category))))
+      (if cat (org-agenda-filter-apply
+	       (list (concat (if strip "-" "+") cat)) 'category)
+	(error "No category at point")))))
+
 (defun org-agenda-filter-by-tag (strip &optional char narrow)
 (defun org-agenda-filter-by-tag (strip &optional char narrow)
   "Keep only those lines in the agenda buffer that have a specific tag.
   "Keep only those lines in the agenda buffer that have a specific tag.
 The tag is selected with its fast selection letter, as configured.
 The tag is selected with its fast selection letter, as configured.
@@ -6171,7 +6216,7 @@ to switch to narrowing."
 	 (effort-op org-agenda-filter-effort-default-operator)
 	 (effort-op org-agenda-filter-effort-default-operator)
 	 (effort-prompt "")
 	 (effort-prompt "")
 	 (inhibit-read-only t)
 	 (inhibit-read-only t)
-	 (current org-agenda-filter)
+	 (current org-agenda-tag-filter)
 	 maybe-refresh a n tag)
 	 maybe-refresh a n tag)
     (unless char
     (unless char
       (message
       (message
@@ -6210,20 +6255,26 @@ to switch to narrowing."
 		   "Tag: " org-global-tags-completion-table))))
 		   "Tag: " org-global-tags-completion-table))))
     (cond
     (cond
      ((equal char ?\r)
      ((equal char ?\r)
-      (org-agenda-filter-by-tag-show-all)
+      (org-agenda-filter-show-all-tag)
       (when org-agenda-auto-exclude-function
       (when org-agenda-auto-exclude-function
-	(setq org-agenda-filter '())
+	(setq org-agenda-tag-filter '())
 	(dolist (tag (org-agenda-get-represented-tags))
 	(dolist (tag (org-agenda-get-represented-tags))
 	  (let ((modifier (funcall org-agenda-auto-exclude-function tag)))
 	  (let ((modifier (funcall org-agenda-auto-exclude-function tag)))
 	    (if modifier
 	    (if modifier
-		(push modifier org-agenda-filter))))
+		(push modifier org-agenda-tag-filter))))
-	(if (not (null org-agenda-filter))
+	(if (not (null org-agenda-tag-filter))
-	    (org-agenda-filter-apply org-agenda-filter)))
+	    (org-agenda-filter-apply org-agenda-tag-filter 'tag)))
       (setq maybe-refresh t))
       (setq maybe-refresh t))
      ((equal char ?/)
      ((equal char ?/)
-      (org-agenda-filter-by-tag-show-all)
+      (org-agenda-filter-show-all-tag)
-      (when (get 'org-agenda-filter :preset-filter)
+      (when (get 'org-agenda-tag-filter :preset-filter)
-	(org-agenda-filter-apply org-agenda-filter))
+	(org-agenda-filter-apply org-agenda-tag-filter 'tag))
+      (setq maybe-refresh t))
+     ((equal char ?. )
+      (setq org-agenda-tag-filter
+	    (mapcar (lambda(tag) (concat "+" tag))
+		    (org-get-at-bol 'tags)))
+      (org-agenda-filter-apply org-agenda-tag-filter 'tag)
       (setq maybe-refresh t))
       (setq maybe-refresh t))
      ((or (equal char ?\ )
      ((or (equal char ?\ )
 	  (setq a (rassoc char alist))
 	  (setq a (rassoc char alist))
@@ -6235,12 +6286,12 @@ to switch to narrowing."
 	       (setq tag "?eff")
 	       (setq tag "?eff")
 	       a (cons tag nil))
 	       a (cons tag nil))
 	  (and tag (setq a (cons tag nil))))
 	  (and tag (setq a (cons tag nil))))
-      (org-agenda-filter-by-tag-show-all)
+      (org-agenda-filter-show-all-tag)
       (setq tag (car a))
       (setq tag (car a))
-      (setq org-agenda-filter
+      (setq org-agenda-tag-filter
 	    (cons (concat (if strip "-" "+") tag)
 	    (cons (concat (if strip "-" "+") tag)
 		  (if narrow current nil)))
 		  (if narrow current nil)))
-      (org-agenda-filter-apply org-agenda-filter)
+      (org-agenda-filter-apply org-agenda-tag-filter 'tag)
       (setq maybe-refresh t))
       (setq maybe-refresh t))
      (t (error "Invalid tag selection character %c" char)))
      (t (error "Invalid tag selection character %c" char)))
     (when (and maybe-refresh
     (when (and maybe-refresh
@@ -6264,10 +6315,12 @@ to switch to narrowing."
   (org-agenda-filter-by-tag strip char 'refine))
   (org-agenda-filter-by-tag strip char 'refine))
 
 
 (defun org-agenda-filter-make-matcher ()
 (defun org-agenda-filter-make-matcher ()
-  "Create the form that tests a line for the agenda filter."
+  "Create the form that tests a line for agenda filter."
   (let (f f1)
   (let (f f1)
-    (dolist (x (append (get 'org-agenda-filter :preset-filter)
+    ;; first compute the tag-filter matcher
-		       org-agenda-filter))
+    (dolist (x (delete-dups
+		(append (get 'org-agenda-tag-filter
+			     :preset-filter) org-agenda-tag-filter)))
       (if (member x '("-" "+"))
       (if (member x '("-" "+"))
 	  (setq f1 (if (equal x "-") 'tags '(not tags)))
 	  (setq f1 (if (equal x "-") 'tags '(not tags)))
 	(if (string-match "[<=>?]" x)
 	(if (string-match "[<=>?]" x)
@@ -6276,6 +6329,12 @@ to switch to narrowing."
 	(if (equal (string-to-char x) ?-)
 	(if (equal (string-to-char x) ?-)
 	    (setq f1 (list 'not f1))))
 	    (setq f1 (list 'not f1))))
       (push f1 f))
       (push f1 f))
+    ;; then compute the category-filter matcher
+    (dolist (x (delete-dups
+		(append (get 'org-agenda-category-filter
+			     :preset-filter) org-agenda-category-filter)))
+      (setq f1 (list 'equal (substring x 1) 'cat))
+      (push f1 f))
     (cons 'and (nreverse f))))
     (cons 'and (nreverse f))))
 
 
 (defun org-agenda-filter-effort-form (e)
 (defun org-agenda-filter-effort-form (e)
@@ -6300,49 +6359,64 @@ If the line does not have an effort defined, return nil."
       (funcall op (or eff (if org-sort-agenda-noeffort-is-high 32767 0))
       (funcall op (or eff (if org-sort-agenda-noeffort-is-high 32767 0))
 	       value))))
 	       value))))
 
 
-(defun org-agenda-filter-apply (filter)
+(defvar org-agenda-filtered-by-category nil)
+(defun org-agenda-filter-apply (filter type)
   "Set FILTER as the new agenda filter and apply it."
   "Set FILTER as the new agenda filter and apply it."
   (let (tags)
   (let (tags)
-    (setq org-agenda-filter filter
+    (if (eq type 'tag)
-	  org-agenda-filter-form (org-agenda-filter-make-matcher))
+	(setq org-agenda-tag-filter filter)
+      (setq org-agenda-category-filter filter
+	    org-agenda-filtered-by-category t))
+    (setq org-agenda-filter-form (org-agenda-filter-make-matcher))
     (org-agenda-set-mode-name)
     (org-agenda-set-mode-name)
     (save-excursion
     (save-excursion
       (goto-char (point-min))
       (goto-char (point-min))
       (while (not (eobp))
       (while (not (eobp))
 	(if (org-get-at-bol 'org-marker)
 	(if (org-get-at-bol 'org-marker)
 	    (progn
 	    (progn
-	      (setq tags (org-get-at-bol 'tags)) ; used in eval
+	      (setq tags (org-get-at-bol 'tags) ; used in eval
+		    cat (get-text-property (point) 'org-category))
 	      (if (not (eval org-agenda-filter-form))
 	      (if (not (eval org-agenda-filter-form))
-		  (org-agenda-filter-by-tag-hide-line))
+		  (org-agenda-filter-hide-line type))
 	      (beginning-of-line 2))
 	      (beginning-of-line 2))
 	  (beginning-of-line 2))))
 	  (beginning-of-line 2))))
     (if (get-char-property (point) 'invisible)
     (if (get-char-property (point) 'invisible)
 	(org-agenda-previous-line))))
 	(org-agenda-previous-line))))
 
 
-(defun org-agenda-filter-by-tag-hide-line ()
+(defun org-agenda-filter-hide-line (type)
   (let (ov)
   (let (ov)
     (setq ov (make-overlay (max (point-min) (1- (point-at-bol)))
     (setq ov (make-overlay (max (point-min) (1- (point-at-bol)))
 			       (point-at-eol)))
 			       (point-at-eol)))
     (overlay-put ov 'invisible t)
     (overlay-put ov 'invisible t)
-    (overlay-put ov 'type 'tags-filter)
+    (overlay-put ov 'type type)
-    (push ov org-agenda-filter-overlays)))
+    (if (eq type 'tag)
+	(push ov org-agenda-tag-filter-overlays)
+      (push ov org-agenda-cat-filter-overlays))))
 
 
 (defun org-agenda-fix-tags-filter-overlays-at (&optional pos)
 (defun org-agenda-fix-tags-filter-overlays-at (&optional pos)
   (setq pos (or pos (point)))
   (setq pos (or pos (point)))
   (save-excursion
   (save-excursion
     (dolist (ov (overlays-at pos))
     (dolist (ov (overlays-at pos))
       (when (and (overlay-get ov 'invisible)
       (when (and (overlay-get ov 'invisible)
-		 (eq (overlay-get ov 'type) 'tags-filter))
+		 (eq (overlay-get ov 'type) 'tag))
 	(goto-char pos)
 	(goto-char pos)
 	(if (< (overlay-start ov) (point-at-eol))
 	(if (< (overlay-start ov) (point-at-eol))
 	    (move-overlay ov (point-at-eol)
 	    (move-overlay ov (point-at-eol)
 			      (overlay-end ov)))))))
 			      (overlay-end ov)))))))
 
 
-(defun org-agenda-filter-by-tag-show-all ()
+(defun org-agenda-filter-show-all-tag nil
-  (mapc 'delete-overlay org-agenda-filter-overlays)
+  (mapc 'delete-overlay org-agenda-tag-filter-overlays)
-  (setq org-agenda-filter-overlays nil)
+  (setq org-agenda-tag-filter-overlays nil
-  (setq org-agenda-filter nil)
+	org-agenda-tag-filter nil
-  (setq org-agenda-filter-form nil)
+	org-agenda-filter-form nil)
+  (org-agenda-set-mode-name))
+
+(defun org-agenda-filter-show-all-cat nil
+  (mapc 'delete-overlay org-agenda-cat-filter-overlays)
+  (setq org-agenda-cat-filter-overlays nil
+	org-agenda-filtered-by-category nil
+	org-agenda-category-filter nil
+	org-agenda-filter-form nil)
   (org-agenda-set-mode-name))
   (org-agenda-set-mode-name))
 
 
 (defun org-agenda-manipulate-query-add ()
 (defun org-agenda-manipulate-query-add ()
@@ -6757,16 +6831,29 @@ When called with a prefix argument, include all archive files as well."
 	       ((eq org-agenda-show-log 'clockcheck) " ClkCk")
 	       ((eq org-agenda-show-log 'clockcheck) " ClkCk")
 	       (org-agenda-show-log " Log")
 	       (org-agenda-show-log " Log")
 	       (t ""))
 	       (t ""))
-	      ;; show tags used for filtering in a custom face
+	      (if (or org-agenda-category-filter (get 'org-agenda-category-filter
-	      (if (or org-agenda-filter (get 'org-agenda-filter
+	      					      :preset-filter))
+	      	  '(:eval (org-propertize
+	      		   (concat " <"
+	      			   (mapconcat
+	      			    'identity
+	      			    (append
+	      			     (get 'org-agenda-category-filter :preset-filter)
+	      			     org-agenda-category-filter)
+	      			    "")
+	      			   ">")
+	      		   'face 'org-agenda-filter-category
+	      		   'help-echo "Category used in filtering"))
+	      	"")
+	      (if (or org-agenda-tag-filter (get 'org-agenda-tag-filter
 					     :preset-filter))
 					     :preset-filter))
 		  '(:eval (org-propertize
 		  '(:eval (org-propertize
 			   (concat " {"
 			   (concat " {"
 				   (mapconcat
 				   (mapconcat
 				    'identity
 				    'identity
 				    (append
 				    (append
-				     (get 'org-agenda-filter :preset-filter)
+				     (get 'org-agenda-tag-filter :preset-filter)
-				     org-agenda-filter)
+				     org-agenda-tag-filter)
 				    "")
 				    "")
 				   "}")
 				   "}")
 			   'face 'org-agenda-filter-tags
 			   'face 'org-agenda-filter-tags
@@ -7913,7 +8000,7 @@ the resulting entry will not be shown.  When TEXT is empty, switch to
      ((eq type 'anniversary)
      ((eq type 'anniversary)
       (or (re-search-forward "^*[ \t]+Anniversaries" nil t)
       (or (re-search-forward "^*[ \t]+Anniversaries" nil t)
 	(progn
 	(progn
-	  (or (org-on-heading-p t)
+	  (or (org-at-heading-p t)
 	      (progn
 	      (progn
 		(outline-next-heading)
 		(outline-next-heading)
 		(insert "* Anniversaries\n\n")
 		(insert "* Anniversaries\n\n")
@@ -8499,9 +8586,9 @@ details and examples."
     (org-prepare-agenda-buffers files)
     (org-prepare-agenda-buffers files)
     (while (setq file (pop files))
     (while (setq file (pop files))
       (setq entries
       (setq entries
-	    (delq nil 
+	    (delq nil
 		  (append entries
 		  (append entries
-			  (apply 'org-agenda-get-day-entries 
+			  (apply 'org-agenda-get-day-entries
 				 file today scope)))))
 				 file today scope)))))
     ;; Map thru entries and find if we should filter them out
     ;; Map thru entries and find if we should filter them out
     (mapc
     (mapc

+ 249 - 211
lisp/org-archive.el

@@ -190,158 +190,166 @@ If the cursor is not at a headline when this command is called, try all level
 1 trees.  If the cursor is on a headline, only try the direct children of
 1 trees.  If the cursor is on a headline, only try the direct children of
 this heading."
 this heading."
   (interactive "P")
   (interactive "P")
-  (if find-done
+  (if (and (org-region-active-p) org-loop-over-headlines-in-active-region)
-      (org-archive-all-done)
+      (let ((cl (if (eq org-loop-over-headlines-in-active-region 'start-level)
-    ;; Save all relevant TODO keyword-relatex variables
+		    'region-start-level 'region))
-
+	    org-loop-over-headlines-in-active-region)
-    (let ((tr-org-todo-line-regexp org-todo-line-regexp) ; keep despite compiler
+	(org-map-entries
-	  (tr-org-todo-keywords-1 org-todo-keywords-1)
+	 `(progn (setq org-map-continue-from (progn (org-back-to-heading) (point)))
-	  (tr-org-todo-kwd-alist org-todo-kwd-alist)
+		 (org-archive-subtree ,find-done))
-	  (tr-org-done-keywords org-done-keywords)
+	 org-loop-over-headlines-in-active-region
-	  (tr-org-todo-regexp org-todo-regexp)
+	 cl (if (outline-invisible-p) (org-end-of-subtree nil t))))
-	  (tr-org-todo-line-regexp org-todo-line-regexp)
+    (if find-done
-	  (tr-org-odd-levels-only org-odd-levels-only)
+	(org-archive-all-done)
-	  (this-buffer (current-buffer))
+      ;; Save all relevant TODO keyword-relatex variables
-	  ;; start of variables that will be used for saving context
+      (let ((tr-org-todo-line-regexp org-todo-line-regexp) ; keep despite compiler
-	  ;; The compiler complains about them - keep them anyway!
+	    (tr-org-todo-keywords-1 org-todo-keywords-1)
-	  (file (abbreviate-file-name
+	    (tr-org-todo-kwd-alist org-todo-kwd-alist)
-		 (or (buffer-file-name (buffer-base-buffer))
+	    (tr-org-done-keywords org-done-keywords)
-		     (error "No file associated to buffer"))))
+	    (tr-org-todo-regexp org-todo-regexp)
-	  (olpath (mapconcat 'identity (org-get-outline-path) "/"))
+	    (tr-org-todo-line-regexp org-todo-line-regexp)
-	  (time (format-time-string
+	    (tr-org-odd-levels-only org-odd-levels-only)
-		 (substring (cdr org-time-stamp-formats) 1 -1)
+	    (this-buffer (current-buffer))
-		 (current-time)))
+	    ;; start of variables that will be used for saving context
-	  category todo priority ltags itags atags
+	    ;; The compiler complains about them - keep them anyway!
-	  ;; end of variables that will be used for saving context
+	    (file (abbreviate-file-name
-	  location afile heading buffer level newfile-p infile-p visiting)
+		   (or (buffer-file-name (buffer-base-buffer))
-
+		       (error "No file associated to buffer"))))
-      ;; Find the local archive location
+	    (olpath (mapconcat 'identity (org-get-outline-path) "/"))
-      (setq location (org-get-local-archive-location)
+	    (time (format-time-string
-	    afile (org-extract-archive-file location)
+		   (substring (cdr org-time-stamp-formats) 1 -1)
-	    heading (org-extract-archive-heading location)
+		   (current-time)))
-	    infile-p (equal file (abbreviate-file-name afile)))
+	    category todo priority ltags itags atags
-      (unless afile
+	    ;; end of variables that will be used for saving context
-	(error "Invalid `org-archive-location'"))
+	    location afile heading buffer level newfile-p infile-p visiting)
-
+
-      (if (> (length afile) 0)
+	;; Find the local archive location
-	  (setq newfile-p (not (file-exists-p afile))
+	(setq location (org-get-local-archive-location)
-		visiting (find-buffer-visiting afile)
+	      afile (org-extract-archive-file location)
-		buffer (or visiting (find-file-noselect afile)))
+	      heading (org-extract-archive-heading location)
-	(setq buffer (current-buffer)))
+	      infile-p (equal file (abbreviate-file-name afile)))
-      (unless buffer
+	(unless afile
-	(error "Cannot access file \"%s\"" afile))
+	  (error "Invalid `org-archive-location'"))
-      (if (and (> (length heading) 0)
+
-	       (string-match "^\\*+" heading))
+	(if (> (length afile) 0)
-	  (setq level (match-end 0))
+	    (setq newfile-p (not (file-exists-p afile))
-	(setq heading nil level 0))
+		  visiting (find-buffer-visiting afile)
-      (save-excursion
+		  buffer (or visiting (find-file-noselect afile)))
-	(org-back-to-heading t)
+	  (setq buffer (current-buffer)))
-	;; Get context information that will be lost by moving the tree
+	(unless buffer
-	(setq category (org-get-category nil 'force-refresh)
+	  (error "Cannot access file \"%s\"" afile))
-	      todo (and (looking-at org-todo-line-regexp)
+	(if (and (> (length heading) 0)
-			(match-string 2))
+		 (string-match "^\\*+" heading))
-	      priority (org-get-priority
+	    (setq level (match-end 0))
-			(if (match-end 3) (match-string 3) ""))
+	  (setq heading nil level 0))
-	      ltags (org-get-tags)
+	(save-excursion
-	      itags (org-delete-all ltags (org-get-tags-at))
+	  (org-back-to-heading t)
-	      atags (org-get-tags-at))
+	  ;; Get context information that will be lost by moving the tree
-	(setq ltags (mapconcat 'identity ltags " ")
+	  (setq category (org-get-category nil 'force-refresh)
-	      itags (mapconcat 'identity itags " "))
+		todo (and (looking-at org-todo-line-regexp)
-	;; We first only copy, in case something goes wrong
+			  (match-string 2))
-	;; we need to protect `this-command', to avoid kill-region sets it,
+		priority (org-get-priority
-	;; which would lead to duplication of subtrees
+			  (if (match-end 3) (match-string 3) ""))
-	(let (this-command) (org-copy-subtree 1 nil t))
+		ltags (org-get-tags)
-	(set-buffer buffer)
+		itags (org-delete-all ltags (org-get-tags-at))
-	;; Enforce org-mode for the archive buffer
+		atags (org-get-tags-at))
-	(if (not (eq major-mode 'org-mode))
+	  (setq ltags (mapconcat 'identity ltags " ")
-	    ;; Force the mode for future visits.
+		itags (mapconcat 'identity itags " "))
-	    (let ((org-insert-mode-line-in-empty-file t)
+	  ;; We first only copy, in case something goes wrong
-		  (org-inhibit-startup t))
+	  ;; we need to protect `this-command', to avoid kill-region sets it,
-	      (call-interactively 'org-mode)))
+	  ;; which would lead to duplication of subtrees
-	(when newfile-p
+	  (let (this-command) (org-copy-subtree 1 nil t))
-	  (goto-char (point-max))
+	  (set-buffer buffer)
-	  (insert (format "\nArchived entries from file %s\n\n"
+	  ;; Enforce org-mode for the archive buffer
-			  (buffer-file-name this-buffer))))
+	  (if (not (eq major-mode 'org-mode))
-	;; Force the TODO keywords of the original buffer
+	      ;; Force the mode for future visits.
-	(let ((org-todo-line-regexp tr-org-todo-line-regexp)
+	      (let ((org-insert-mode-line-in-empty-file t)
-	      (org-todo-keywords-1 tr-org-todo-keywords-1)
+		    (org-inhibit-startup t))
-	      (org-todo-kwd-alist tr-org-todo-kwd-alist)
+		(call-interactively 'org-mode)))
-	      (org-done-keywords tr-org-done-keywords)
+	  (when newfile-p
-	      (org-todo-regexp tr-org-todo-regexp)
+	    (goto-char (point-max))
-	      (org-todo-line-regexp tr-org-todo-line-regexp)
+	    (insert (format "\nArchived entries from file %s\n\n"
-	      (org-odd-levels-only
+			    (buffer-file-name this-buffer))))
-	       (if (local-variable-p 'org-odd-levels-only (current-buffer))
+	  ;; Force the TODO keywords of the original buffer
-		   org-odd-levels-only
+	  (let ((org-todo-line-regexp tr-org-todo-line-regexp)
-		 tr-org-odd-levels-only)))
+		(org-todo-keywords-1 tr-org-todo-keywords-1)
-	  (goto-char (point-min))
+		(org-todo-kwd-alist tr-org-todo-kwd-alist)
-	  (show-all)
+		(org-done-keywords tr-org-done-keywords)
-	  (if heading
+		(org-todo-regexp tr-org-todo-regexp)
-	      (progn
+		(org-todo-line-regexp tr-org-todo-line-regexp)
-		(if (re-search-forward
+		(org-odd-levels-only
-		     (concat "^" (regexp-quote heading)
+		 (if (local-variable-p 'org-odd-levels-only (current-buffer))
-			     (org-re "[ \t]*\\(:[[:alnum:]_@#%:]+:\\)?[ \t]*\\($\\|\r\\)"))
+		     org-odd-levels-only
-		     nil t)
+		   tr-org-odd-levels-only)))
-		    (goto-char (match-end 0))
+	    (goto-char (point-min))
-		  ;; Heading not found, just insert it at the end
+	    (show-all)
-		  (goto-char (point-max))
+	    (if heading
-		  (or (bolp) (insert "\n"))
+		(progn
-		  (insert "\n" heading "\n")
+		  (if (re-search-forward
-		  (end-of-line 0))
+		       (concat "^" (regexp-quote heading)
-		;; Make the subtree visible
+			       (org-re "[ \t]*\\(:[[:alnum:]_@#%:]+:\\)?[ \t]*\\($\\|\r\\)"))
-		(show-subtree)
+		       nil t)
-		(if org-archive-reversed-order
+		      (goto-char (match-end 0))
-		    (progn
+		    ;; Heading not found, just insert it at the end
-		      (org-back-to-heading t)
+		    (goto-char (point-max))
-		      (outline-next-heading))
+		    (or (bolp) (insert "\n"))
-		  (org-end-of-subtree t))
+		    (insert "\n" heading "\n")
-		(skip-chars-backward " \t\r\n")
+		    (end-of-line 0))
-		(and (looking-at "[ \t\r\n]*")
+		  ;; Make the subtree visible
-		     (replace-match "\n\n")))
+		  (show-subtree)
-	    ;; No specific heading, just go to end of file.
+		  (if org-archive-reversed-order
-	    (goto-char (point-max)) (insert "\n"))
+		      (progn
-	  ;; Paste
+			(org-back-to-heading t)
-	  (org-paste-subtree (org-get-valid-level level (and heading 1)))
+			(outline-next-heading))
-	  ;; Shall we append inherited tags?
+		    (org-end-of-subtree t))
-	  (and itags
+		  (skip-chars-backward " \t\r\n")
-	       (or (and (eq org-archive-subtree-add-inherited-tags 'infile)
+		  (and (looking-at "[ \t\r\n]*")
-			infile-p)
+		       (replace-match "\n\n")))
-		   (eq org-archive-subtree-add-inherited-tags t))
+	      ;; No specific heading, just go to end of file.
-	       (org-set-tags-to atags))
+	      (goto-char (point-max)) (insert "\n"))
-	  ;; Mark the entry as done
+	    ;; Paste
-	  (when (and org-archive-mark-done
+	    (org-paste-subtree (org-get-valid-level level (and heading 1)))
-		     (looking-at org-todo-line-regexp)
+	    ;; Shall we append inherited tags?
-		     (or (not (match-end 2))
+	    (and itags
-			 (not (member (match-string 2) org-done-keywords))))
+		 (or (and (eq org-archive-subtree-add-inherited-tags 'infile)
-	    (let (org-log-done org-todo-log-states)
+			  infile-p)
-	      (org-todo
+		     (eq org-archive-subtree-add-inherited-tags t))
-	       (car (or (member org-archive-mark-done org-done-keywords)
+		 (org-set-tags-to atags))
-			org-done-keywords)))))
+	    ;; Mark the entry as done
-
+	    (when (and org-archive-mark-done
-	  ;; Add the context info
+		       (looking-at org-todo-line-regexp)
-	  (when org-archive-save-context-info
+		       (or (not (match-end 2))
-	    (let ((l org-archive-save-context-info) e n v)
+			   (not (member (match-string 2) org-done-keywords))))
-	      (while (setq e (pop l))
+	      (let (org-log-done org-todo-log-states)
-		(when (and (setq v (symbol-value e))
+		(org-todo
-			   (stringp v) (string-match "\\S-" v))
+		 (car (or (member org-archive-mark-done org-done-keywords)
-		  (setq n (concat "ARCHIVE_" (upcase (symbol-name e))))
+			  org-done-keywords)))))
-		  (org-entry-put (point) n v)))))
+
-
+	    ;; Add the context info
-	  ;; Save and kill the buffer, if it is not the same buffer.
+	    (when org-archive-save-context-info
-	  (when (not (eq this-buffer buffer))
+	      (let ((l org-archive-save-context-info) e n v)
-	    (save-buffer))))
+		(while (setq e (pop l))
-      ;; Here we are back in the original buffer.  Everything seems to have
+		  (when (and (setq v (symbol-value e))
-      ;; worked.  So now cut the tree and finish up.
+			     (stringp v) (string-match "\\S-" v))
-      (let (this-command) (org-cut-subtree))
+		    (setq n (concat "ARCHIVE_" (upcase (symbol-name e))))
-      (when (featurep 'org-inlinetask)
+		    (org-entry-put (point) n v)))))
-	(org-inlinetask-remove-END-maybe))
+
-      (setq org-markers-to-move nil)
+	    ;; Save and kill the buffer, if it is not the same buffer.
-      (message "Subtree archived %s"
+	    (when (not (eq this-buffer buffer))
-	       (if (eq this-buffer buffer)
+	      (save-buffer))))
-		   (concat "under heading: " heading)
+	;; Here we are back in the original buffer.  Everything seems to have
-		 (concat "in file: " (abbreviate-file-name afile))))))
+	;; worked.  So now cut the tree and finish up.
-  (org-reveal)
+	(let (this-command) (org-cut-subtree))
-  (if (looking-at "^[ \t]*$")
+	(when (featurep 'org-inlinetask)
-      (outline-next-visible-heading 1)))
+	  (org-inlinetask-remove-END-maybe))
+	(setq org-markers-to-move nil)
+	(message "Subtree archived %s"
+		 (if (eq this-buffer buffer)
+		     (concat "under heading: " heading)
+		   (concat "in file: " (abbreviate-file-name afile))))))
+    (org-reveal)
+    (if (looking-at "^[ \t]*$")
+	(outline-next-visible-heading 1))))
 
 
 (defun org-archive-to-archive-sibling ()
 (defun org-archive-to-archive-sibling ()
   "Archive the current heading by moving it under the archive sibling.
   "Archive the current heading by moving it under the archive sibling.
@@ -349,55 +357,69 @@ The archive sibling is a sibling of the heading with the heading name
 `org-archive-sibling-heading' and an `org-archive-tag' tag.  If this
 `org-archive-sibling-heading' and an `org-archive-tag' tag.  If this
 sibling does not exist, it will be created at the end of the subtree."
 sibling does not exist, it will be created at the end of the subtree."
   (interactive)
   (interactive)
-  (save-restriction
+  (if (and (org-region-active-p) org-loop-over-headlines-in-active-region)
-    (widen)
+      (let ((cl (when (eq org-loop-over-headlines-in-active-region 'start-level)
-    (let (b e pos leader level)
+		  'region-start-level 'region))
-      (org-back-to-heading t)
+	    org-loop-over-headlines-in-active-region)
-      (looking-at org-outline-regexp)
+	(org-map-entries
-      (setq leader (match-string 0)
+	 '(progn (setq org-map-continue-from
-	    level (funcall outline-level))
+		       (progn (org-back-to-heading)
-      (setq pos (point))
+			      (if (looking-at (concat "^.*:" org-archive-tag ":.*$"))
-      (condition-case nil
+			      	  (org-end-of-subtree t)
-	  (outline-up-heading 1 t)
+				(point))))
-	(error (setq e (point-max)) (goto-char (point-min))))
+		 (when (org-at-heading-p)
-      (setq b (point))
+		   (org-archive-to-archive-sibling)))
-      (unless e
+	 org-loop-over-headlines-in-active-region
+	 cl (if (outline-invisible-p) (org-end-of-subtree nil t))))
+    (save-restriction
+      (widen)
+      (let (b e pos leader level)
+	(org-back-to-heading t)
+	(looking-at org-outline-regexp)
+	(setq leader (match-string 0)
+	      level (funcall outline-level))
+	(setq pos (point))
 	(condition-case nil
 	(condition-case nil
-	    (org-end-of-subtree t t)
+	    (outline-up-heading 1 t)
-	  (error (goto-char (point-max))))
+	  (error (setq e (point-max)) (goto-char (point-min))))
-	(setq e (point)))
+	(setq b (point))
-      (goto-char b)
+	(unless e
-      (unless (re-search-forward
+	  (condition-case nil
-	       (concat "^" (regexp-quote leader)
+	      (org-end-of-subtree t t)
-		       "[ \t]*"
+	    (error (goto-char (point-max))))
-		       org-archive-sibling-heading
+	  (setq e (point)))
-		       "[ \t]*:"
+	(goto-char b)
-		       org-archive-tag ":") e t)
+	(unless (re-search-forward
-	(goto-char e)
+		 (concat "^" (regexp-quote leader)
-	(or (bolp) (newline))
+			 "[ \t]*"
-	(insert leader org-archive-sibling-heading "\n")
+			 org-archive-sibling-heading
-	(beginning-of-line 0)
+			 "[ \t]*:"
-	(org-toggle-tag org-archive-tag 'on))
+			 org-archive-tag ":") e t)
-      (beginning-of-line 1)
+	  (goto-char e)
-      (if org-archive-reversed-order
+	  (or (bolp) (newline))
-	  (outline-next-heading)
+	  (insert leader org-archive-sibling-heading "\n")
-	(org-end-of-subtree t t))
+	  (beginning-of-line 0)
-      (save-excursion
+	  (org-toggle-tag org-archive-tag 'on))
-	(goto-char pos)
+	(beginning-of-line 1)
-	(let ((this-command this-command)) (org-cut-subtree)))
+	(if org-archive-reversed-order
-      (org-paste-subtree (org-get-valid-level level 1))
+	    (outline-next-heading)
-      (org-set-property
+	  (org-end-of-subtree t t))
-       "ARCHIVE_TIME"
+	(save-excursion
-       (format-time-string
+	  (goto-char pos)
-	(substring (cdr org-time-stamp-formats) 1 -1)
+	  (let ((this-command this-command)) (org-cut-subtree)))
-	(current-time)))
+	(org-paste-subtree (org-get-valid-level level 1))
-      (outline-up-heading 1 t)
+	(org-set-property
-      (hide-subtree)
+	 "ARCHIVE_TIME"
-      (org-cycle-show-empty-lines 'folded)
+	 (format-time-string
-      (goto-char pos)))
+	  (substring (cdr org-time-stamp-formats) 1 -1)
-  (org-reveal)
+	  (current-time)))
-  (if (looking-at "^[ \t]*$")
+	(outline-up-heading 1 t)
-      (outline-next-visible-heading 1)))
+	(hide-subtree)
+	(org-cycle-show-empty-lines 'folded)
+	(goto-char pos)))
+    (org-reveal)
+    (if (looking-at "^[ \t]*$")
+	(outline-next-visible-heading 1))))
 
 
 (defun org-archive-all-done (&optional tag)
 (defun org-archive-all-done (&optional tag)
   "Archive sublevels of the current tree without open TODO items.
   "Archive sublevels of the current tree without open TODO items.
@@ -411,7 +433,7 @@ When TAG is non-nil, don't move trees, but mark them with the ARCHIVE tag."
 	(question (if tag "Set ARCHIVE tag (no open TODO items)? "
 	(question (if tag "Set ARCHIVE tag (no open TODO items)? "
 		    "Move subtree to archive (no open TODO items)? "))
 		    "Move subtree to archive (no open TODO items)? "))
 	beg end (cntarch 0))
 	beg end (cntarch 0))
-    (if (org-on-heading-p)
+    (if (org-at-heading-p)
 	(progn
 	(progn
 	  (setq re1 (concat "^" (regexp-quote
 	  (setq re1 (concat "^" (regexp-quote
 				 (make-string
 				 (make-string
@@ -448,20 +470,36 @@ When TAG is non-nil, don't move trees, but mark them with the ARCHIVE tag."
 With prefix ARG, check all children of current headline and offer tagging
 With prefix ARG, check all children of current headline and offer tagging
 the children that do not contain any open TODO items."
 the children that do not contain any open TODO items."
   (interactive "P")
   (interactive "P")
-  (if find-done
+  (if (and (org-region-active-p) org-loop-over-headlines-in-active-region)
-      (org-archive-all-done 'tag)
+      (let ((cl (if (eq org-loop-over-headlines-in-active-region 'start-level)
-    (let (set)
+		    'region-start-level 'region))
-      (save-excursion
+	    org-loop-over-headlines-in-active-region)
-	(org-back-to-heading t)
+	(org-map-entries
-	(setq set (org-toggle-tag org-archive-tag))
+	 `(org-toggle-archive-tag ,find-done)
-	(when set (hide-subtree)))
+	 org-loop-over-headlines-in-active-region
-      (and set (beginning-of-line 1))
+	 cl (if (outline-invisible-p) (org-end-of-subtree nil t))))
-      (message "Subtree %s" (if set "archived" "unarchived")))))
+    (if find-done
+	(org-archive-all-done 'tag)
+      (let (set)
+	(save-excursion
+	  (org-back-to-heading t)
+	  (setq set (org-toggle-tag org-archive-tag))
+	  (when set (hide-subtree)))
+	(and set (beginning-of-line 1))
+	(message "Subtree %s" (if set "archived" "unarchived"))))))
 
 
 (defun org-archive-set-tag ()
 (defun org-archive-set-tag ()
   "Set the ARCHIVE tag."
   "Set the ARCHIVE tag."
   (interactive)
   (interactive)
-  (org-toggle-tag org-archive-tag 'on))
+  (if (and (org-region-active-p) org-loop-over-headlines-in-active-region)
+      (let ((cl (if (eq org-loop-over-headlines-in-active-region 'start-level)
+		    'region-start-level 'region))
+	    org-loop-over-headlines-in-active-region)
+	(org-map-entries
+	 'org-archive-set-tag
+	 org-loop-over-headlines-in-active-region
+	 cl (if (outline-invisible-p) (org-end-of-subtree nil t))))
+    (org-toggle-tag org-archive-tag 'on)))
 
 
 ;;;###autoload
 ;;;###autoload
 (defun org-archive-subtree-default ()
 (defun org-archive-subtree-default ()

+ 1 - 1
lisp/org-beamer.el

@@ -399,7 +399,7 @@ the value will be inserted right after the documentclass statement."
       (insert org-beamer-header-extra)
       (insert org-beamer-header-extra)
       (or (bolp) (insert "\n"))))))
       (or (bolp) (insert "\n"))))))
 
 
-(defcustom org-beamer-fragile-re "^[ \t]*\\\\begin{\\(verbatim\\|lstlisting\\|minted\\)}"
+(defcustom org-beamer-fragile-re "\\\\\\(verb\\|lstinline\\)\\|^[ \t]*\\\\begin{\\(verbatim\\|lstlisting\\|minted\\)}"
   "If this regexp matches in a frame, the frame is marked as fragile."
   "If this regexp matches in a frame, the frame is marked as fragile."
   :group 'org-beamer
   :group 'org-beamer
   :type 'regexp)
   :type 'regexp)

+ 1 - 1
lisp/org-capture.el

@@ -1417,7 +1417,7 @@ The template may still contain \"%?\" for cursor positioning."
 		(or (equal (char-before) ?:) (insert ":"))
 		(or (equal (char-before) ?:) (insert ":"))
 		(insert ins)
 		(insert ins)
 		(or (equal (char-after) ?:) (insert ":"))
 		(or (equal (char-after) ?:) (insert ":"))
-		(and (org-on-heading-p) (org-set-tags nil 'align)))))
+		(and (org-at-heading-p) (org-set-tags nil 'align)))))
 	   ((equal char "C")
 	   ((equal char "C")
 	    (cond ((= (length clipboards) 1) (insert (car clipboards)))
 	    (cond ((= (length clipboards) 1) (insert (car clipboards)))
 		  ((> (length clipboards) 1)
 		  ((> (length clipboards) 1)

+ 1 - 1
lisp/org-clock.el

@@ -1066,7 +1066,7 @@ the clocking selection, associated with the letter `d'."
 
 
       ;; Clock in at which position?
       ;; Clock in at which position?
       (setq target-pos
       (setq target-pos
-	    (if (and (eobp) (not (org-on-heading-p)))
+	    (if (and (eobp) (not (org-at-heading-p)))
 		(point-at-bol 0)
 		(point-at-bol 0)
 	      (point)))
 	      (point)))
       (run-hooks 'org-clock-in-prepare-hook)
       (run-hooks 'org-clock-in-prepare-hook)

+ 2 - 2
lisp/org-colview-xemacs.el

@@ -707,7 +707,7 @@ Where possible, use the standard interface for changing this line."
       (beginning-of-line 1)
       (beginning-of-line 1)
       ;; `next-line' is needed here, because it skips invisible line.
       ;; `next-line' is needed here, because it skips invisible line.
       (condition-case nil (org-no-warnings (next-line 1)) (error nil))
       (condition-case nil (org-no-warnings (next-line 1)) (error nil))
-      (setq hidep (org-on-heading-p 1)))
+      (setq hidep (org-at-heading-p 1)))
     (eval form)
     (eval form)
     (and hidep (hide-entry))))
     (and hidep (hide-entry))))
 
 
@@ -1036,7 +1036,7 @@ display, or in the #+COLUMNS line of the current buffer."
 	      (replace-match (concat "#+COLUMNS: " fmt) t t))
 	      (replace-match (concat "#+COLUMNS: " fmt) t t))
 	    (unless (> cnt 0)
 	    (unless (> cnt 0)
 	      (goto-char (point-min))
 	      (goto-char (point-min))
-	      (or (org-on-heading-p t) (outline-next-heading))
+	      (or (org-at-heading-p t) (outline-next-heading))
 	      (let ((inhibit-read-only t))
 	      (let ((inhibit-read-only t))
 		(insert-before-markers "#+COLUMNS: " fmt "\n")))
 		(insert-before-markers "#+COLUMNS: " fmt "\n")))
 	    (org-set-local 'org-columns-default-format fmt))))))
 	    (org-set-local 'org-columns-default-format fmt))))))

+ 2 - 2
lisp/org-colview.el

@@ -547,7 +547,7 @@ Where possible, use the standard interface for changing this line."
       (beginning-of-line 1)
       (beginning-of-line 1)
       ;; `next-line' is needed here, because it skips invisible line.
       ;; `next-line' is needed here, because it skips invisible line.
       (condition-case nil (org-no-warnings (next-line 1)) (error nil))
       (condition-case nil (org-no-warnings (next-line 1)) (error nil))
-      (setq hidep (org-on-heading-p 1)))
+      (setq hidep (org-at-heading-p 1)))
     (eval form)
     (eval form)
     (and hidep (hide-entry))))
     (and hidep (hide-entry))))
 
 
@@ -875,7 +875,7 @@ display, or in the #+COLUMNS line of the current buffer."
 	      (replace-match (concat "#+COLUMNS: " fmt) t t))
 	      (replace-match (concat "#+COLUMNS: " fmt) t t))
 	    (unless (> cnt 0)
 	    (unless (> cnt 0)
 	      (goto-char (point-min))
 	      (goto-char (point-min))
-	      (or (org-on-heading-p t) (outline-next-heading))
+	      (or (org-at-heading-p t) (outline-next-heading))
 	      (let ((inhibit-read-only t))
 	      (let ((inhibit-read-only t))
 		(insert-before-markers "#+COLUMNS: " fmt "\n")))
 		(insert-before-markers "#+COLUMNS: " fmt "\n")))
 	    (org-set-local 'org-columns-default-format fmt))))))
 	    (org-set-local 'org-columns-default-format fmt))))))

+ 1 - 2
contrib/lisp/org-eshell.el → lisp/org-eshell.el

@@ -4,7 +4,7 @@
 ;; Author: Konrad Hinsen <konrad.hinsen AT fastmail.net>
 ;; Author: Konrad Hinsen <konrad.hinsen AT fastmail.net>
 ;; Version: 0.1
 ;; Version: 0.1
 ;;
 ;;
-;; This file is not part of GNU Emacs.
+;; This file is part of GNU Emacs.
 ;;
 ;;
 ;; Emacs is free software; you can redistribute it and/or modify
 ;; 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
@@ -58,7 +58,6 @@
       (org-store-link-props
       (org-store-link-props
        :link (org-make-link "eshell:" link)
        :link (org-make-link "eshell:" link)
        :description command))))
        :description command))))
-  
 
 
 (provide 'org-eshell)
 (provide 'org-eshell)
 
 

+ 18 - 4
lisp/org-exp.el

@@ -217,6 +217,11 @@ and in `org-clock-clocktable-language-setup'."
   :group 'org-export-general
   :group 'org-export-general
   :type 'string)
   :type 'string)
 
 
+(defcustom org-export-date-timestamp-format "%Y-%m-%d"
+  "Time string format for Org timestamps in the #+DATE option."
+  :group 'org-export-general
+  :type 'string)
+
 (defvar org-export-page-description ""
 (defvar org-export-page-description ""
   "The page description, for the XHTML meta tag.
   "The page description, for the XHTML meta tag.
 This is best set with the #+DESCRIPTION line in a file, it does not make
 This is best set with the #+DESCRIPTION line in a file, it does not make
@@ -726,6 +731,7 @@ must accept the property list as an argument, and must return the (possibly
 modified) list.")
 modified) list.")
 
 
 ;; FIXME: should we fold case here?
 ;; FIXME: should we fold case here?
+
 (defun org-infile-export-plist ()
 (defun org-infile-export-plist ()
   "Return the property list with file-local settings for export."
   "Return the property list with file-local settings for export."
   (save-excursion
   (save-excursion
@@ -759,7 +765,15 @@ modified) list.")
 	   ((string-equal key "TITLE") (setq p (plist-put p :title val)))
 	   ((string-equal key "TITLE") (setq p (plist-put p :title val)))
 	   ((string-equal key "AUTHOR")(setq p (plist-put p :author val)))
 	   ((string-equal key "AUTHOR")(setq p (plist-put p :author val)))
 	   ((string-equal key "EMAIL") (setq p (plist-put p :email val)))
 	   ((string-equal key "EMAIL") (setq p (plist-put p :email val)))
-	   ((string-equal key "DATE") (setq p (plist-put p :date val)))
+	   ((string-equal key "DATE")
+	    ;; If date is an Org timestamp, convert it to a time
+	    ;; string using `org-export-date-timestamp-format'
+	    (when (string-match org-ts-regexp3 val)
+	      (setq val (format-time-string
+			 org-export-date-timestamp-format
+			 (apply 'encode-time (org-parse-time-string
+					      (match-string 0 val))))))
+	    (setq p (plist-put p :date val)))
 	   ((string-equal key "KEYWORDS") (setq p (plist-put p :keywords val)))
 	   ((string-equal key "KEYWORDS") (setq p (plist-put p :keywords val)))
 	   ((string-equal key "DESCRIPTION")
 	   ((string-equal key "DESCRIPTION")
 	    (setq p (plist-put p :description val)))
 	    (setq p (plist-put p :description val)))
@@ -1416,7 +1430,7 @@ the current file."
 		   (setq found (condition-case nil (org-link-search link)
 		   (setq found (condition-case nil (org-link-search link)
 				 (error nil)))
 				 (error nil)))
 		   (when (and found
 		   (when (and found
-			      (or (org-on-heading-p)
+			      (or (org-at-heading-p)
 				  (not (eq found 'dedicated))))
 				  (not (eq found 'dedicated))))
 		     (or (get-text-property (point) 'target)
 		     (or (get-text-property (point) 'target)
 			 (get-text-property
 			 (get-text-property
@@ -1527,7 +1541,7 @@ removed as well."
       (setq beg (point))
       (setq beg (point))
       (put-text-property beg (point-max) :org-delete t)
       (put-text-property beg (point-max) :org-delete t)
       (while (re-search-forward re-sel nil t)
       (while (re-search-forward re-sel nil t)
-	(when (org-on-heading-p)
+	(when (org-at-heading-p)
 	  (org-back-to-heading)
 	  (org-back-to-heading)
 	  (remove-text-properties
 	  (remove-text-properties
 	   (max (1- (point)) (point-min))
 	   (max (1- (point)) (point-min))
@@ -1597,7 +1611,7 @@ from the buffer."
     (when (not (eq export-archived-trees t))
     (when (not (eq export-archived-trees t))
       (goto-char (point-min))
       (goto-char (point-min))
       (while (re-search-forward re-archive nil t)
       (while (re-search-forward re-archive nil t)
-	(if (not (org-on-heading-p t))
+	(if (not (org-at-heading-p t))
 	    (goto-char (point-at-eol))
 	    (goto-char (point-at-eol))
 	  (beginning-of-line 1)
 	  (beginning-of-line 1)
 	  (setq a (if export-archived-trees
 	  (setq a (if export-archived-trees

+ 6 - 0
lisp/org-faces.el

@@ -678,6 +678,12 @@ month and 365.24 days for a year)."
   "Face for tag(s) in the mode-line when filtering the agenda."
   "Face for tag(s) in the mode-line when filtering the agenda."
   :group 'org-faces)
   :group 'org-faces)
 
 
+(defface org-agenda-filter-category
+  (org-compatible-face 'modeline
+    nil)
+  "Face for tag(s) in the mode-line when filtering the agenda."
+  :group 'org-faces)
+
 (defface org-time-grid ;; originally copied from font-lock-variable-name-face
 (defface org-time-grid ;; originally copied from font-lock-variable-name-face
   (org-compatible-face nil
   (org-compatible-face nil
     '((((class color) (min-colors 16) (background light)) (:foreground "DarkGoldenrod"))
     '((((class color) (min-colors 16) (background light)) (:foreground "DarkGoldenrod"))

+ 1 - 1
lisp/org-latex.el

@@ -2361,7 +2361,7 @@ The conversion is made depending of STRING-BEFORE and STRING-AFTER."
 					  (let ((next (org-footnote-get-next-reference)))
 					  (let ((next (org-footnote-get-next-reference)))
 					    (and next (= (nth 1 next) (nth 2 ref)))))
 					    (and next (= (nth 1 next) (nth 2 ref)))))
 			  org-export-latex-footnote-separator ""))))
 			  org-export-latex-footnote-separator ""))))
-	    (when (org-on-heading-p)
+	    (when (org-at-heading-p)
 	      (setq fnote (concat (org-export-latex-protect-string "\\protect")
 	      (setq fnote (concat (org-export-latex-protect-string "\\protect")
 				  fnote)))
 				  fnote)))
 	    ;; Ensure a footnote at column 0 cannot end a list
 	    ;; Ensure a footnote at column 0 cannot end a list

+ 5 - 5
lisp/org-list.el

@@ -113,7 +113,7 @@
 (declare-function org-inlinetask-outline-regexp "org-inlinetask" ())
 (declare-function org-inlinetask-outline-regexp "org-inlinetask" ())
 (declare-function org-level-increment "org" ())
 (declare-function org-level-increment "org" ())
 (declare-function org-narrow-to-subtree "org" ())
 (declare-function org-narrow-to-subtree "org" ())
-(declare-function org-on-heading-p "org" (&optional invisible-ok))
+(declare-function org-at-heading-p "org" (&optional invisible-ok))
 (declare-function org-previous-line-empty-p "org" ())
 (declare-function org-previous-line-empty-p "org" ())
 (declare-function org-remove-if "org" (predicate seq))
 (declare-function org-remove-if "org" (predicate seq))
 (declare-function org-reduced-level "org" (L))
 (declare-function org-reduced-level "org" (L))
@@ -2288,7 +2288,7 @@ in subtree, ignoring drawers."
 		    (setq lim-up (point-at-bol))
 		    (setq lim-up (point-at-bol))
 		  (error "No item in region"))
 		  (error "No item in region"))
 		(setq lim-down (copy-marker limit))))
 		(setq lim-down (copy-marker limit))))
-	     ((org-on-heading-p)
+	     ((org-at-heading-p)
 	      ;; On an heading, start at first item after drawers and
 	      ;; On an heading, start at first item after drawers and
 	      ;; time-stamps (scheduled, etc.).
 	      ;; time-stamps (scheduled, etc.).
 	      (let ((limit (save-excursion (outline-next-heading) (point))))
 	      (let ((limit (save-excursion (outline-next-heading) (point))))
@@ -2447,7 +2447,7 @@ With optional prefix argument ALL, do this for the whole buffer."
 	      (cond			; boxes count
 	      (cond			; boxes count
 	       ;; Cookie is at an heading, but specifically for todo,
 	       ;; Cookie is at an heading, but specifically for todo,
 	       ;; not for checkboxes: skip it.
 	       ;; not for checkboxes: skip it.
-	       ((and (org-on-heading-p)
+	       ((and (org-at-heading-p)
 		     (string-match "\\<todo\\>"
 		     (string-match "\\<todo\\>"
 				   (downcase
 				   (downcase
 				    (or (org-entry-get nil "COOKIE_DATA") ""))))
 				    (or (org-entry-get nil "COOKIE_DATA") ""))))
@@ -2456,14 +2456,14 @@ With optional prefix argument ALL, do this for the whole buffer."
 	       ;; heading already have been read.  Use data collected
 	       ;; heading already have been read.  Use data collected
 	       ;; in STRUCTS-BAK.  This should only happen when
 	       ;; in STRUCTS-BAK.  This should only happen when
 	       ;; heading has more than one cookie on it.
 	       ;; heading has more than one cookie on it.
-	       ((and (org-on-heading-p)
+	       ((and (org-at-heading-p)
 		     (<= (save-excursion (outline-next-heading) (point))
 		     (<= (save-excursion (outline-next-heading) (point))
 			 backup-end))
 			 backup-end))
 		(funcall count-boxes nil structs-bak recursivep))
 		(funcall count-boxes nil structs-bak recursivep))
 	       ;; Cookie is at a fresh heading.  Grab structure of
 	       ;; Cookie is at a fresh heading.  Grab structure of
 	       ;; every list containing a checkbox between point and
 	       ;; every list containing a checkbox between point and
 	       ;; next headline, and save them in STRUCTS-BAK.
 	       ;; next headline, and save them in STRUCTS-BAK.
-	       ((org-on-heading-p)
+	       ((org-at-heading-p)
 		(setq backup-end (save-excursion
 		(setq backup-end (save-excursion
 				   (outline-next-heading) (point))
 				   (outline-next-heading) (point))
 		      structs-bak nil)
 		      structs-bak nil)

+ 169 - 77
lisp/org-odt.el

@@ -72,50 +72,54 @@
     ("\\.\\.\\." . "&#x2026;"))		; hellip
     ("\\.\\.\\." . "&#x2026;"))		; hellip
   "Regular expressions for special string conversion.")
   "Regular expressions for special string conversion.")
 
 
-(defconst org-odt-lib-dir (file-name-directory load-file-name))
+(defconst org-odt-lib-dir (file-name-directory load-file-name)
-(defconst org-odt-styles-dir
+  "Location of ODT exporter.
-  (let* ((styles-dir1 (expand-file-name "../etc/styles/" org-odt-lib-dir)) ; git
+Use this to infer values of `org-odt-styles-dir' and
-	 (styles-dir2 (expand-file-name "./etc/styles/" org-odt-lib-dir)) ; elpa
+`org-export-odt-schema-dir'.")
-	 (styles-dir3 (expand-file-name "./etc/org/" data-directory)) ; system
+
-	 (styles-dir
+(defvar org-odt-data-dir nil
-	  (catch 'styles-dir
+  "Data directory for ODT exporter.
-	    (mapc (lambda (styles-dir)
+Use this to infer values of `org-odt-styles-dir' and
-		    (when (and (file-readable-p
+`org-export-odt-schema-dir'.")
-				(expand-file-name
+
-				 "OrgOdtContentTemplate.xml" styles-dir))
+(defconst org-odt-schema-dir-list
-			       (file-readable-p
+  (list
-				(expand-file-name
+   (and org-odt-data-dir
-				 "OrgOdtStyles.xml" styles-dir)))
+	(expand-file-name "./schema/" org-odt-data-dir)) ; bail out
-		      (throw 'styles-dir styles-dir)))
+   (eval-when-compile
-		  (list styles-dir1 styles-dir2 styles-dir3))
+     (and (boundp 'org-odt-data-dir) org-odt-data-dir ; see make install
-	    nil)))
+	  (expand-file-name "./schema/" org-odt-data-dir)))
-    (unless styles-dir
+   (expand-file-name "../contrib/odt/etc/schema/" org-odt-lib-dir) ; git
-      (error "Cannot find factory styles file. Check package dir layout"))
+   )
-    styles-dir)
+  "List of directories to search for OpenDocument schema files.
-  "Directory that holds auxiliary XML files used by the ODT exporter.
+Use this list to set the default value of
-
+`org-export-odt-schema-dir'.  The entries in this list are
-This directory contains the following XML files -
+populated heuristically based on the values of `org-odt-lib-dir'
- \"OrgOdtStyles.xml\" and \"OrgOdtContentTemplate.xml\".  These
+and `org-odt-data-dir'.")
- XML files are used as the default values of
- `org-export-odt-styles-file' and
- `org-export-odt-content-template-file'.
-
-The default value of this variable varies depending on the
-version of org in use.  Note that the user could be using org
-from one of: org's own private git repository, GNU ELPA tar or
-standard Emacs.")
 
 
 (defcustom org-export-odt-schema-dir
 (defcustom org-export-odt-schema-dir
-  (let ((schema-dir (expand-file-name
+  (let* ((schema-dir
-		     "../contrib/odt/etc/schema/" org-odt-lib-dir)))
+	  (catch 'schema-dir
-    (if (and (file-readable-p
+	    (message "Debug (org-odt): Searching for OpenDocument schema files...")
-	      (expand-file-name "od-manifest-schema-v1.2-cs01.rnc" schema-dir))
+	    (mapc
-	     (file-readable-p
+	     (lambda (schema-dir)
-	      (expand-file-name "od-schema-v1.2-cs01.rnc" schema-dir))
+	       (when schema-dir
-	     (file-readable-p
+		 (message "Debug (org-odt): Trying %s..." schema-dir)
-	      (expand-file-name "schemas.xml" schema-dir)))
+		 (when (and (file-readable-p
-	schema-dir
+			     (expand-file-name "od-manifest-schema-v1.2-cs01.rnc"
-      (prog1 nil (message "Unable to locate OpenDocument schema files."))))
+					       schema-dir))
+			    (file-readable-p
+			     (expand-file-name "od-schema-v1.2-cs01.rnc"
+					       schema-dir))
+			    (file-readable-p
+			     (expand-file-name "schemas.xml" schema-dir)))
+		   (message "Debug (org-odt): Using schema files under %s"
+			    schema-dir)
+		   (throw 'schema-dir schema-dir))))
+	     org-odt-schema-dir-list)
+	    (message "Debug (org-odt): No OpenDocument schema files installed")
+	    nil)))
+    schema-dir)
   "Directory that contains OpenDocument schema files.
   "Directory that contains OpenDocument schema files.
 
 
 This directory contains:
 This directory contains:
@@ -129,9 +133,10 @@ of OpenDocument XML takes place based on the value
 `rng-nxml-auto-validate-flag'.
 `rng-nxml-auto-validate-flag'.
 
 
 The default value of this variable varies depending on the
 The default value of this variable varies depending on the
-version of org in use.  The OASIS schema files are available only
+version of org in use and is initialized from
-in the org's private git repository.  It is *not* bundled with
+`org-odt-schema-dir-list'.  The OASIS schema files are available
-GNU ELPA tar or standard Emacs distribution."
+only in the org's private git repository.  It is *not* bundled
+with GNU ELPA tar or standard Emacs distribution."
   :type '(choice
   :type '(choice
 	  (const :tag "Not set" nil)
 	  (const :tag "Not set" nil)
 	  (directory :tag "Schema directory"))
 	  (directory :tag "Schema directory"))
@@ -150,14 +155,67 @@ Also add it to `rng-schema-locating-files'."
 		(file-readable-p
 		(file-readable-p
 		 (expand-file-name "schemas.xml" schema-dir)))
 		 (expand-file-name "schemas.xml" schema-dir)))
 	       schema-dir
 	       schema-dir
-	     (prog1 nil
+	     (when value
-	       (message "Warning (org-odt): Unable to locate OpenDocument schema files.")))))
+	       (message "Error (org-odt): %s has no OpenDocument schema files"
+			value))
+	     nil)))
     (when org-export-odt-schema-dir
     (when org-export-odt-schema-dir
       (eval-after-load 'rng-loc
       (eval-after-load 'rng-loc
 	'(add-to-list 'rng-schema-locating-files
 	'(add-to-list 'rng-schema-locating-files
 		      (expand-file-name "schemas.xml"
 		      (expand-file-name "schemas.xml"
 					org-export-odt-schema-dir))))))
 					org-export-odt-schema-dir))))))
 
 
+(defconst org-odt-styles-dir-list
+  (list
+   (and org-odt-data-dir
+	(expand-file-name "./styles/" org-odt-data-dir)) ; bail out
+   (eval-when-compile
+     (and (boundp 'org-odt-data-dir) org-odt-data-dir ; see make install
+	  (expand-file-name "./styles/" org-odt-data-dir)))
+   (expand-file-name "../etc/styles/" org-odt-lib-dir) ; git
+   (expand-file-name "./etc/styles/" org-odt-lib-dir)  ; elpa
+   (expand-file-name "./org/" data-directory)	       ; system
+   )
+  "List of directories to search for OpenDocument styles files.
+See `org-odt-styles-dir'.  The entries in this list are populated
+heuristically based on the values of `org-odt-lib-dir' and
+`org-odt-data-dir'.")
+
+(defconst org-odt-styles-dir
+  (let* ((styles-dir
+	  (catch 'styles-dir
+	    (message "Debug (org-odt): Searching for OpenDocument styles files...")
+	    (mapc (lambda (styles-dir)
+		    (when styles-dir
+		      (message "Debug (org-odt): Trying %s..." styles-dir)
+		      (when (and (file-readable-p
+				  (expand-file-name
+				   "OrgOdtContentTemplate.xml" styles-dir))
+				 (file-readable-p
+				  (expand-file-name
+				   "OrgOdtStyles.xml" styles-dir)))
+			(message "Debug (org-odt): Using styles under %s"
+				 styles-dir)
+			(throw 'styles-dir styles-dir))))
+		  org-odt-styles-dir-list)
+	    nil)))
+    (unless styles-dir
+      (error "Error (org-odt): Cannot find factory styles files. Aborting."))
+    styles-dir)
+  "Directory that holds auxiliary XML files used by the ODT exporter.
+
+This directory contains the following XML files -
+ \"OrgOdtStyles.xml\" and \"OrgOdtContentTemplate.xml\".  These
+ XML files are used as the default values of
+ `org-export-odt-styles-file' and
+ `org-export-odt-content-template-file'.
+
+The default value of this variable varies depending on the
+version of org in use and is initialized from
+`org-odt-styles-dir-list'.  Note that the user could be using org
+from one of: org's own private git repository, GNU ELPA tar or
+standard Emacs.")
+
 (defvar org-odt-file-extensions
 (defvar org-odt-file-extensions
   '(("odt" . "OpenDocument Text")
   '(("odt" . "OpenDocument Text")
     ("ott" . "OpenDocument Text Template")
     ("ott" . "OpenDocument Text Template")
@@ -1383,7 +1441,7 @@ value of `org-export-odt-fontify-srcblocks."
 	(org-lparse-insert-list-table
 	(org-lparse-insert-list-table
 	 `((,(org-odt-format-entity
 	 `((,(org-odt-format-entity
 	      (if caption "CaptionedDisplayFormula" "DisplayFormula")
 	      (if caption "CaptionedDisplayFormula" "DisplayFormula")
-	      href width height caption nil)
+	      href width height :caption caption :label nil)
 	    ,(if (not label) ""
 	    ,(if (not label) ""
 	       (org-odt-format-entity-caption label nil "__MathFormula__"))))
 	       (org-odt-format-entity-caption label nil "__MathFormula__"))))
 	 nil nil nil "OrgEquation" nil '((1 "c" 8) (2 "c" 1)))
 	 nil nil nil "OrgEquation" nil '((1 "c" 8) (2 "c" 1)))
@@ -1585,7 +1643,7 @@ ATTR is a string of other attributes of the a element."
    (expand-file-name
    (expand-file-name
     (concat (sha1 file-name) "." (file-name-extension file-name)) "Pictures")))
     (concat (sha1 file-name) "." (file-name-extension file-name)) "Pictures")))
 
 
-(defun org-export-odt-format-image (src href &optional embed-as)
+(defun org-export-odt-format-image (src href)
   "Create image tag with source and attributes."
   "Create image tag with source and attributes."
   (save-match-data
   (save-match-data
     (let* ((caption (org-find-text-property-in-string 'org-caption src))
     (let* ((caption (org-find-text-property-in-string 'org-caption src))
@@ -1593,14 +1651,27 @@ ATTR is a string of other attributes of the a element."
 	   (attr (org-find-text-property-in-string 'org-attributes src))
 	   (attr (org-find-text-property-in-string 'org-attributes src))
 	   (label (org-find-text-property-in-string 'org-label src))
 	   (label (org-find-text-property-in-string 'org-label src))
 	   (latex-frag (org-find-text-property-in-string
 	   (latex-frag (org-find-text-property-in-string
-			      'org-latex-src src))
+			'org-latex-src src))
 	   (category (and latex-frag "__DvipngImage__"))
 	   (category (and latex-frag "__DvipngImage__"))
-	   (embed-as (or embed-as
-			 (if latex-frag
-			     (or (org-find-text-property-in-string
-				  'org-latex-src-embed-type src) 'character)
-			   'paragraph)))
 	   (attr-plist (org-lparse-get-block-params attr))
 	   (attr-plist (org-lparse-get-block-params attr))
+	   (user-frame-anchor
+	    (car (assoc-string (plist-get attr-plist :anchor)
+			       (if (or caption label)
+				   '(("paragraph") ("page"))
+				 '(("character") ("paragraph") ("page"))) t)))
+	   (user-frame-style
+	    (and user-frame-anchor (plist-get attr-plist :style)))
+	   (user-frame-attrs
+	    (and user-frame-anchor (plist-get attr-plist :attributes)))
+	   (user-frame-params
+	    (list user-frame-style user-frame-attrs user-frame-anchor))
+	   (embed-as (cond
+		      (latex-frag
+		       (symbol-name
+			(or (org-find-text-property-in-string
+			     'org-latex-src-embed-type src) 'character)))
+		      (user-frame-anchor)
+		      (t "paragraph")))
 	   (size (org-odt-image-size-from-file
 	   (size (org-odt-image-size-from-file
 		  src (plist-get attr-plist :width)
 		  src (plist-get attr-plist :width)
 		  (plist-get attr-plist :height)
 		  (plist-get attr-plist :height)
@@ -1609,15 +1680,12 @@ ATTR is a string of other attributes of the a element."
       (when latex-frag
       (when latex-frag
 	(setq href (org-propertize href :title "LaTeX Fragment"
 	(setq href (org-propertize href :title "LaTeX Fragment"
 				   :description latex-frag)))
 				   :description latex-frag)))
-      (cond
+      (let ((frame-style-handle (concat (and (or caption label) "Captioned")
-       ((not (or caption label))
+					embed-as "Image")))
-	(case embed-as
-	  (paragraph (org-odt-format-entity "DisplayImage" href width height))
-	  (character (org-odt-format-entity "InlineImage" href width height))
-	  (t (error "Unknown value for embed-as %S" embed-as))))
-       (t
 	(org-odt-format-entity
 	(org-odt-format-entity
-	 "CaptionedDisplayImage" href width height caption label category))))))
+	 frame-style-handle href width height
+	 :caption caption :label label :category category
+	 :user-frame-params user-frame-params)))))
 
 
 (defun org-odt-format-object-description (title description)
 (defun org-odt-format-object-description (title description)
   (concat (and title (org-odt-format-tags
   (concat (and title (org-odt-format-tags
@@ -1663,31 +1731,55 @@ ATTR is a string of other attributes of the a element."
 		content) nil nil "OrgInlineTaskFrame" " style:rel-width=\"100%\"")))
 		content) nil nil "OrgInlineTaskFrame" " style:rel-width=\"100%\"")))
 
 
 (defvar org-odt-entity-frame-styles
 (defvar org-odt-entity-frame-styles
-  '(("InlineImage" "__Figure__" ("OrgInlineImage" nil "as-char"))
+  '(("CharacterImage" "__Figure__" ("OrgInlineImage" nil "as-char"))
-    ("DisplayImage" "__Figure__" ("OrgDisplayImage" nil "paragraph"))
+    ("ParagraphImage" "__Figure__" ("OrgDisplayImage" nil "paragraph"))
-    ("CaptionedDisplayImage" "__Figure__"
+    ("PageImage" "__Figure__" ("OrgPageImage" nil "page"))
+    ("CaptionedParagraphImage" "__Figure__"
+     ("OrgCaptionedImage"
+      " style:rel-width=\"100%\" style:rel-height=\"scale\"" "paragraph")
+     ("OrgImageCaptionFrame" nil "paragraph"))
+    ("CaptionedPageImage" "__Figure__"
      ("OrgCaptionedImage"
      ("OrgCaptionedImage"
       " style:rel-width=\"100%\" style:rel-height=\"scale\"" "paragraph")
       " style:rel-width=\"100%\" style:rel-height=\"scale\"" "paragraph")
-     ("OrgImageCaptionFrame"))
+     ("OrgPageImageCaptionFrame" nil "page"))
     ("InlineFormula" "__MathFormula__" ("OrgInlineFormula" nil "as-char"))
     ("InlineFormula" "__MathFormula__" ("OrgInlineFormula" nil "as-char"))
     ("DisplayFormula" "__MathFormula__" ("OrgDisplayFormula" nil "as-char"))
     ("DisplayFormula" "__MathFormula__" ("OrgDisplayFormula" nil "as-char"))
     ("CaptionedDisplayFormula" "__MathFormula__"
     ("CaptionedDisplayFormula" "__MathFormula__"
      ("OrgCaptionedFormula" nil "paragraph")
      ("OrgCaptionedFormula" nil "paragraph")
      ("OrgFormulaCaptionFrame" nil "as-char"))))
      ("OrgFormulaCaptionFrame" nil "as-char"))))
 
 
-(defun org-odt-format-entity (entity href width height
+(defun org-odt-merge-frame-params(default-frame-params user-frame-params)
-				     &optional caption label category)
+  (if (not user-frame-params) default-frame-params
-  (let* ((entity-style (assoc entity org-odt-entity-frame-styles))
+    (assert (= (length default-frame-params) 3))
-	 (entity-frame (apply 'org-odt-format-frame
+    (assert (= (length user-frame-params) 3))
-			      href width height (nth 2 entity-style))))
+    (loop for user-frame-param in user-frame-params
-    (if (not (or caption label)) entity-frame
+	  for default-frame-param in default-frame-params
+	  collect (or user-frame-param default-frame-param))))
+
+(defun* org-odt-format-entity (entity href width height
+				      &key caption label category
+				      user-frame-params)
+  (let* ((entity-style (assoc-string entity org-odt-entity-frame-styles t))
+	 default-frame-params frame-params)
+    (cond
+     ((not (or caption label))
+      (setq default-frame-params (nth 2 entity-style))
+      (setq frame-params (org-odt-merge-frame-params
+			  default-frame-params user-frame-params))
+      (apply 'org-odt-format-frame href width height frame-params))
+     (t
+      (setq default-frame-params (nth 3 entity-style))
+      (setq frame-params (org-odt-merge-frame-params
+			  default-frame-params user-frame-params))
       (apply 'org-odt-format-textbox
       (apply 'org-odt-format-textbox
 	     (org-odt-format-stylized-paragraph
 	     (org-odt-format-stylized-paragraph
 	      'illustration
 	      'illustration
-	      (concat entity-frame
+	      (concat
-		      (org-odt-format-entity-caption
+	       (apply 'org-odt-format-frame href width height
-		       label caption (or category (nth 1 entity-style)))))
+		      (nth 2 entity-style))
-	     width height (nth 3 entity-style)))))
+	       (org-odt-format-entity-caption
+		label caption (or category (nth 1 entity-style)))))
+	     width height frame-params)))))
 
 
 (defvar org-odt-embedded-images-count 0)
 (defvar org-odt-embedded-images-count 0)
 (defun org-odt-copy-image-file (path)
 (defun org-odt-copy-image-file (path)

+ 1 - 1
lisp/org-remember.el

@@ -1014,7 +1014,7 @@ See also the variable `org-reverse-note-order'."
 					; not handle this note
 					; not handle this note
 	    (and visitp (run-with-idle-timer 0.01 nil 'org-remember-visit-immediately))
 	    (and visitp (run-with-idle-timer 0.01 nil 'org-remember-visit-immediately))
 	    (goto-char spos)
 	    (goto-char spos)
-	    (cond ((org-on-heading-p t)
+	    (cond ((org-at-heading-p t)
 		   (org-back-to-heading t)
 		   (org-back-to-heading t)
 		   (setq level (funcall outline-level))
 		   (setq level (funcall outline-level))
 		   (cond
 		   (cond

ファイルの差分が大きいため隠しています
+ 317 - 252
lisp/org.el


+ 10 - 0
testing/examples/ob-octave-test.org

@@ -43,3 +43,13 @@ Input elisp nil
 #+begin_src octave :exports results :results silent :var s='nil
 #+begin_src octave :exports results :results silent :var s='nil
 ans = s
 ans = s
 #+end_src
 #+end_src
+
+
+* Graphical tests
+#+begin_src octave :results graphics :file chart.png
+sombrero;
+#+end_src
+
+#+begin_src octave :session
+sombrero;
+#+end_src

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません