Browse Source

Merge branch 'master' of orgmode.org:org-mode

Christian Egli 12 years ago
parent
commit
c35168ed3f

+ 7 - 0
contrib/lisp/org-contacts.el

@@ -81,6 +81,12 @@ When set to nil, all your Org files will be used."
   :type 'string
   :type 'string
   :group 'org-contacts)
   :group 'org-contacts)
 
 
+(defcustom org-contacts-alias-property "ALIAS"
+  "Name of the property for contact name alias."
+  :type 'string
+  :group 'org-contacts)
+
+
 (defcustom org-contacts-birthday-format "Birthday: %l (%Y)"
 (defcustom org-contacts-birthday-format "Birthday: %l (%Y)"
   "Format of the anniversary agenda entry.
   "Format of the anniversary agenda entry.
 The following replacements are available:
 The following replacements are available:
@@ -129,6 +135,7 @@ The following replacements are available:
 
 
 (defcustom org-contacts-matcher
 (defcustom org-contacts-matcher
   (mapconcat 'identity (list org-contacts-email-property
   (mapconcat 'identity (list org-contacts-email-property
+			     org-contacts-alias-property
 			     org-contacts-tel-property
 			     org-contacts-tel-property
 			     org-contacts-address-property
 			     org-contacts-address-property
 			     org-contacts-birthday-property)
 			     org-contacts-birthday-property)

File diff suppressed because it is too large
+ 372 - 220
doc/org.texi


+ 3 - 4
lisp/ob-core.el

@@ -317,7 +317,7 @@ Do not query the user."
 (defsubst org-babel-confirm-evaluate (info)
 (defsubst org-babel-confirm-evaluate (info)
   "Confirm evaluation of the code block INFO.
   "Confirm evaluation of the code block INFO.
 
 
-If the variable `org-babel-confirm-evaluate-answer-no´ is bound
+If the variable `org-babel-confirm-evaluate-answer-no' is bound
 to a non-nil value, auto-answer with \"no\".
 to a non-nil value, auto-answer with \"no\".
 
 
 This query can also be suppressed by setting the value of
 This query can also be suppressed by setting the value of
@@ -2514,9 +2514,8 @@ appropriate."
   (if (and (stringp cell) (not (equal cell "")))
   (if (and (stringp cell) (not (equal cell "")))
       (or (org-babel-number-p cell)
       (or (org-babel-number-p cell)
           (if (and (not inhibit-lisp-eval)
           (if (and (not inhibit-lisp-eval)
-		   (member (substring cell 0 1) '("(" "'" "`" "[" "*"))
-		   (or (not (equal (substring cell 0 1) "*"))
-		       (equal (substring cell (- (length cell) 1)) "*")))
+		   (or (member (substring cell 0 1) '("(" "'" "`" "["))
+		       (string= cell "*this*")))
               (eval (read cell))
               (eval (read cell))
             (if (string= (substring cell 0 1) "\"")
             (if (string= (substring cell 0 1) "\"")
 		(read cell)
 		(read cell)

+ 3 - 3
lisp/ob-exp.el

@@ -92,8 +92,8 @@ process."
 
 
 (defun org-babel-exp-src-block (&rest headers)
 (defun org-babel-exp-src-block (&rest headers)
   "Process source block for export.
   "Process source block for export.
-Depending on the 'export' headers argument in replace the source
-code block with...
+Depending on the 'export' headers argument, replace the source
+code block like this:
 
 
 both ---- display the code and the results
 both ---- display the code and the results
 
 
@@ -103,7 +103,7 @@ code ---- the default, display the code inside the block but do
 results - just like none only the block is run on export ensuring
 results - just like none only the block is run on export ensuring
           that it's results are present in the org-mode buffer
           that it's results are present in the org-mode buffer
 
 
-none ----- do not display either code or results upon export
+none ---- do not display either code or results upon export
 
 
 Assume point is at the beginning of block's starting line."
 Assume point is at the beginning of block's starting line."
   (interactive)
   (interactive)

+ 1 - 0
lisp/ob-lob.el

@@ -116,6 +116,7 @@ if so then run the appropriate source block from the Library."
 	 (list (length (if (= (length (match-string 12)) 0)
 	 (list (length (if (= (length (match-string 12)) 0)
 			   (match-string 2) (match-string 11)))))))))
 			   (match-string 2) (match-string 11)))))))))
 
 
+(defvar org-babel-default-header-args:emacs-lisp) ; Defined in ob-emacs-lisp.el
 (defun org-babel-lob-execute (info)
 (defun org-babel-lob-execute (info)
   "Execute the lob call specified by INFO."
   "Execute the lob call specified by INFO."
   (let* ((mkinfo (lambda (p) (list "emacs-lisp" "results" p nil nil (nth 2 info))))
   (let* ((mkinfo (lambda (p) (list "emacs-lisp" "results" p nil nil (nth 2 info))))

+ 1 - 1
lisp/ob-ref.el

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

+ 39 - 29
lisp/org-agenda.el

@@ -2472,12 +2472,12 @@ This undoes changes both in the agenda buffer and in the remote buffer
 that have been changed along."
 that have been changed along."
   (interactive)
   (interactive)
   (or org-agenda-allow-remote-undo
   (or org-agenda-allow-remote-undo
-      (error "Check the variable `org-agenda-allow-remote-undo' to activate remote undo"))
+      (user-error "Check the variable `org-agenda-allow-remote-undo' to activate remote undo"))
   (if (not (eq this-command last-command))
   (if (not (eq this-command last-command))
       (setq org-agenda-undo-has-started-in nil
       (setq org-agenda-undo-has-started-in nil
 	    org-agenda-pending-undo-list org-agenda-undo-list))
 	    org-agenda-pending-undo-list org-agenda-undo-list))
   (if (not org-agenda-pending-undo-list)
   (if (not org-agenda-pending-undo-list)
-      (error "No further undo information"))
+      (user-error "No further undo information"))
   (let* ((entry (pop org-agenda-pending-undo-list))
   (let* ((entry (pop org-agenda-pending-undo-list))
 	 buf line cmd rembuf)
 	 buf line cmd rembuf)
     (setq cmd (pop entry) line (pop entry))
     (setq cmd (pop entry) line (pop entry))
@@ -2787,7 +2787,7 @@ Pressing `<' twice means to restrict to the current subtree or region
 		(org-let lprops '(funcall type org-match)))
 		(org-let lprops '(funcall type org-match)))
 	       ((fboundp type)
 	       ((fboundp type)
 		(org-let lprops '(funcall type org-match)))
 		(org-let lprops '(funcall type org-match)))
-	       (t (error "Invalid custom agenda command type %s" type))))
+	       (t (user-error "Invalid custom agenda command type %s" type))))
 	  (org-agenda-run-series (nth 1 entry) (cddr entry))))
 	  (org-agenda-run-series (nth 1 entry) (cddr entry))))
        ((equal org-keys "C")
        ((equal org-keys "C")
 	(setq org-agenda-custom-commands org-agenda-custom-commands-orig)
 	(setq org-agenda-custom-commands org-agenda-custom-commands-orig)
@@ -2818,14 +2818,14 @@ Pressing `<' twice means to restrict to the current subtree or region
 	 t t))
 	 t t))
        ((equal org-keys "L")
        ((equal org-keys "L")
 	(unless (derived-mode-p 'org-mode)
 	(unless (derived-mode-p 'org-mode)
-	  (error "This is not an Org-mode file"))
+	  (user-error "This is not an Org-mode file"))
 	(unless restriction
 	(unless restriction
 	  (put 'org-agenda-files 'org-restrict (list bfn))
 	  (put 'org-agenda-files 'org-restrict (list bfn))
 	  (org-call-with-arg 'org-timeline arg)))
 	  (org-call-with-arg 'org-timeline arg)))
        ((equal org-keys "#") (call-interactively 'org-agenda-list-stuck-projects))
        ((equal org-keys "#") (call-interactively 'org-agenda-list-stuck-projects))
        ((equal org-keys "/") (call-interactively 'org-occur-in-agenda-files))
        ((equal org-keys "/") (call-interactively 'org-occur-in-agenda-files))
        ((equal org-keys "!") (customize-variable 'org-stuck-projects))
        ((equal org-keys "!") (customize-variable 'org-stuck-projects))
-       (t (error "Invalid agenda key"))))))
+       (t (user-error "Invalid agenda key"))))))
 
 
 (defun org-agenda-append-agenda ()
 (defun org-agenda-append-agenda ()
   "Append another agenda view to the current one.
   "Append another agenda view to the current one.
@@ -2833,11 +2833,12 @@ This function allows interactive building of block agendas.
 Agenda views are separated by `org-agenda-block-separator'."
 Agenda views are separated by `org-agenda-block-separator'."
   (interactive)
   (interactive)
   (unless (derived-mode-p 'org-agenda-mode)
   (unless (derived-mode-p 'org-agenda-mode)
-    (error "Can only append from within agenda buffer"))
+    (user-error "Can only append from within agenda buffer"))
   (let ((org-agenda-multi t))
   (let ((org-agenda-multi t))
     (org-agenda)
     (org-agenda)
     (widen)
     (widen)
     (org-agenda-finalize)
     (org-agenda-finalize)
+    (setq buffer-read-only t)
     (org-agenda-fit-window-to-buffer)))
     (org-agenda-fit-window-to-buffer)))
 
 
 (defun org-agenda-normalize-custom-commands (cmds)
 (defun org-agenda-normalize-custom-commands (cmds)
@@ -3040,7 +3041,7 @@ L   Timeline for current buffer         #   List stuck projects (!=configure)
             (org-agenda-get-restriction-and-command prefix-descriptions))
             (org-agenda-get-restriction-and-command prefix-descriptions))
 
 
 	   ((equal c ?q) (error "Abort"))
 	   ((equal c ?q) (error "Abort"))
-	   (t (error "Invalid key %c" c))))))))
+	   (t (user-error "Invalid key %c" c))))))))
 
 
 (defun org-agenda-fit-window-to-buffer ()
 (defun org-agenda-fit-window-to-buffer ()
   "Fit the window to the buffer size."
   "Fit the window to the buffer size."
@@ -3302,7 +3303,7 @@ If AGENDA-BUFFER-NAME, use this as the buffer name for the agenda to write."
 	  (and (file-exists-p file)
 	  (and (file-exists-p file)
 	       (if (called-interactively-p 'any)
 	       (if (called-interactively-p 'any)
 		   (not (y-or-n-p (format "Overwrite existing file %s? " file))))))
 		   (not (y-or-n-p (format "Overwrite existing file %s? " file))))))
-      (error "Cannot write agenda to file %s" file))
+      (user-error "Cannot write agenda to file %s" file))
   (org-let (if nosettings nil org-agenda-exporter-settings)
   (org-let (if nosettings nil org-agenda-exporter-settings)
     '(save-excursion
     '(save-excursion
        (save-window-excursion
        (save-window-excursion
@@ -4331,7 +4332,8 @@ items if they have an hour specification like [h]h:mm."
 	(t n)))
 	(t n)))
 
 
 (defun org-agenda-span-to-ndays (span &optional start-day)
 (defun org-agenda-span-to-ndays (span &optional start-day)
-  "Return ndays from SPAN, possibly starting at START-DAY."
+  "Return ndays from SPAN, possibly starting at START-DAY.
+START-DAY is an absolute time value."
   (cond ((numberp span) span)
   (cond ((numberp span) span)
 	((eq span 'day) 1)
 	((eq span 'day) 1)
 	((eq span 'week) 7)
 	((eq span 'week) 7)
@@ -7723,23 +7725,31 @@ Negative selection means regexp must not match for selection of an entry."
   (let* ((org-read-date-prefer-future
   (let* ((org-read-date-prefer-future
 	  (eval org-agenda-jump-prefer-future))
 	  (eval org-agenda-jump-prefer-future))
 	 (date (org-read-date))
 	 (date (org-read-date))
+	 (day (time-to-days (org-time-string-to-time date)))
 	 (org-agenda-sticky-orig org-agenda-sticky)
 	 (org-agenda-sticky-orig org-agenda-sticky)
 	 (org-agenda-buffer-tmp-name (buffer-name))
 	 (org-agenda-buffer-tmp-name (buffer-name))
 	 (args (get-text-property (min (1- (point-max)) (point)) 'org-last-args))
 	 (args (get-text-property (min (1- (point-max)) (point)) 'org-last-args))
 	 (0-arg (or current-prefix-arg (car args)))
 	 (0-arg (or current-prefix-arg (car args)))
 	 (2-arg (nth 2 args))
 	 (2-arg (nth 2 args))
+	 (with-hour-p (nth 4 org-agenda-redo-command))
 	 (newcmd (list 'org-agenda-list 0-arg date
 	 (newcmd (list 'org-agenda-list 0-arg date
-		       (org-agenda-span-to-ndays 2-arg)))
+		       (org-agenda-span-to-ndays
+			2-arg (org-time-string-to-absolute date))
+		       with-hour-p))
 	 (newargs (cdr newcmd))
 	 (newargs (cdr newcmd))
 	 (inhibit-read-only t)
 	 (inhibit-read-only t)
 	 org-agenda-sticky)
 	 org-agenda-sticky)
     (if (not (org-agenda-check-type t 'agenda))
     (if (not (org-agenda-check-type t 'agenda))
-	(error "Not available in non-agenda blocks")
+	(error "Not available in non-agenda views")
       (add-text-properties (point-min) (point-max)
       (add-text-properties (point-min) (point-max)
 			   `(org-redo-cmd ,newcmd org-last-args ,newargs))
 			   `(org-redo-cmd ,newcmd org-last-args ,newargs))
       (org-agenda-redo)
       (org-agenda-redo)
-    (setq org-agenda-sticky org-agenda-sticky-orig
-	  org-agenda-this-buffer-is-sticky org-agenda-sticky))))
+      (goto-char (point-min))
+      (while (not (or (= (or (get-text-property (point) 'day) 0) day)
+		      (save-excursion (move-beginning-of-line 2) (eobp))))
+	(move-beginning-of-line 2))
+      (setq org-agenda-sticky org-agenda-sticky-orig
+	    org-agenda-this-buffer-is-sticky org-agenda-sticky))))
 
 
 (defun org-agenda-goto-today ()
 (defun org-agenda-goto-today ()
   "Go to today."
   "Go to today."
@@ -9230,7 +9240,7 @@ ARG is passed through to `org-deadline'."
   "Cancel the currently running clock."
   "Cancel the currently running clock."
   (interactive "P")
   (interactive "P")
   (unless (marker-buffer org-clock-marker)
   (unless (marker-buffer org-clock-marker)
-    (error "No running clock"))
+    (user-error "No running clock"))
   (org-with-remote-undo (marker-buffer org-clock-marker)
   (org-with-remote-undo (marker-buffer org-clock-marker)
     (org-clock-cancel)))
     (org-clock-cancel)))
 
 
@@ -9258,7 +9268,7 @@ buffer, display it in another window."
 	(setq d1 (calendar-cursor-to-date t)
 	(setq d1 (calendar-cursor-to-date t)
 	      d2 (car calendar-mark-ring))
 	      d2 (car calendar-mark-ring))
       (setq dp1 (get-text-property (point-at-bol) 'day))
       (setq dp1 (get-text-property (point-at-bol) 'day))
-      (unless dp1 (error "No date defined in current line"))
+      (unless dp1 (user-error "No date defined in current line"))
       (setq d1 (calendar-gregorian-from-absolute dp1)
       (setq d1 (calendar-gregorian-from-absolute dp1)
 	    d2 (and (ignore-errors (mark))
 	    d2 (and (ignore-errors (mark))
 		    (save-excursion
 		    (save-excursion
@@ -9282,7 +9292,7 @@ buffer, display it in another window."
      ((equal char ?b)
      ((equal char ?b)
       (setq text (read-string "Block entry: "))
       (setq text (read-string "Block entry: "))
       (unless (and d1 d2 (not (equal d1 d2)))
       (unless (and d1 d2 (not (equal d1 d2)))
-	(error "No block of days selected"))
+	(user-error "No block of days selected"))
       (org-agenda-add-entry-to-org-agenda-diary-file 'block text d1 d2)
       (org-agenda-add-entry-to-org-agenda-diary-file 'block text d1 d2)
       (and (equal (buffer-name) org-agenda-buffer-name) (org-agenda-redo)))
       (and (equal (buffer-name) org-agenda-buffer-name) (org-agenda-redo)))
      ((equal char ?j)
      ((equal char ?j)
@@ -9291,7 +9301,7 @@ buffer, display it in another window."
       (require 'org-datetree)
       (require 'org-datetree)
       (org-datetree-find-date-create d1)
       (org-datetree-find-date-create d1)
       (org-reveal t))
       (org-reveal t))
-     (t (error "Invalid selection character `%c'" char)))))
+     (t (user-error "Invalid selection character `%c'" char)))))
 
 
 (defcustom org-agenda-insert-diary-strategy 'date-tree
 (defcustom org-agenda-insert-diary-strategy 'date-tree
   "Where in `org-agenda-diary-file' should new entries be added?
   "Where in `org-agenda-diary-file' should new entries be added?
@@ -9451,11 +9461,11 @@ entries in that Org-mode file."
 	   (point (point))
 	   (point (point))
 	   (mark (or (mark t) (point))))
 	   (mark (or (mark t) (point))))
       (unless cmd
       (unless cmd
-	(error "No command associated with <%c>" char))
+	(user-error "No command associated with <%c>" char))
       (unless (and (get-text-property point 'day)
       (unless (and (get-text-property point 'day)
 		   (or (not (equal ?b char))
 		   (or (not (equal ?b char))
 		       (get-text-property mark 'day)))
 		       (get-text-property mark 'day)))
-	(error "Don't know which date to use for diary entry"))
+	(user-error "Don't know which date to use for diary entry"))
       ;; We implement this by hacking the `calendar-cursor-to-date' function
       ;; We implement this by hacking the `calendar-cursor-to-date' function
       ;; and the `calendar-mark-ring' variable.  Saves a lot of code.
       ;; and the `calendar-mark-ring' variable.  Saves a lot of code.
       (let ((calendar-mark-ring
       (let ((calendar-mark-ring
@@ -9476,7 +9486,7 @@ entries in that Org-mode file."
   (org-agenda-check-type t 'agenda 'timeline)
   (org-agenda-check-type t 'agenda 'timeline)
   (require 'diary-lib)
   (require 'diary-lib)
   (unless (get-text-property (min (1- (point-max)) (point)) 'day)
   (unless (get-text-property (min (1- (point-max)) (point)) 'day)
-    (error "Don't know which date to use for the calendar command"))
+    (user-error "Don't know which date to use for the calendar command"))
   (let* ((oldf (symbol-function 'calendar-cursor-to-date))
   (let* ((oldf (symbol-function 'calendar-cursor-to-date))
 	 (point (point))
 	 (point (point))
 	 (date (calendar-gregorian-from-absolute
 	 (date (calendar-gregorian-from-absolute
@@ -9525,7 +9535,7 @@ argument, latitude and longitude will be prompted for."
   (interactive)
   (interactive)
   (org-agenda-check-type t 'agenda 'timeline)
   (org-agenda-check-type t 'agenda 'timeline)
   (let* ((day (or (get-text-property (min (1- (point-max)) (point)) 'day)
   (let* ((day (or (get-text-property (min (1- (point-max)) (point)) 'day)
-		  (error "Don't know which date to open in calendar")))
+		  (user-error "Don't know which date to open in calendar")))
 	 (date (calendar-gregorian-from-absolute day))
 	 (date (calendar-gregorian-from-absolute day))
 	 (calendar-move-hook nil)
 	 (calendar-move-hook nil)
 	 (calendar-view-holidays-initially-flag nil)
 	 (calendar-view-holidays-initially-flag nil)
@@ -9548,7 +9558,7 @@ This is a command that has to be installed in `calendar-mode-map'."
   (let ((day (get-text-property (min (1- (point-max)) (point)) 'day))
   (let ((day (get-text-property (min (1- (point-max)) (point)) 'day))
 	date s)
 	date s)
     (unless day
     (unless day
-      (error "Don't know which date to convert"))
+      (user-error "Don't know which date to convert"))
     (setq date (calendar-gregorian-from-absolute day))
     (setq date (calendar-gregorian-from-absolute day))
     (setq s (concat
     (setq s (concat
 	     "Gregorian:  " (calendar-date-string date) "\n"
 	     "Gregorian:  " (calendar-date-string date) "\n"
@@ -9584,7 +9594,7 @@ This is a command that has to be installed in `calendar-mode-map'."
       (let* ((m (org-get-at-bol 'org-hd-marker))
       (let* ((m (org-get-at-bol 'org-hd-marker))
 	     ov)
 	     ov)
 	(unless (org-agenda-bulk-marked-p)
 	(unless (org-agenda-bulk-marked-p)
-	  (unless m (error "Nothing to mark at point"))
+	  (unless m (user-error "Nothing to mark at point"))
 	  (push m org-agenda-bulk-marked-entries)
 	  (push m org-agenda-bulk-marked-entries)
 	  (setq ov (make-overlay (point-at-bol) (+ 2 (point-at-bol))))
 	  (setq ov (make-overlay (point-at-bol) (+ 2 (point-at-bol))))
 	  (org-overlay-display ov (concat org-agenda-bulk-mark-char " ")
 	  (org-overlay-display ov (concat org-agenda-bulk-mark-char " ")
@@ -9676,14 +9686,14 @@ bulk action."
 The prefix arg is passed through to the command if possible."
 The prefix arg is passed through to the command if possible."
   (interactive "P")
   (interactive "P")
   ;; Make sure we have markers, and only valid ones
   ;; Make sure we have markers, and only valid ones
-  (unless org-agenda-bulk-marked-entries (error "No entries are marked"))
+  (unless org-agenda-bulk-marked-entries (user-error "No entries are marked"))
   (mapc
   (mapc
    (lambda (m)
    (lambda (m)
      (unless (and (markerp m)
      (unless (and (markerp m)
 		  (marker-buffer m)
 		  (marker-buffer m)
 		  (buffer-live-p (marker-buffer m))
 		  (buffer-live-p (marker-buffer m))
 		  (marker-position m))
 		  (marker-position m))
-       (error "Marker %s for bulk command is invalid" m)))
+       (user-error "Marker %s for bulk command is invalid" m)))
    org-agenda-bulk-marked-entries)
    org-agenda-bulk-marked-entries)
 
 
   ;; Prompt for the bulk command
   ;; Prompt for the bulk command
@@ -9762,7 +9772,7 @@ The prefix arg is passed through to the command if possible."
 
 
 	 ((equal action ?S)
 	 ((equal action ?S)
 	  (if (not (org-agenda-check-type nil 'agenda 'timeline 'todo))
 	  (if (not (org-agenda-check-type nil 'agenda 'timeline 'todo))
-	      (error "Can't scatter tasks in \"%s\" agenda view" org-agenda-type)
+	      (user-error "Can't scatter tasks in \"%s\" agenda view" org-agenda-type)
 	    (let ((days (read-number
 	    (let ((days (read-number
 			 (format "Scatter tasks across how many %sdays: "
 			 (format "Scatter tasks across how many %sdays: "
 				 (if arg "week" "")) 7)))
 				 (if arg "week" "")) 7)))
@@ -9800,7 +9810,7 @@ The prefix arg is passed through to the command if possible."
 			   (org-icompleting-read "Function: "
 			   (org-icompleting-read "Function: "
 						 obarray 'fboundp t nil nil)))))
 						 obarray 'fboundp t nil nil)))))
 
 
-	 (t (error "Invalid bulk action")))
+	 (t (user-error "Invalid bulk action")))
 
 
 	;; Sort the markers, to make sure that parents are handled before children
 	;; Sort the markers, to make sure that parents are handled before children
 	(setq entries (sort entries
 	(setq entries (sort entries
@@ -9856,7 +9866,7 @@ tag and (if present) the flagging note."
 	(win (selected-window))
 	(win (selected-window))
 	note heading newhead)
 	note heading newhead)
     (unless hdmarker
     (unless hdmarker
-      (error "No linked entry at point"))
+      (user-error "No linked entry at point"))
     (if (and (eq this-command last-command)
     (if (and (eq this-command last-command)
 	     (y-or-n-p "Unflag and remove any flagging note? "))
 	     (y-or-n-p "Unflag and remove any flagging note? "))
 	(progn
 	(progn
@@ -9866,7 +9876,7 @@ tag and (if present) the flagging note."
 	  (message "Entry unflagged"))
 	  (message "Entry unflagged"))
       (setq note (org-entry-get hdmarker "THEFLAGGINGNOTE"))
       (setq note (org-entry-get hdmarker "THEFLAGGINGNOTE"))
       (unless note
       (unless note
-	(error "No flagging note"))
+	(user-error "No flagging note"))
       (org-kill-new note)
       (org-kill-new note)
       (org-switch-to-buffer-other-window "*Flagging Note*")
       (org-switch-to-buffer-other-window "*Flagging Note*")
       (erase-buffer)
       (erase-buffer)

+ 50 - 41
lisp/org-clock.el

@@ -514,46 +514,51 @@ of a different task.")
   "Hook called in task selection just before prompting the user.")
   "Hook called in task selection just before prompting the user.")
 
 
 (defun org-clock-select-task (&optional prompt)
 (defun org-clock-select-task (&optional prompt)
-  "Select a task that recently was associated with clocking."
+  "Select a task that was recently associated with clocking."
   (interactive)
   (interactive)
-  (let (sel-list rpl (i 0) s)
-    (save-window-excursion
-      (org-switch-to-buffer-other-window
-       (get-buffer-create "*Clock Task Select*"))
-      (erase-buffer)
-      (when (marker-buffer org-clock-default-task)
-	(insert (org-add-props "Default Task\n" nil 'face 'bold))
-	(setq s (org-clock-insert-selection-line ?d org-clock-default-task))
-	(push s sel-list))
-      (when (marker-buffer org-clock-interrupted-task)
-	(insert (org-add-props "The task interrupted by starting the last one\n" nil 'face 'bold))
-	(setq s (org-clock-insert-selection-line ?i org-clock-interrupted-task))
-	(push s sel-list))
-      (when (org-clocking-p)
-	(insert (org-add-props "Current Clocking Task\n" nil 'face 'bold))
-	(setq s (org-clock-insert-selection-line ?c org-clock-marker))
-	(push s sel-list))
-      (insert (org-add-props "Recent Tasks\n" nil 'face 'bold))
-      (mapc
-       (lambda (m)
-	 (when (marker-buffer m)
-	   (setq i (1+ i)
-		 s (org-clock-insert-selection-line
-		    (if (< i 10)
-			(+ i ?0)
-		      (+ i (- ?A 10))) m))
-	   (if (fboundp 'int-to-char) (setf (car s) (int-to-char (car s))))
-	   (push s sel-list)))
-       org-clock-history)
-      (run-hooks 'org-clock-before-select-task-hook)
-      (org-fit-window-to-buffer)
-      (message (or prompt "Select task for clocking:"))
-      (setq rpl (read-char-exclusive))
-      (cond
-       ((eq rpl ?q) nil)
-       ((eq rpl ?x) nil)
-       ((assoc rpl sel-list) (cdr (assoc rpl sel-list)))
-       (t (error "Invalid task choice %c" rpl))))))
+  (let ((chl (length org-clock-history)) sel-list rpl (i 0) s)
+    (if (zerop chl)
+	(user-error "No recent clock")
+      (save-window-excursion
+	(org-switch-to-buffer-other-window
+	 (get-buffer-create "*Clock Task Select*"))
+	(erase-buffer)
+	(when (marker-buffer org-clock-default-task)
+	  (insert (org-add-props "Default Task\n" nil 'face 'bold))
+	  (setq s (org-clock-insert-selection-line ?d org-clock-default-task))
+	  (push s sel-list))
+	(when (marker-buffer org-clock-interrupted-task)
+	  (insert (org-add-props "The task interrupted by starting the last one\n" nil 'face 'bold))
+	  (setq s (org-clock-insert-selection-line ?i org-clock-interrupted-task))
+	  (push s sel-list))
+	(when (org-clocking-p)
+	  (insert (org-add-props "Current Clocking Task\n" nil 'face 'bold))
+	  (setq s (org-clock-insert-selection-line ?c org-clock-marker))
+	  (push s sel-list))
+	(insert (org-add-props "Recent Tasks\n" nil 'face 'bold))
+	(mapc
+	 (lambda (m)
+	   (when (marker-buffer m)
+	     (setq i (1+ i)
+		   s (org-clock-insert-selection-line
+		      (if (< i 10)
+			  (+ i ?0)
+			(+ i (- ?A 10))) m))
+	     (if (fboundp 'int-to-char) (setf (car s) (int-to-char (car s))))
+	     (push s sel-list)))
+	 org-clock-history)
+	(run-hooks 'org-clock-before-select-task-hook)
+	(goto-char (point-min))
+	;; Set min-height relatively to circumvent a possible but in
+	;; `fit-window-to-buffer'
+	(fit-window-to-buffer nil nil (if (< chl 10) chl (+ 5 chl)))
+	(message (or prompt "Select task for clocking:"))
+	(setq cursor-type nil rpl (read-char-exclusive))
+	(cond
+	 ((eq rpl ?q) nil)
+	 ((eq rpl ?x) nil)
+	 ((assoc rpl sel-list) (cdr (assoc rpl sel-list)))
+	 (t (user-error "Invalid task choice %c" rpl)))))))
 
 
 (defun org-clock-insert-selection-line (i marker)
 (defun org-clock-insert-selection-line (i marker)
   "Insert a line for the clock selection menu.
   "Insert a line for the clock selection menu.
@@ -580,7 +585,7 @@ pointing to it."
 			   org-odd-levels-only)
 			   org-odd-levels-only)
 			  (length prefix)))))))
 			  (length prefix)))))))
       (when (and cat task)
       (when (and cat task)
-	(insert (format "[%c] %-15s %s\n" i cat task))
+	(insert (format "[%c] %-12s  %s\n" i cat task))
 	(cons i marker)))))
 	(cons i marker)))))
 
 
 (defvar org-clock-task-overrun nil
 (defvar org-clock-task-overrun nil
@@ -926,19 +931,23 @@ was started."
 		(with-output-to-temp-buffer "*Org Clock*"
 		(with-output-to-temp-buffer "*Org Clock*"
 		  (princ "Select a Clock Resolution Command:
 		  (princ "Select a Clock Resolution Command:
 
 
-i/q/C-g  Ignore this question; the same as keeping all the idle time.
+i/q      Ignore this question; the same as keeping all the idle time.
 
 
 k/K      Keep X minutes of the idle time (default is all).  If this
 k/K      Keep X minutes of the idle time (default is all).  If this
          amount is less than the default, you will be clocked out
          amount is less than the default, you will be clocked out
          that many minutes after the time that idling began, and then
          that many minutes after the time that idling began, and then
          clocked back in at the present time.
          clocked back in at the present time.
+
 g/G      Indicate that you \"got back\" X minutes ago.  This is quite
 g/G      Indicate that you \"got back\" X minutes ago.  This is quite
          different from 'k': it clocks you out from the beginning of
          different from 'k': it clocks you out from the beginning of
          the idle period and clock you back in X minutes ago.
          the idle period and clock you back in X minutes ago.
+
 s/S      Subtract the idle time from the current clock.  This is the
 s/S      Subtract the idle time from the current clock.  This is the
          same as keeping 0 minutes.
          same as keeping 0 minutes.
+
 C        Cancel the open timer altogether.  It will be as though you
 C        Cancel the open timer altogether.  It will be as though you
          never clocked in.
          never clocked in.
+
 j/J      Jump to the current clock, to make manual adjustments.
 j/J      Jump to the current clock, to make manual adjustments.
 
 
 For all these options, using uppercase makes your final state
 For all these options, using uppercase makes your final state

+ 1 - 1
lisp/org-element.el

@@ -3393,7 +3393,7 @@ LIMIT bounds the search.
 
 
 Return value is a cons cell whose CAR is `table-cell' and CDR is
 Return value is a cons cell whose CAR is `table-cell' and CDR is
 beginning position."
 beginning position."
-  (when (looking-at "[ \t]*.*?[ \t]+|") (cons 'table-cell (point))))
+  (when (looking-at "[ \t]*.*?[ \t]*|") (cons 'table-cell (point))))
 
 
 
 
 ;;;; Target
 ;;;; Target

+ 5 - 5
lisp/org-footnote.el

@@ -138,13 +138,13 @@ will be used to define the footnote at the reference position."
   "Non-nil means define automatically new labels for footnotes.
   "Non-nil means define automatically new labels for footnotes.
 Possible values are:
 Possible values are:
 
 
-nil        prompt the user for each label
-t          create unique labels of the form [fn:1], [fn:2], ...
-confirm    like t, but let the user edit the created value.  In particular,
-           the label can be removed from the minibuffer, to create
+nil        Prompt the user for each label.
+t          Create unique labels of the form [fn:1], [fn:2], etc.
+confirm    Like t, but let the user edit the created value.
+           The label can be removed from the minibuffer to create
            an anonymous footnote.
            an anonymous footnote.
 random	   Automatically generate a unique, random label.
 random	   Automatically generate a unique, random label.
-plain      Automatically create plain number labels like [1]"
+plain      Automatically create plain number labels like [1]."
   :group 'org-footnote
   :group 'org-footnote
   :type '(choice
   :type '(choice
 	  (const :tag "Prompt for label" nil)
 	  (const :tag "Prompt for label" nil)

+ 4 - 5
lisp/org-macs.el

@@ -162,18 +162,17 @@ We use a macro so that the test can happen at compilation time."
   (cons (if (fboundp 'with-no-warnings) 'with-no-warnings 'progn) body))
   (cons (if (fboundp 'with-no-warnings) 'with-no-warnings 'progn) body))
 (def-edebug-spec org-no-warnings (body))
 (def-edebug-spec org-no-warnings (body))
 
 
-;; FIXME: Normalize argument names
-(defmacro org-with-remote-undo (_buffer &rest _body)
+(defmacro org-with-remote-undo (buffer &rest body)
   "Execute BODY while recording undo information in two buffers."
   "Execute BODY while recording undo information in two buffers."
   (org-with-gensyms (cline cmd buf1 buf2 undo1 undo2 c1 c2)
   (org-with-gensyms (cline cmd buf1 buf2 undo1 undo2 c1 c2)
     `(let ((,cline (org-current-line))
     `(let ((,cline (org-current-line))
 	   (,cmd this-command)
 	   (,cmd this-command)
 	   (,buf1 (current-buffer))
 	   (,buf1 (current-buffer))
-	   (,buf2 ,_buffer)
+	   (,buf2 ,buffer)
 	   (,undo1 buffer-undo-list)
 	   (,undo1 buffer-undo-list)
-	   (,undo2 (with-current-buffer ,_buffer buffer-undo-list))
+	   (,undo2 (with-current-buffer ,buffer buffer-undo-list))
 	   ,c1 ,c2)
 	   ,c1 ,c2)
-       ,@_body
+       ,@body
        (when org-agenda-allow-remote-undo
        (when org-agenda-allow-remote-undo
 	 (setq ,c1 (org-verify-change-for-undo
 	 (setq ,c1 (org-verify-change-for-undo
 		    ,undo1 (with-current-buffer ,buf1 buffer-undo-list))
 		    ,undo1 (with-current-buffer ,buf1 buffer-undo-list))

+ 3 - 3
lisp/org-mobile.el

@@ -1066,13 +1066,13 @@ be returned that indicates what went wrong."
 	 (t (error "Heading changed in MobileOrg and on the computer")))))
 	 (t (error "Heading changed in MobileOrg and on the computer")))))
 
 
      ((eq what 'addheading)
      ((eq what 'addheading)
-      (if (org-on-heading-p) ; if false we are in top-level of file
+      (if (org-at-heading-p) ; if false we are in top-level of file
 	  (progn
 	  (progn
 	    ;; Workaround a `org-insert-heading-respect-content' bug
 	    ;; Workaround a `org-insert-heading-respect-content' bug
 	    ;; which prevents correct insertion when point is invisible
 	    ;; which prevents correct insertion when point is invisible
 	    (org-show-subtree)
 	    (org-show-subtree)
 	    (end-of-line 1)
 	    (end-of-line 1)
-	    (org-insert-heading-respect-content '(4) t)
+	    (org-insert-heading-respect-content '(16) t)
 	    (org-demote))
 	    (org-demote))
 	(beginning-of-line)
 	(beginning-of-line)
 	(insert "* "))
 	(insert "* "))
@@ -1081,7 +1081,7 @@ be returned that indicates what went wrong."
      ((eq what 'refile)
      ((eq what 'refile)
       (org-copy-subtree)
       (org-copy-subtree)
       (org-with-point-at (org-mobile-locate-entry new)
       (org-with-point-at (org-mobile-locate-entry new)
-	(if (org-on-heading-p) ; if false we are in top-level of file
+	(if (org-at-heading-p) ; if false we are in top-level of file
 	    (progn
 	    (progn
 	      (setq level (org-get-valid-level (funcall outline-level) 1))
 	      (setq level (org-get-valid-level (funcall outline-level) 1))
 	      (org-end-of-subtree t t)
 	      (org-end-of-subtree t t)

+ 1 - 1
lisp/org-mouse.el

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

+ 10 - 7
lisp/org-table.el

@@ -1118,7 +1118,7 @@ copying.  In the case of a timestamp, increment by one day."
   (interactive "p")
   (interactive "p")
   (let* ((colpos (org-table-current-column))
   (let* ((colpos (org-table-current-column))
 	 (col (current-column))
 	 (col (current-column))
-	 (field (org-table-get-field))
+	 (field (save-excursion (org-table-get-field)))
 	 (non-empty (string-match "[^ \t]" field))
 	 (non-empty (string-match "[^ \t]" field))
 	 (beg (org-table-begin))
 	 (beg (org-table-begin))
 	 (orig-n n)
 	 (orig-n n)
@@ -2929,7 +2929,10 @@ list, 'literal is for the format specifier L."
       (if lispp
       (if lispp
 	  (if (eq lispp 'literal)
 	  (if (eq lispp 'literal)
 	      elements
 	      elements
-	    (prin1-to-string (if numbers (string-to-number elements) elements)))
+	    (if (and (eq elements "") (not keep-empty))
+		""
+	      (prin1-to-string
+	       (if numbers (string-to-number elements) elements))))
 	(if (string-match "\\S-" elements)
 	(if (string-match "\\S-" elements)
 	    (progn
 	    (progn
 	      (when numbers (setq elements (number-to-string
 	      (when numbers (setq elements (number-to-string
@@ -2942,7 +2945,7 @@ list, 'literal is for the format specifier L."
 	    (delq nil
 	    (delq nil
 		  (mapcar (lambda (x) (if (string-match "\\S-" x) x nil))
 		  (mapcar (lambda (x) (if (string-match "\\S-" x) x nil))
 			  elements))))
 			  elements))))
-    (setq elements (or elements '("")))
+    (setq elements (or elements '()))  ; if delq returns nil then we need '()
     (if lispp
     (if lispp
 	(mapconcat
 	(mapconcat
 	 (lambda (x)
 	 (lambda (x)
@@ -4963,11 +4966,11 @@ it here: http://gnuvola.org/software/j/aa2u/ascii-art-to-unicode.el."
 (defun org-table-get-remote-range (name-or-id form)
 (defun org-table-get-remote-range (name-or-id form)
   "Get a field value or a list of values in a range from table at ID.
   "Get a field value or a list of values in a range from table at ID.
 
 
-NAME-OR-ID may be the name of a table in the current file as set by
-a \"#+TBLNAME:\" directive.  The first table following this line
+NAME-OR-ID may be the name of a table in the current file as set
+by a \"#+NAME:\" directive.  The first table following this line
 will then be used.  Alternatively, it may be an ID referring to
 will then be used.  Alternatively, it may be an ID referring to
-any entry, also in a different file.  In this case, the first table
-in that entry will be referenced.
+any entry, also in a different file.  In this case, the first
+table in that entry will be referenced.
 FORM is a field or range descriptor like \"@2$3\" or \"B3\" or
 FORM is a field or range descriptor like \"@2$3\" or \"B3\" or
 \"@I$2..@II$2\".  All the references must be absolute, not relative.
 \"@I$2..@II$2\".  All the references must be absolute, not relative.
 
 

+ 102 - 111
lisp/org.el

@@ -1340,9 +1340,8 @@ default   the value to be used for all contexts not explicitly
 (defcustom org-insert-heading-respect-content nil
 (defcustom org-insert-heading-respect-content nil
   "Non-nil means insert new headings after the current subtree.
   "Non-nil means insert new headings after the current subtree.
 When nil, the new heading is created directly after the current line.
 When nil, the new heading is created directly after the current line.
-The commands \\[org-insert-heading-respect-content] and
-\\[org-insert-todo-heading-respect-content] turn this variable on
-for the duration of the command."
+The commands \\[org-insert-heading-respect-content] and \\[org-insert-todo-heading-respect-content] turn
+this variable on for the duration of the command."
   :group 'org-structure
   :group 'org-structure
   :type 'boolean)
   :type 'boolean)
 
 
@@ -4011,7 +4010,7 @@ After a match, the match groups contain these elements:
 	   (body1 (concat body "*?"))
 	   (body1 (concat body "*?"))
 	   (markers (mapconcat 'car org-emphasis-alist ""))
 	   (markers (mapconcat 'car org-emphasis-alist ""))
 	   (vmarkers (mapconcat
 	   (vmarkers (mapconcat
-		      (lambda (x) (if (eq (nth 4 x) 'verbatim) (car x) ""))
+		      (lambda (x) (if (eq (nth 2 x) 'verbatim) (car x) ""))
 		      org-emphasis-alist "")))
 		      org-emphasis-alist "")))
       ;; make sure special characters appear at the right position in the class
       ;; make sure special characters appear at the right position in the class
       (if (string-match "\\^" markers)
       (if (string-match "\\^" markers)
@@ -4051,7 +4050,10 @@ After a match, the match groups contain these elements:
 		    "\\3\\)"
 		    "\\3\\)"
 		    "\\([" post  "]\\|$\\)")))))
 		    "\\([" post  "]\\|$\\)")))))
 
 
-(defcustom org-emphasis-regexp-components
+;; This used to be a defcustom (Org <8.0) but allowing the users to
+;; set this option proved cumbersome.  See this message/thread:
+;; http://article.gmane.org/gmane.emacs.orgmode/68681
+(defvar org-emphasis-regexp-components
   '(" \t('\"{" "- \t.,:!?;'\")}\\" " \t\r\n,\"'" "." 1)
   '(" \t('\"{" "- \t.,:!?;'\")}\\" " \t\r\n,\"'" "." 1)
   "Components used to build the regular expression for emphasis.
   "Components used to build the regular expression for emphasis.
 This is a list with five entries.  Terminology:  In an emphasis string
 This is a list with five entries.  Terminology:  In an emphasis string
@@ -4067,43 +4069,32 @@ body-regexp  A regexp like \".\" to match a body character.  Don't use
              non-shy groups here, and don't allow newline here.
              non-shy groups here, and don't allow newline here.
 newline      The maximum number of newlines allowed in an emphasis exp.
 newline      The maximum number of newlines allowed in an emphasis exp.
 
 
-Use customize to modify this, or restart Emacs after changing it."
-  :group 'org-appearance
-  :set 'org-set-emph-re
-  :type '(list
-	  (sexp    :tag "Allowed chars in pre      ")
-	  (sexp    :tag "Allowed chars in post     ")
-	  (sexp    :tag "Forbidden chars in border ")
-	  (sexp    :tag "Regexp for body           ")
-	  (integer :tag "number of newlines allowed")
-	  (option (boolean :tag "Please ignore this button"))))
+You need to reload Org or to restart Emacs after customizing this.")
 
 
 (defcustom org-emphasis-alist
 (defcustom org-emphasis-alist
-  `(("*" bold "<b>" "</b>")
-    ("/" italic "<i>" "</i>")
-    ("_" underline "<span style=\"text-decoration:underline;\">" "</span>")
-    ("=" org-code "<code>" "</code>" verbatim)
-    ("~" org-verbatim "<code>" "</code>" verbatim)
-    ("+" ,(if (featurep 'xemacs) 'org-table '(:strike-through t))
-     "<del>" "</del>")
-    )
-  "Special syntax for emphasized text.
-Text starting and ending with a special character will be emphasized, for
-example *bold*, _underlined_ and /italic/.  This variable sets the marker
-characters, the face to be used by font-lock for highlighting in Org-mode
-Emacs buffers, and the HTML tags to be used for this.
-For LaTeX export, see the variable `org-export-latex-emphasis-alist'.
-Use customize to modify this, or restart Emacs after changing it."
+  `(("*" bold)
+    ("/" italic)
+    ("_" underline)
+    ("=" org-code verbatim)
+    ("~" org-verbatim verbatim)
+    ("+" ,(if (featurep 'xemacs) 'org-table '(:strike-through t))))
+  "Alist of characters and faces to emphasize text.
+Text starting and ending with a special character will be emphasized,
+for example *bold*, _underlined_ and /italic/.  This variable sets the
+marker characters and the face to be used by font-lock for highlighting
+in Org-mode Emacs buffers.
+
+You need to reload Org or to restart Emacs after customizing this."
   :group 'org-appearance
   :group 'org-appearance
   :set 'org-set-emph-re
   :set 'org-set-emph-re
+  :version "24.4"
+  :package-version '(Org . "8.0")
   :type '(repeat
   :type '(repeat
 	  (list
 	  (list
 	   (string :tag "Marker character")
 	   (string :tag "Marker character")
 	   (choice
 	   (choice
 	    (face :tag "Font-lock-face")
 	    (face :tag "Font-lock-face")
 	    (plist :tag "Face property list"))
 	    (plist :tag "Face property list"))
-	   (string :tag "HTML start tag")
-	   (string :tag "HTML end tag")
 	   (option (const verbatim)))))
 	   (option (const verbatim)))))
 
 
 (defvar org-protecting-blocks
 (defvar org-protecting-blocks
@@ -5145,10 +5136,9 @@ Support for group tags is controlled by the option
   "Return the contents of FILE, as a string."
   "Return the contents of FILE, as a string."
   (if (or (not file)
   (if (or (not file)
 	  (not (file-readable-p file)))
 	  (not (file-readable-p file)))
-      (if (not noerror)
-	  (error "Cannot read file \"%s\"" file)
-	(message "Cannot read file \"%s\"" file)
-	(sit-for 3))
+      (if noerror
+	  (message "Cannot read file \"%s\"" file)
+	(error "Cannot read file \"%s\"" file))
     (with-temp-buffer
     (with-temp-buffer
       (insert-file-contents file)
       (insert-file-contents file)
       (buffer-string))))
       (buffer-string))))
@@ -5687,36 +5677,27 @@ The time stamps may be either active or inactive.")
 If there is an active region, change that region to a new emphasis.
 If there is an active region, change that region to a new emphasis.
 If there is no region, just insert the marker characters and position
 If there is no region, just insert the marker characters and position
 the cursor between them.
 the cursor between them.
-CHAR should be either the marker character, or the first character of the
-HTML tag associated with that emphasis.  If CHAR is a space, the means
-to remove the emphasis of the selected region.
-If char is not given (for example in an interactive call) it
-will be prompted for."
+CHAR should be the marker character.  If it is a space, it means to
+remove the emphasis of the selected region.
+If CHAR is not given (for example in an interactive call) it will be
+prompted for."
   (interactive)
   (interactive)
-  (let ((eal org-emphasis-alist) e det
-	(erc org-emphasis-regexp-components)
+  (let ((erc org-emphasis-regexp-components)
 	(prompt "")
 	(prompt "")
-	(string "") beg end move tag c s)
+	(string "") beg end move c s)
     (if (org-region-active-p)
     (if (org-region-active-p)
 	(setq beg (region-beginning) end (region-end)
 	(setq beg (region-beginning) end (region-end)
 	      string (buffer-substring beg end))
 	      string (buffer-substring beg end))
       (setq move t))
       (setq move t))
 
 
-    (while (setq e (pop eal))
-      (setq tag (car (org-split-string (nth 2 e) "[ <>/]+"))
-	    c (aref tag 0))
-      (push (cons c (string-to-char (car e))) det)
-      (setq prompt (concat prompt (format " [%s%c]%s" (car e) c
-					  (substring tag 1)))))
-    (setq det (nreverse det))
     (unless char
     (unless char
-      (message "%s" (concat "Emphasis marker or tag:" prompt))
+      (message "Emphasis marker or tag: [%s]"
+	       (mapconcat (lambda(e) (car e)) org-emphasis-alist ""))
       (setq char (read-char-exclusive)))
       (setq char (read-char-exclusive)))
-    (setq char (or (cdr (assoc char det)) char))
     (if (equal char ?\ )
     (if (equal char ?\ )
 	(setq s "" move nil)
 	(setq s "" move nil)
       (unless (assoc (char-to-string char) org-emphasis-alist)
       (unless (assoc (char-to-string char) org-emphasis-alist)
-	(error "No such emphasis marker: \"%c\"" char))
+	(user-error "No such emphasis marker: \"%c\"" char))
       (setq s (char-to-string char)))
       (setq s (char-to-string char)))
     (while (and (> (length string) 1)
     (while (and (> (length string) 1)
 		(equal (substring string 0 1) (substring string -1))
 		(equal (substring string 0 1) (substring string -1))
@@ -7522,11 +7503,13 @@ This is important for non-interactive uses of the command."
      (if (org-previous-line-empty-p) "" "\n")
      (if (org-previous-line-empty-p) "" "\n")
      (if (org-in-src-block-p) ",* " "* "))
      (if (org-in-src-block-p) ",* " "* "))
     (run-hooks 'org-insert-heading-hook))
     (run-hooks 'org-insert-heading-hook))
-   ((or arg (not (org-insert-item
-		  (save-excursion
-		    (beginning-of-line)
-		    (looking-at org-list-full-item-re)
-		    (match-string 3)))))
+   ((or arg
+	org-insert-heading-respect-content
+	(not (org-insert-item
+	      (save-excursion
+		(beginning-of-line)
+		(looking-at org-list-full-item-re)
+		(match-string 3)))))
     (let (begn endn)
     (let (begn endn)
       (when (org-buffer-narrowed-p)
       (when (org-buffer-narrowed-p)
 	(setq begn (point-min) endn (point-max))
 	(setq begn (point-min) endn (point-max))
@@ -7537,6 +7520,8 @@ This is important for non-interactive uses of the command."
 	      (or (not (null arg)) org-insert-heading-respect-content))
 	      (or (not (null arg)) org-insert-heading-respect-content))
 	     (level nil)
 	     (level nil)
 	     (on-heading (org-at-heading-p))
 	     (on-heading (org-at-heading-p))
+	     (on-empty-line
+	      (save-excursion (beginning-of-line 1) (looking-at "^\\s-*$")))
 	     (head (save-excursion
 	     (head (save-excursion
 		     (condition-case nil
 		     (condition-case nil
 			 (progn
 			 (progn
@@ -7589,6 +7574,11 @@ This is important for non-interactive uses of the command."
 		tags pos)
 		tags pos)
 	    (cond
 	    (cond
 	     ;; Insert a new line, possibly at end of parent subtree
 	     ;; Insert a new line, possibly at end of parent subtree
+	     ((and (not arg) (not on-heading) (not on-empty-line)
+		   (not (save-excursion
+			  (beginning-of-line 1)
+			  (looking-at org-list-full-item-re))))
+	      (beginning-of-line 1))
 	     (org-insert-heading-respect-content
 	     (org-insert-heading-respect-content
 	      (if (not eops)
 	      (if (not eops)
 		  (progn
 		  (progn
@@ -7638,7 +7628,9 @@ This is important for non-interactive uses of the command."
 		  (org-set-tags nil 'align))))
 		  (org-set-tags nil 'align))))
 	     (t
 	     (t
 	      (or split (end-of-line 1))
 	      (or split (end-of-line 1))
-	      (newline (if blank 2 1))))))
+	      (newline (cond ((and blank (not on-empty-line)) 2)
+			     (blank 1)
+			     (on-empty-line 0) (t 1)))))))
 	(insert head) (just-one-space)
 	(insert head) (just-one-space)
 	(setq pos (point))
 	(setq pos (point))
 	(end-of-line 1)
 	(end-of-line 1)
@@ -10122,23 +10114,6 @@ from."
       (org-add-props s nil 'org-attr attr))
       (org-add-props s nil 'org-attr attr))
     s))
     s))
 
 
-(defun org-extract-attributes-from-string (tag)
-  (let (key value attr)
-    (while (string-match "\\([a-zA-Z]+\\)=\"\\([^\"]*\\)\"\\s-?" tag)
-      (setq key (match-string 1 tag) value (match-string 2 tag)
-	    tag (replace-match "" t t tag)
-	    attr (plist-put attr (intern key) value)))
-    (cons tag attr)))
-
-(defun org-attributes-to-string (plist)
-  "Format a property list into an HTML attribute list."
-  (let ((s "") key value)
-    (while plist
-      (setq key (pop plist) value (pop plist))
-      (and value
-	   (setq s (concat s " " (symbol-name key) "=\"" value "\""))))
-    s))
-
 ;;; Opening/following a link
 ;;; Opening/following a link
 
 
 (defvar org-link-search-failed nil)
 (defvar org-link-search-failed nil)
@@ -12250,9 +12225,10 @@ For calling through lisp, arg is also interpreted in the following way:
 			      (nth 2 (assoc this org-todo-log-states))))
 			      (nth 2 (assoc this org-todo-log-states))))
 	      (if (and (eq dolog 'note) (eq org-inhibit-logging 'note))
 	      (if (and (eq dolog 'note) (eq org-inhibit-logging 'note))
 		  (setq dolog 'time))
 		  (setq dolog 'time))
-	      (when (and org-state
-			 (member org-state org-not-done-keywords)
-			 (not (member this org-not-done-keywords)))
+	      (when (or (not org-state)
+			(and org-state
+			     (member org-state org-not-done-keywords)
+			     (not (member this org-not-done-keywords))))
 		;; This is now a todo state and was not one before
 		;; This is now a todo state and was not one before
 		;; If there was a CLOSED time stamp, get rid of it.
 		;; If there was a CLOSED time stamp, get rid of it.
 		(org-add-planning-info nil nil 'closed))
 		(org-add-planning-info nil nil 'closed))
@@ -13242,7 +13218,7 @@ EXTRA is additional text that will be inserted into the notes buffer."
   (org-switch-to-buffer-other-window "*Org Note*")
   (org-switch-to-buffer-other-window "*Org Note*")
   (erase-buffer)
   (erase-buffer)
   (if (memq org-log-note-how '(time state))
   (if (memq org-log-note-how '(time state))
-      (let (current-prefix-arg)	(org-store-log-note))
+      (let (current-prefix-arg) (org-store-log-note))
     (let ((org-inhibit-startup t)) (org-mode))
     (let ((org-inhibit-startup t)) (org-mode))
     (insert (format "# Insert note for %s.
     (insert (format "# Insert note for %s.
 # Finish with C-c C-c, or cancel with C-c C-k.\n\n"
 # Finish with C-c C-c, or cancel with C-c C-k.\n\n"
@@ -13343,12 +13319,19 @@ EXTRA is additional text that will be inserted into the notes buffer."
 	      (insert (pop lines))))
 	      (insert (pop lines))))
 	  (message "Note stored")
 	  (message "Note stored")
 	  (org-back-to-heading t)
 	  (org-back-to-heading t)
-	  (org-cycle-hide-drawers 'children))))))
-  (set-window-configuration org-log-note-window-configuration)
-  (with-current-buffer (marker-buffer org-log-note-return-to)
-    (goto-char org-log-note-return-to))
-  (move-marker org-log-note-return-to nil)
-  (and org-log-post-message (message "%s" org-log-post-message)))
+	  (org-cycle-hide-drawers 'children))
+	;; Fix `buffer-undo-list' when `org-store-log-note' is called
+	;; from within `org-add-log-note' because `buffer-undo-list'
+	;; is then modified outside of `org-with-remote-undo'.
+	(when (eq this-command 'org-agenda-todo)
+	  (setcdr buffer-undo-list (cddr buffer-undo-list)))))))
+  ;; Don't add undo information when called from `org-agenda-todo'
+  (let ((buffer-undo-list (eq this-command 'org-agenda-todo)))
+    (set-window-configuration org-log-note-window-configuration)
+    (with-current-buffer (marker-buffer org-log-note-return-to)
+      (goto-char org-log-note-return-to))
+    (move-marker org-log-note-return-to nil)
+    (and org-log-post-message (message "%s" org-log-post-message))))
 
 
 (defun org-remove-empty-drawer-at (drawer pos)
 (defun org-remove-empty-drawer-at (drawer pos)
   "Remove an empty drawer DRAWER at position POS.
   "Remove an empty drawer DRAWER at position POS.
@@ -13969,9 +13952,12 @@ See also `org-scan-tags'.
   (unless (boundp 'todo-only)
   (unless (boundp 'todo-only)
     (error "`org-make-tags-matcher' expects todo-only to be scoped in"))
     (error "`org-make-tags-matcher' expects todo-only to be scoped in"))
   (unless match
   (unless match
-    ;; Get a new match request, with completion
+    ;; Get a new match request, with completion against the global
+    ;; tags table and the local tags in current buffer
     (let ((org-last-tags-completion-table
     (let ((org-last-tags-completion-table
-	   (org-global-tags-completion-table)))
+	   (org-uniquify
+	    (delq nil (append (org-get-buffer-tags)
+			      (org-global-tags-completion-table))))))
       (setq match (org-completing-read-no-i
       (setq match (org-completing-read-no-i
 		   "Match: " 'org-tags-completion-function nil nil nil
 		   "Match: " 'org-tags-completion-function nil nil nil
 		   'org-tags-history))))
 		   'org-tags-history))))
@@ -14098,14 +14084,14 @@ This replaces every group tag in MATCH with a regexp tag search.
 For example, a group tag \"Work\" defined as { Work : Lab Conf }
 For example, a group tag \"Work\" defined as { Work : Lab Conf }
 will be replaced like this:
 will be replaced like this:
 
 
-   Work =>  {\(?:Work\|Lab\|Conf\}
-  +Work => +{\(?:Work\|Lab\|Conf\}
-  -Work => -{\(?:Work\|Lab\|Conf\}
+   Work =>  {\\(?:Work\\|Lab\\|Conf\\)}
+  +Work => +{\\(?:Work\\|Lab\\|Conf\\)}
+  -Work => -{\\(?:Work\\|Lab\\|Conf\\)}
 
 
 Replacing by a regexp preserves the structure of the match.
 Replacing by a regexp preserves the structure of the match.
 E.g., this expansion
 E.g., this expansion
 
 
-  Work|Home => {\(?:Work\|Lab\|Conf\}|Home
+  Work|Home => {\\(?:Work\\|Lab\\|Conf\\}|Home
 
 
 will match anything tagged with \"Lab\" and \"Home\", or tagged
 will match anything tagged with \"Lab\" and \"Home\", or tagged
 with \"Conf\" and \"Home\" or tagged with \"Work\" and \"home\".
 with \"Conf\" and \"Home\" or tagged with \"Work\" and \"home\".
@@ -14120,23 +14106,26 @@ When DOWNCASE is non-nil, expand downcased TAGS."
 	     (stable org-mode-syntax-table)
 	     (stable org-mode-syntax-table)
 	     (tal (or org-tag-groups-alist-for-agenda
 	     (tal (or org-tag-groups-alist-for-agenda
 		      org-tag-groups-alist))
 		      org-tag-groups-alist))
-	     (tal (if downcased (mapcar (lambda(tg) (mapcar 'downcase tg)) tal) tal))
+	     (tal (if downcased
+		      (mapcar (lambda(tg) (mapcar 'downcase tg)) tal) tal))
 	     (tml (mapcar 'car tal))
 	     (tml (mapcar 'car tal))
 	     (rtnmatch match) rpl)
 	     (rtnmatch match) rpl)
 	;; @ and _ are allowed as word-components in tags
 	;; @ and _ are allowed as word-components in tags
 	(modify-syntax-entry ?@ "w" stable)
 	(modify-syntax-entry ?@ "w" stable)
 	(modify-syntax-entry ?_ "w" stable)
 	(modify-syntax-entry ?_ "w" stable)
-	(while (and tml (string-match
-			 (concat "\\(?1:[+-]?\\)\\(?2:\\<" (regexp-opt tml) "\\>\\)")
-			 rtnmatch))
+	(while (and tml
+		    (string-match
+		     (concat "\\(?1:[+-]?\\)\\(?2:\\<"
+			     (regexp-opt tml) "\\>\\)") rtnmatch))
 	  (let* ((dir (match-string 1 rtnmatch))
 	  (let* ((dir (match-string 1 rtnmatch))
 		 (tag (match-string 2 rtnmatch))
 		 (tag (match-string 2 rtnmatch))
 		 (tag (if downcased (downcase tag) tag)))
 		 (tag (if downcased (downcase tag) tag)))
 	    (setq tml (delete tag tml))
 	    (setq tml (delete tag tml))
-	    (setq rpl (append (org-uniquify rpl) (assoc tag tal)))
-	    (setq rtnmatch
-		  (replace-match
-		   (concat dir "{" (regexp-opt rpl) "}") t t rtnmatch))))
+	    (when (not (get-text-property 0 'grouptag (match-string 2 rtnmatch)))
+	      (setq rpl (append (org-uniquify rpl) (assoc tag tal)))
+	      (setq rpl (concat dir "{\\<" (regexp-opt rpl) "\\>}"))
+	      (if (stringp rpl) (org-add-props rpl '(grouptag t)))
+	      (setq rtnmatch (replace-match rpl t t rtnmatch)))))
 	(if single-as-list
 	(if single-as-list
 	    (or (reverse rpl) (list rtnmatch))
 	    (or (reverse rpl) (list rtnmatch))
 	  rtnmatch))
 	  rtnmatch))
@@ -14487,7 +14476,9 @@ This works in the agenda, and also in an org-mode buffer."
    (list (region-beginning) (region-end)
    (list (region-beginning) (region-end)
 	 (let ((org-last-tags-completion-table
 	 (let ((org-last-tags-completion-table
 		(if (derived-mode-p 'org-mode)
 		(if (derived-mode-p 'org-mode)
-		    (org-get-buffer-tags)
+		    (org-uniquify
+		     (delq nil (append (org-get-buffer-tags)
+				       (org-global-tags-completion-table))))
 		  (org-global-tags-completion-table))))
 		  (org-global-tags-completion-table))))
 	   (org-icompleting-read
 	   (org-icompleting-read
 	    "Tag: " 'org-tags-completion-function nil nil nil
 	    "Tag: " 'org-tags-completion-function nil nil nil
@@ -17464,7 +17455,9 @@ The format is determined by `org-time-clocksum-format',
 `org-time-clocksum-use-fractional' and
 `org-time-clocksum-use-fractional' and
 `org-time-clocksum-fractional-format' and
 `org-time-clocksum-fractional-format' and
 `org-time-clocksum-use-effort-durations'."
 `org-time-clocksum-use-effort-durations'."
-  (let ((clocksum "") h d w mo y fmt n)
+  (let ((clocksum "")
+	(m (round m)) ; Don't allow fractions of minutes
+	h d w mo y fmt n)
     (setq h (if org-time-clocksum-use-effort-durations
     (setq h (if org-time-clocksum-use-effort-durations
 		(cdr (assoc "h" org-effort-durations)) 60)
 		(cdr (assoc "h" org-effort-durations)) 60)
 	  d (if org-time-clocksum-use-effort-durations
 	  d (if org-time-clocksum-use-effort-durations
@@ -21594,14 +21587,12 @@ for the search purpose."
   "Return the reverse of STRING."
   "Return the reverse of STRING."
   (apply 'string (reverse (string-to-list string))))
   (apply 'string (reverse (string-to-list string))))
 
 
-(defun org-uniquify (list)
-  "Remove duplicate elements from LIST."
-  (let (res)
-    (mapc (lambda (x) (add-to-list 'res x 'append)) list)
-    res))
+(defsubst org-uniquify (list)
+  "Non-destructively remove duplicate elements from LIST."
+  (let ((res (copy-seq list))) (delete-dups res)))
 
 
 (defun org-uniquify-alist (alist)
 (defun org-uniquify-alist (alist)
-  "Merge duplicate elements of an alist.
+  "Merge duplicate elements of ALIST.
 
 
 For example, in this alist:
 For example, in this alist:
 
 
@@ -23029,8 +23020,8 @@ non-nil it will also look at invisible ones."
                're-search-forward))
                're-search-forward))
           (count (if arg (abs arg) 1))
           (count (if arg (abs arg) 1))
           (result (point)))
           (result (point)))
-      (forward-char (if (and arg (< arg 0)) -1 1))
-      (while (and (> count 0)
+      (while (and (prog1 (> count 0)
+		    (forward-char (if (and arg (< arg 0)) -1 1)))
                   (funcall f org-outline-regexp-bol nil 'move))
                   (funcall f org-outline-regexp-bol nil 'move))
         (let ((l (- (match-end 0) (match-beginning 0) 1)))
         (let ((l (- (match-end 0) (match-beginning 0) 1)))
           (cond ((< l level) (setq count 0))
           (cond ((< l level) (setq count 0))

+ 80 - 97
lisp/ox-html.el

@@ -112,6 +112,7 @@
 		(org-open-file (org-html-export-to-html nil s v b)))))))
 		(org-open-file (org-html-export-to-html nil s v b)))))))
   :options-alist
   :options-alist
   '((:html-extension nil nil org-html-extension)
   '((:html-extension nil nil org-html-extension)
+    (:html-link-org-as-html nil nil org-html-link-org-files-as-html)
     (:html-doctype "HTML_DOCTYPE" nil org-html-doctype)
     (:html-doctype "HTML_DOCTYPE" nil org-html-doctype)
     (:html-container "HTML_CONTAINER" nil org-html-container-element)
     (:html-container "HTML_CONTAINER" nil org-html-container-element)
     (:html-link-home "HTML_LINK_HOME" nil org-html-link-home)
     (:html-link-home "HTML_LINK_HOME" nil org-html-link-home)
@@ -123,7 +124,10 @@
     (:html-head-extra "HTML_HEAD_EXTRA" nil org-html-head-extra newline)
     (:html-head-extra "HTML_HEAD_EXTRA" nil org-html-head-extra newline)
     (:html-head-include-default-style "HTML_INCLUDE_STYLE" nil org-html-head-include-default-style newline)
     (:html-head-include-default-style "HTML_INCLUDE_STYLE" nil org-html-head-include-default-style newline)
     (:html-head-include-scripts "HTML_INCLUDE_SCRIPTS" nil org-html-head-include-scripts newline)
     (:html-head-include-scripts "HTML_INCLUDE_SCRIPTS" nil org-html-head-include-scripts newline)
-    (:html-table-tag nil nil org-html-table-tag)
+    (:html-table-attributes nil nil org-html-table-default-attributes)
+    (:html-table-row-tags nil nil org-html-table-row-tags)
+    (:html-xml-declaration nil nil org-html-xml-declaration)
+    (:html-inline-images nil nil org-html-inline-images)
     (:infojs-opt "INFOJS_OPT" nil nil)
     (:infojs-opt "INFOJS_OPT" nil nil)
     ;; Redefine regular options.
     ;; Redefine regular options.
     (:creator "CREATOR" nil org-html-creator-string)
     (:creator "CREATOR" nil org-html-creator-string)
@@ -135,10 +139,6 @@
 (defvar org-html-format-table-no-css)
 (defvar org-html-format-table-no-css)
 (defvar htmlize-buffer-places)  ; from htmlize.el
 (defvar htmlize-buffer-places)  ; from htmlize.el
 
 
-(defvar org-html--timestamp-format "%Y-%m-%d %a %H:%M"
-  "FORMAT used by `format-time-string' for timestamps in
-preamble, postamble and metadata.")
-
 (defvar org-html--pre/postamble-class "status"
 (defvar org-html--pre/postamble-class "status"
   "CSS class used for pre/postamble")
   "CSS class used for pre/postamble")
 
 
@@ -695,16 +695,9 @@ be linked only."
     ("http" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")
     ("http" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")
     ("https" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'"))
     ("https" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'"))
   "Rules characterizing image files that can be inlined into HTML.
   "Rules characterizing image files that can be inlined into HTML.
-
 A rule consists in an association whose key is the type of link
 A rule consists in an association whose key is the type of link
 to consider, and value is a regexp that will be matched against
 to consider, and value is a regexp that will be matched against
-link's path.
-
-Note that, by default, the image extension *actually* allowed
-depend on the way the HTML file is processed.  When used with
-pdflatex, pdf, jpg and png images are OK.  When processing
-through dvi to Postscript, only ps and eps are allowed.  The
-default we use here encompasses both."
+link's path."
   :group 'org-export-html
   :group 'org-export-html
   :version "24.4"
   :version "24.4"
   :package-version '(Org . "8.0")
   :package-version '(Org . "8.0")
@@ -750,13 +743,16 @@ in all modes you want.  Then, use the command
 
 
 ;;;; Table
 ;;;; Table
 
 
-(defcustom org-html-table-tag
-  "<table border=\"2\" cellspacing=\"0\" cellpadding=\"6\" rules=\"groups\" frame=\"hsides\">"
-  "The HTML tag that is used to start a table.
-This must be a <table> tag, but you may change the options like
-borders and spacing."
+(defcustom org-html-table-default-attributes
+  '(:border "2" :cellspacing "0" :cellpadding "6" :rules "groups" :frame "hsides")
+  "Default attributes and values which will be used in table tags.
+This is a plist where attributes are symbols, starting with
+colons, and values are strings."
   :group 'org-export-html
   :group 'org-export-html
-  :type 'string)
+  :version "24.4"
+  :package-version '(Org . "8.0")
+  :type '(plist :key-type (symbol :tag "Property")
+		:value-type (string :tag "Value")))
 
 
 (defcustom org-html-table-header-tags '("<th scope=\"%s\"%s>" . "</th>")
 (defcustom org-html-table-header-tags '("<th scope=\"%s\"%s>" . "</th>")
   "The opening tag for table header fields.
   "The opening tag for table header fields.
@@ -786,6 +782,7 @@ evaluated for each row in order to construct the table row tags.
 During evaluation, these variables will be dynamically bound so that
 During evaluation, these variables will be dynamically bound so that
 you can reuse them:
 you can reuse them:
 
 
+       `row-number': row number (0 is the first row)
   `rowgroup-number': group number of current row
   `rowgroup-number': group number of current row
  `start-rowgroup-p': non-nil means the row starts a group
  `start-rowgroup-p': non-nil means the row starts a group
    `end-rowgroup-p': non-nil means the row ends a group
    `end-rowgroup-p': non-nil means the row ends a group
@@ -794,11 +791,17 @@ you can reuse them:
 
 
 For example:
 For example:
 
 
-  (setq org-html-table-row-tags
-        (cons '(cond (top-row-p \"<tr class=\\\"tr-top\\\">\")
-                     (bottom-row-p \"<tr class=\\\"tr-bottom\\\">\"))))
-
-will use the \"tr-top\" and \"tr-bottom\" classes for top and bottom row."
+\(setq org-html-table-row-tags
+      (cons '(cond (top-row-p \"<tr class=\\\"tr-top\\\">\")
+                   (bottom-row-p \"<tr class=\\\"tr-bottom\\\">\")
+                   (t (if (= (mod row-number 2) 1)
+			  \"<tr class=\\\"tr-odd\\\">\"
+			\"<tr class=\\\"tr-even\\\">\")))
+	    \"</tr>\"))
+
+will use the \"tr-top\" and \"tr-bottom\" classes for the top row
+and the bottom row, and otherwise alternate between \"tr-odd\" and
+\"tr-even\" for odd and even rows."
   :group 'org-export-html
   :group 'org-export-html
   :type '(cons
   :type '(cons
 	  (choice :tag "Opening tag"
 	  (choice :tag "Opening tag"
@@ -914,6 +917,14 @@ org-info.js for your website."
 	       (list :tag "Postamble" (const :format "" postamble)
 	       (list :tag "Postamble" (const :format "" postamble)
 		     (string :tag "     id") (string :tag "element"))))
 		     (string :tag "     id") (string :tag "element"))))
 
 
+(defcustom org-html-metadata-timestamp-format "%Y-%m-%d %a %H:%M"
+  "Format used for timestamps in preamble, postamble and metadata.
+See `format-time-string' for more information on its components."
+  :group 'org-export-html
+  :version "24.4"
+  :package-version '(Org . "8.0")
+  :type 'string)
+
 ;;;; Template :: Mathjax
 ;;;; Template :: Mathjax
 
 
 (defcustom org-html-mathjax-options
 (defcustom org-html-mathjax-options
@@ -1228,6 +1239,19 @@ CSS classes, then this prefix can be very useful."
 
 
 ;;; Internal Functions
 ;;; Internal Functions
 
 
+(defun org-html--make-attribute-string (attributes)
+  "Return a list of attributes, as a string.
+ATTRIBUTES is a plist where values are either strings or nil. An
+attributes with a nil value will be omitted from the result."
+  (let (output)
+    (dolist (item attributes (mapconcat 'identity (nreverse output) " "))
+      (cond ((null item) (pop output))
+            ((symbolp item) (push (substring (symbol-name item) 1) output))
+            (t (let ((key (car output))
+                     (value (replace-regexp-in-string
+                             "\"" "&quot;" (org-html-encode-plain-text item))))
+                 (setcar output (format "%s=\"%s\"" key value))))))))
+
 (defun org-html-format-inline-image (src &optional
 (defun org-html-format-inline-image (src &optional
 					 caption label attr standalone-p)
 					 caption label attr standalone-p)
   "Format an inline image from SRC.
   "Format an inline image from SRC.
@@ -1287,32 +1311,6 @@ ELEMENT is either a src block or an example block."
 
 
 ;;;; Table
 ;;;; Table
 
 
-(defun org-html-splice-attributes (tag attributes)
-  "Return a HTML TAG edited wrt ATTRIBUTES."
-  (if (not attributes)
-      tag
-    (let (oldatt newatt)
-      (setq oldatt (org-extract-attributes-from-string tag)
-	    tag (pop oldatt)
-	    newatt (cdr (org-extract-attributes-from-string attributes)))
-      (while newatt
-	(setq oldatt (plist-put oldatt (pop newatt) (pop newatt))))
-      (if (string-match ">" tag)
-	  (setq tag
-		(replace-match (concat (org-attributes-to-string oldatt) ">")
-			       t t tag)))
-      tag)))
-
-(defun org-export-splice-style (style extra)
-  "Return STYLE updated wrt EXTRA."
-  (if (and (stringp extra)
-	   (string-match "\\S-" extra)
-	   (string-match "</style>" style))
-      (concat (substring style 0 (match-beginning 0))
-	      "\n" extra "\n"
-	      (substring style (match-beginning 0)))
-    style))
-
 (defun org-html-htmlize-region-for-paste (beg end)
 (defun org-html-htmlize-region-for-paste (beg end)
   "Convert the region between BEG and END to HTML, using htmlize.el.
   "Convert the region between BEG and END to HTML, using htmlize.el.
 This is much like `htmlize-region-for-paste', only that it uses
 This is much like `htmlize-region-for-paste', only that it uses
@@ -1434,7 +1432,7 @@ INFO is a plist used as a communication channel."
      (format
      (format
       (when :time-stamp-file
       (when :time-stamp-file
 	(format-time-string
 	(format-time-string
-	 (concat "<!-- " org-html--timestamp-format " -->\n"))))
+	 (concat "<!-- " org-html-metadata-timestamp-format " -->\n"))))
      (format
      (format
       "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=%s\"/>\n"
       "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=%s\"/>\n"
       (or (and org-html-coding-system
       (or (and org-html-coding-system
@@ -1502,7 +1500,7 @@ INFO is a plist used as a communication channel."
 used in the preamble or postamble."
 used in the preamble or postamble."
   `((?t . ,(org-export-data (plist-get info :title) info))
   `((?t . ,(org-export-data (plist-get info :title) info))
     (?d . ,(org-export-data (org-export-get-date info) info))
     (?d . ,(org-export-data (org-export-get-date info) info))
-    (?T . ,(format-time-string org-html--timestamp-format))
+    (?T . ,(format-time-string org-html-metadata-timestamp-format))
     (?a . ,(org-export-data (plist-get info :author) info))
     (?a . ,(org-export-data (plist-get info :author) info))
     (?e . ,(mapconcat
     (?e . ,(mapconcat
 	    (lambda (e)
 	    (lambda (e)
@@ -1511,7 +1509,7 @@ used in the preamble or postamble."
 	    ", "))
 	    ", "))
     (?c . ,(plist-get info :creator))
     (?c . ,(plist-get info :creator))
     (?C . ,(let ((file (plist-get info :input-file)))
     (?C . ,(let ((file (plist-get info :input-file)))
-	     (format-time-string org-html--timestamp-format
+	     (format-time-string org-html-metadata-timestamp-format
 				 (if file (nth 5 (file-attributes file))
 				 (if file (nth 5 (file-attributes file))
 				   (current-time)))))
 				   (current-time)))))
     (?v . ,(or org-html-validation-link ""))))
     (?v . ,(or org-html-validation-link ""))))
@@ -1554,10 +1552,9 @@ communication channel."
 		      (format
 		      (format
 		       "<p class=\"date\">%s: %s</p>\n"
 		       "<p class=\"date\">%s: %s</p>\n"
 		       (org-html--translate "Created" info)
 		       (org-html--translate "Created" info)
-		       (format-time-string org-html--timestamp-format)))
+		       (format-time-string org-html-metadata-timestamp-format)))
 		    (when (plist-get info :with-creator)
 		    (when (plist-get info :with-creator)
-		      (format "<p class=\"creator\">%s</p>\n"
-			      creator))
+		      (format "<p class=\"creator\">%s</p>\n" creator))
 		    (format "<p class=\"xhtml-validation\">%s</p>\n"
 		    (format "<p class=\"xhtml-validation\">%s</p>\n"
 			    validation-link))))
 			    validation-link))))
 		(t (format-spec
 		(t (format-spec
@@ -2194,7 +2191,7 @@ holding contextual information."
 		  "div")
 		  "div")
 		(format "outline-container-%s"
 		(format "outline-container-%s"
 			(or (org-element-property :CUSTOM_ID headline)
 			(or (org-element-property :CUSTOM_ID headline)
-			    section-number))
+			    (concat "sec-" section-number)))
 		(concat (format "outline-%d" level1) (and extra-class " ")
 		(concat (format "outline-%d" level1) (and extra-class " ")
 			extra-class)
 			extra-class)
 		(format "\n<h%d id=\"%s\">%s%s</h%d>\n"
 		(format "\n<h%d id=\"%s\">%s%s</h%d>\n"
@@ -2418,6 +2415,7 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 
 
 (defun org-html-link--inline-image (link desc info)
 (defun org-html-link--inline-image (link desc info)
   "Return HTML code for an inline image.
   "Return HTML code for an inline image.
+
 LINK is the link pointing to the inline image.  INFO is a plist
 LINK is the link pointing to the inline image.  INFO is a plist
 used as a communication channel.
 used as a communication channel.
 
 
@@ -2433,20 +2431,12 @@ Inline images can have these attributes:
 		     (t raw-path)))
 		     (t raw-path)))
 	 (parent (org-export-get-parent-element link))
 	 (parent (org-export-get-parent-element link))
 	 (caption (org-export-data (org-export-get-caption parent) info))
 	 (caption (org-export-data (org-export-get-caption parent) info))
-	 (label (org-element-property :name parent))
-	 (attrs (org-export-read-attribute :attr_html parent))
-	 (alt (plist-get attrs :alt))
-	 (width (plist-get attrs :width))
-	 (height (plist-get attrs :height))
-	 (options (plist-get attrs :options)))
+	 (label (org-element-property :name parent)))
     ;; Return proper string, depending on DISPOSITION.
     ;; Return proper string, depending on DISPOSITION.
     (org-html-format-inline-image
     (org-html-format-inline-image
      path caption label
      path caption label
-     (mapconcat 'identity
-		(delq nil (list (if width (format "width=\"%s\"" width))
-				(if alt (format "alt=\"%s\"" alt))
-				(if height (format "height=\"%s\"" height))
-				options)) " ")
+     (org-html--make-attribute-string
+      (org-export-read-attribute :attr_html parent))
      (org-html-standalone-image-p link info))))
      (org-html-standalone-image-p link info))))
 
 
 (defvar org-html-standalone-image-predicate)
 (defvar org-html-standalone-image-predicate)
@@ -2547,20 +2537,19 @@ INFO is a plist holding contextual information.  See
 							numbers "-"))))))
 							numbers "-"))))))
 		    (t raw-path))))
 		    (t raw-path))))
 	   (t raw-path)))
 	   (t raw-path)))
-	 attributes protocol)
-    ;; Extract attributes from parent's paragraph. HACK: Only do this
-    ;; for the first link in parent.  This is needed as long as
-    ;; attributes cannot be set on a per link basis.
-    (and (setq attributes
-	       (let ((parent (org-export-get-parent-element link)))
-		 (if (not (eq (org-element-map parent 'link 'identity info t)
-			      link))
-		     ""
-		    (let ((att (org-export-read-attribute :attr_html parent :options)))
-		      (unless (and desc att (string-match (regexp-quote att) desc))
-			(or att ""))))))
-	 (unless (string= attributes "")
-	   (setq attributes (concat " " attributes))))
+	 ;; Extract attributes from parent's paragraph. HACK: Only do
+	 ;; this for the first link in parent.  This is needed as long
+	 ;; as attributes cannot be set on a per link basis.
+	 (attributes
+	  (let ((parent (org-export-get-parent-element link)))
+	    (if (not (eq (org-element-map parent 'link 'identity info t) link))
+		""
+	      (let ((att (org-html--make-attribute-string
+			  (org-export-read-attribute :attr_html parent))))
+		(cond ((not (org-string-nw-p att)) "")
+		      ((and desc (string-match (regexp-quote att) desc)) "")
+		      (t (concat " " att)))))))
+	 protocol)
     (cond
     (cond
      ;; Image file.
      ;; Image file.
      ((and (or (eq t org-html-inline-images)
      ((and (or (eq t org-html-inline-images)
@@ -2964,6 +2953,7 @@ communication channel."
   ;; borders of the current row.
   ;; borders of the current row.
   (when (eq (org-element-property :type table-row) 'standard)
   (when (eq (org-element-property :type table-row) 'standard)
     (let* ((rowgroup-number (org-export-table-row-group table-row info))
     (let* ((rowgroup-number (org-export-table-row-group table-row info))
+	   (row-number (org-export-table-row-number table-row info))
 	   (start-rowgroup-p
 	   (start-rowgroup-p
 	    (org-export-table-row-starts-rowgroup-p table-row info))
 	    (org-export-table-row-starts-rowgroup-p table-row info))
 	   (end-rowgroup-p
 	   (end-rowgroup-p
@@ -3040,7 +3030,11 @@ contextual information."
      (let* ((label (org-element-property :name table))
      (let* ((label (org-element-property :name table))
 	    (caption (org-export-get-caption table))
 	    (caption (org-export-get-caption table))
 	    (attributes
 	    (attributes
-	     (org-export-read-attribute :attr_html table :options))
+	     (org-html--make-attribute-string
+	      (org-combine-plists
+	       (and label (list :id (org-export-solidify-link-text label)))
+	       (plist-get info :html-table-attributes)
+	       (org-export-read-attribute :attr_html table))))
 	    (alignspec
 	    (alignspec
 	     (if (and (boundp 'org-html-format-table-no-css)
 	     (if (and (boundp 'org-html-format-table-no-css)
 		      org-html-format-table-no-css)
 		      org-html-format-table-no-css)
@@ -3063,20 +3057,9 @@ contextual information."
 		      (when (org-export-table-cell-ends-colgroup-p
 		      (when (org-export-table-cell-ends-colgroup-p
 			     table-cell info)
 			     table-cell info)
 			"\n</colgroup>"))))
 			"\n</colgroup>"))))
-		 (org-html-table-first-row-data-cells table info) "\n"))))
-	    (table-attributes
-	     (let ((table-tag (plist-get info :html-table-tag)))
-	       (concat
-		(and (string-match  "<table\\(.*\\)>" table-tag)
-		     (match-string 1 table-tag))
-		(and label (format " id=\"%s\""
-				   (org-export-solidify-link-text label)))
-		(unless (string= attributes "")
-		  (concat " " attributes))))))
-       ;; Remove last blank line.
-       (setq contents (substring contents 0 -1))
-       (format "<table%s>\n%s\n%s\n%s\n</table>"
-	       table-attributes
+		 (org-html-table-first-row-data-cells table info) "\n")))))
+       (format "<table%s>\n%s\n%s\n%s</table>"
+	       (if (equal attributes "") "" (concat " " attributes))
 	       (if (not caption) ""
 	       (if (not caption) ""
 		 (format "<caption>%s</caption>"
 		 (format "<caption>%s</caption>"
 			 (org-export-data caption info)))
 			 (org-export-data caption info)))

+ 3 - 2
lisp/ox-icalendar.el

@@ -897,7 +897,8 @@ The file is stored under the name chosen in
   "Export current agenda view to an iCalendar FILE.
   "Export current agenda view to an iCalendar FILE.
 This function assumes major mode for current buffer is
 This function assumes major mode for current buffer is
 `org-agenda-mode'."
 `org-agenda-mode'."
-  (let ((org-icalendar-combined-agenda-file file)
+  (let (org-export-babel-evaluate ; Don't evaluate Babel block
+	(org-icalendar-combined-agenda-file file)
 	(marker-list
 	(marker-list
 	 ;; Collect the markers pointing to entries in the current
 	 ;; Collect the markers pointing to entries in the current
 	 ;; agenda buffer.
 	 ;; agenda buffer.
@@ -971,7 +972,7 @@ files to build the calendar from."
 				      (lambda (m-list dummy)
 				      (lambda (m-list dummy)
 					(mapc (lambda (m)
 					(mapc (lambda (m)
 						(org-entry-put
 						(org-entry-put
-						 m "ICALENDAR_MARK" "t"))
+						 m "ICALENDAR-MARK" "t"))
 					      m-list))
 					      m-list))
 				      (sort marks '>))
 				      (sort marks '>))
 				     org-export-before-processing-hook)))
 				     org-export-before-processing-hook)))

+ 15 - 15
lisp/ox-latex.el

@@ -294,13 +294,13 @@
      ("\\subsection{%s}" . "\\subsection*{%s}")
      ("\\subsection{%s}" . "\\subsection*{%s}")
      ("\\subsubsection{%s}" . "\\subsubsection*{%s}")))
      ("\\subsubsection{%s}" . "\\subsubsection*{%s}")))
   "Alist of LaTeX classes and associated header and structure.
   "Alist of LaTeX classes and associated header and structure.
-If #+LaTeX_CLASS is set in the buffer, use its value and the
+If #+LATEX_CLASS is set in the buffer, use its value and the
 associated information.  Here is the structure of each cell:
 associated information.  Here is the structure of each cell:
 
 
   \(class-name
   \(class-name
     header-string
     header-string
-    \(numbered-section . unnumbered-section\)
-    ...\)
+    \(numbered-section . unnumbered-section)
+    ...)
 
 
 The header string
 The header string
 -----------------
 -----------------
@@ -315,7 +315,8 @@ following commands will be added:
   `org-latex-packages-alist'.  Thus, your header definitions
   `org-latex-packages-alist'.  Thus, your header definitions
   should avoid to also request these packages.
   should avoid to also request these packages.
 
 
-- Lines specified via \"#+LaTeX_HEADER:\"
+- Lines specified via \"#+LATEX_HEADER:\" and
+  \"#+LATEX_HEADER_EXTRA:\" keywords.
 
 
 If you need more control about the sequence in which the header
 If you need more control about the sequence in which the header
 is built up, or if you want to exclude one of these building
 is built up, or if you want to exclude one of these building
@@ -326,8 +327,8 @@ macro-like placeholders.
  [NO-DEFAULT-PACKAGES]   do not include any of the default packages
  [NO-DEFAULT-PACKAGES]   do not include any of the default packages
  [PACKAGES]              \\usepackage statements for packages
  [PACKAGES]              \\usepackage statements for packages
  [NO-PACKAGES]           do not include the packages
  [NO-PACKAGES]           do not include the packages
- [EXTRA]                 the stuff from #+LaTeX_HEADER
- [NO-EXTRA]              do not include #+LaTeX_HEADER stuff
+ [EXTRA]                 the stuff from #+LATEX_HEADER
+ [NO-EXTRA]              do not include #+LATEX_HEADER stuff
 
 
 So a header like
 So a header like
 
 
@@ -338,9 +339,9 @@ So a header like
   [PACKAGES]
   [PACKAGES]
 
 
 will omit the default packages, and will include the
 will omit the default packages, and will include the
-#+LaTeX_HEADER lines, then have a call to \\providecommand, and
-then place \\usepackage commands based on the content of
-`org-latex-packages-alist'.
+#+LATEX_HEADER and #+LATEX_HEADER_EXTRA lines, then have a call
+to \\providecommand, and then place \\usepackage commands based
+on the content of `org-latex-packages-alist'.
 
 
 If your header, `org-latex-default-packages-alist' or
 If your header, `org-latex-default-packages-alist' or
 `org-latex-packages-alist' inserts
 `org-latex-packages-alist' inserts
@@ -357,14 +358,14 @@ following the header string.  For each sectioning level, a number
 of strings is specified.  A %s formatter is mandatory in each
 of strings is specified.  A %s formatter is mandatory in each
 section string and will be replaced by the title of the section.
 section string and will be replaced by the title of the section.
 
 
-Instead of a cons cell \(numbered . unnumbered\), you can also
+Instead of a cons cell (numbered . unnumbered), you can also
 provide a list of 2 or 4 elements,
 provide a list of 2 or 4 elements,
 
 
-  \(numbered-open numbered-close\)
+  \(numbered-open numbered-close)
 
 
 or
 or
 
 
-  \(numbered-open numbered-close unnumbered-open unnumbered-close\)
+  \(numbered-open numbered-close unnumbered-open unnumbered-close)
 
 
 providing opening and closing strings for a LaTeX environment
 providing opening and closing strings for a LaTeX environment
 that should represent the document section.  The opening clause
 that should represent the document section.  The opening clause
@@ -372,7 +373,7 @@ should have a %s to represent the section title.
 
 
 Instead of a list of sectioning commands, you can also specify
 Instead of a list of sectioning commands, you can also specify
 a function name.  That function will be called with two
 a function name.  That function will be called with two
-parameters, the \(reduced) level of the headline, and a predicate
+parameters, the (reduced) level of the headline, and a predicate
 non-nil when the headline should be numbered.  It must return
 non-nil when the headline should be numbered.  It must return
 a format string in which the section title will be added."
 a format string in which the section title will be added."
   :group 'org-export-latex
   :group 'org-export-latex
@@ -1814,7 +1815,6 @@ used as a communication channel."
 	 ;; ATTR_LATEX line, and also via default variables.
 	 ;; ATTR_LATEX line, and also via default variables.
 	 (width (cond ((plist-get attr :width))
 	 (width (cond ((plist-get attr :width))
 		      ((plist-get attr :height) "")
 		      ((plist-get attr :height) "")
-		      ((eq float 'figure) "0.7\\textwidth")
 		      ((eq float 'wrap) "0.48\\textwidth")
 		      ((eq float 'wrap) "0.48\\textwidth")
 		      (t org-latex-image-default-width)))
 		      (t org-latex-image-default-width)))
 	 (height (cond ((plist-get attr :height))
 	 (height (cond ((plist-get attr :height))
@@ -2561,7 +2561,7 @@ This function assumes TABLE has `org' as its `:type' property and
 `inline-math' or `math' as its `:mode' attribute.."
 `inline-math' or `math' as its `:mode' attribute.."
   (let* ((caption (org-latex--caption/label-string table info))
   (let* ((caption (org-latex--caption/label-string table info))
 	 (attr (org-export-read-attribute :attr_latex table))
 	 (attr (org-export-read-attribute :attr_latex table))
-	 (inlinep (eq (plist-get attr :mode) 'inline-math))
+	 (inlinep (equal (plist-get attr :mode) "inline-math"))
 	 (env (or (plist-get attr :environment)
 	 (env (or (plist-get attr :environment)
 		  org-latex-default-table-environment))
 		  org-latex-default-table-environment))
 	 (contents
 	 (contents

+ 2 - 0
lisp/ox-odt.el

@@ -2760,6 +2760,8 @@ INFO is a plist holding contextual information.  See
 		     (concat "file://" (expand-file-name raw-path))
 		     (concat "file://" (expand-file-name raw-path))
 		   (concat "file://" raw-path)))
 		   (concat "file://" raw-path)))
 		(t raw-path)))
 		(t raw-path)))
+	 ;; Convert & to &amp; for correct XML representation
+	 (path (replace-regexp-in-string "&" "&amp;" path))
 	 protocol)
 	 protocol)
     (cond
     (cond
      ;; Image file.
      ;; Image file.

+ 1 - 0
lisp/ox-publish.el

@@ -179,6 +179,7 @@ included.  See the back-end documentation for more information.
   :with-tags                `org-export-with-tags'
   :with-tags                `org-export-with-tags'
   :with-tasks               `org-export-with-tasks'
   :with-tasks               `org-export-with-tasks'
   :with-timestamps          `org-export-with-timestamps'
   :with-timestamps          `org-export-with-timestamps'
+  :with-planning            `org-export-with-planning'
   :with-todo-keywords       `org-export-with-todo-keywords'
   :with-todo-keywords       `org-export-with-todo-keywords'
 
 
 The following properties may be used to control publishing of
 The following properties may be used to control publishing of

+ 44 - 28
lisp/ox.el

@@ -131,7 +131,7 @@
     (:with-footnotes nil "f" org-export-with-footnotes)
     (:with-footnotes nil "f" org-export-with-footnotes)
     (:with-inlinetasks nil "inline" org-export-with-inlinetasks)
     (:with-inlinetasks nil "inline" org-export-with-inlinetasks)
     (:with-latex nil "tex" org-export-with-latex)
     (:with-latex nil "tex" org-export-with-latex)
-    (:with-plannings nil "p" org-export-with-planning)
+    (:with-planning nil "p" org-export-with-planning)
     (:with-priority nil "pri" org-export-with-priority)
     (:with-priority nil "pri" org-export-with-priority)
     (:with-smart-quotes nil "'" org-export-with-smart-quotes)
     (:with-smart-quotes nil "'" org-export-with-smart-quotes)
     (:with-special-strings nil "-" org-export-with-special-strings)
     (:with-special-strings nil "-" org-export-with-special-strings)
@@ -1345,7 +1345,7 @@ The back-end could then be called with, for example:
 ;;   - category :: option
 ;;   - category :: option
 ;;   - type :: symbol (`verbatim', nil, t)
 ;;   - type :: symbol (`verbatim', nil, t)
 ;;
 ;;
-;; + `:with-plannings' :: Non-nil means transcoding should include
+;; + `:with-planning' :: Non-nil means transcoding should include
 ;;      planning info.
 ;;      planning info.
 ;;   - category :: option
 ;;   - category :: option
 ;;   - type :: symbol (nil, t)
 ;;   - type :: symbol (nil, t)
@@ -2005,7 +2005,7 @@ a tree with a select tag."
 		      (not (eq todo-type with-tasks)))
 		      (not (eq todo-type with-tasks)))
 		 (and (consp with-tasks) (not (member todo with-tasks))))))))
 		 (and (consp with-tasks) (not (member todo with-tasks))))))))
     ((latex-environment latex-fragment) (not (plist-get options :with-latex)))
     ((latex-environment latex-fragment) (not (plist-get options :with-latex)))
-    (planning (not (plist-get options :with-plannings)))
+    (planning (not (plist-get options :with-planning)))
     (statistics-cookie (not (plist-get options :with-statistics-cookies)))
     (statistics-cookie (not (plist-get options :with-statistics-cookies)))
     (table-cell
     (table-cell
      (and (org-export-table-has-special-column-p
      (and (org-export-table-has-special-column-p
@@ -3423,24 +3423,31 @@ that property within attributes.
 
 
 This function assumes attributes are defined as \":keyword
 This function assumes attributes are defined as \":keyword
 value\" pairs.  It is appropriate for `:attr_html' like
 value\" pairs.  It is appropriate for `:attr_html' like
-properties.  All values will become strings except the empty
-string and \"nil\", which will become nil."
-  (let ((attributes
-	 (let ((value (org-element-property attribute element)))
-	   (when value
-	     (let ((s (mapconcat 'identity value " ")) result)
-	       (while (string-match
-		       "\\(?:^\\|[ \t]+\\)\\(:[-a-zA-Z0-9_]+\\)\\([ \t]+\\|$\\)"
-		       s)
-		 (let ((value (substring s 0 (match-beginning 0))))
-		   (push (and (not (member value '("nil" ""))) value) result))
-		 (push (intern (match-string 1 s)) result)
-		 (setq s (substring s (match-end 0))))
-	       ;; Ignore any string before the first property with `cdr'.
-	       (cdr (nreverse (cons (and (org-string-nw-p s)
-					 (not (equal s "nil"))
-					 s)
-				    result))))))))
+properties.
+
+All values will become strings except the empty string and
+\"nil\", which will become nil.  Also, values containing only
+double quotes will be read as-is, which means that \"\" value
+will become the empty string."
+  (let* ((prepare-value
+	  (lambda (str)
+	    (cond ((member str '(nil "" "nil")) nil)
+		  ((string-match "^\"\\(\"+\\)?\"$" str)
+		   (or (match-string 1 str) ""))
+		  (t str))))
+	 (attributes
+	  (let ((value (org-element-property attribute element)))
+	    (when value
+	      (let ((s (mapconcat 'identity value " ")) result)
+		(while (string-match
+			"\\(?:^\\|[ \t]+\\)\\(:[-a-zA-Z0-9_]+\\)\\([ \t]+\\|$\\)"
+			s)
+		  (let ((value (substring s 0 (match-beginning 0))))
+		    (push (funcall prepare-value value) result))
+		  (push (intern (match-string 1 s)) result)
+		  (setq s (substring s (match-end 0))))
+		;; Ignore any string before first property with `cdr'.
+		(cdr (nreverse (cons (funcall prepare-value s) result))))))))
     (if property (plist-get attributes property) attributes)))
     (if property (plist-get attributes property) attributes)))
 
 
 (defun org-export-get-caption (element &optional shortp)
 (defun org-export-get-caption (element &optional shortp)
@@ -4640,6 +4647,21 @@ INFO is a plist used as a communication channel."
        (org-export-table-row-ends-rowgroup-p table-row info)
        (org-export-table-row-ends-rowgroup-p table-row info)
        (= (org-export-table-row-group table-row info) 1)))
        (= (org-export-table-row-group table-row info) 1)))
 
 
+(defun org-export-table-row-number (table-row info)
+  "Return TABLE-ROW number.
+INFO is a plist used as a communication channel.  Return value is
+zero-based and ignores separators.  The function returns nil for
+special colums and separators."
+  (when (and (eq (org-element-property :type table-row) 'standard)
+	     (not (org-export-table-row-is-special-p table-row info)))
+    (let ((number 0))
+      (org-element-map (org-export-get-parent-table table-row) 'table-row
+	(lambda (row)
+	  (cond ((eq row table-row) number)
+		((eq (org-element-property :type row) 'standard)
+		 (incf number) nil)))
+	info 'first-match))))
+
 (defun org-export-table-dimensions (table info)
 (defun org-export-table-dimensions (table info)
   "Return TABLE dimensions.
   "Return TABLE dimensions.
 
 
@@ -4677,13 +4699,7 @@ function returns nil for other cells."
 		     (eq (car (org-element-contents table-row)) table-cell)))
 		     (eq (car (org-element-contents table-row)) table-cell)))
       (cons
       (cons
        ;; Row number.
        ;; Row number.
-       (let ((row-count 0))
-	 (org-element-map table 'table-row
-	   (lambda (row)
-	     (cond ((eq (org-element-property :type row) 'rule) nil)
-		   ((eq row table-row) row-count)
-		   (t (incf row-count) nil)))
-	   info 'first-match))
+       (org-export-table-row-number (org-export-get-parent table-cell) info)
        ;; Column number.
        ;; Column number.
        (let ((col-count 0))
        (let ((col-count 0))
 	 (org-element-map table-row 'table-cell
 	 (org-element-map table-row 'table-cell

+ 37 - 23
testing/lisp/test-org-table.el

@@ -339,7 +339,7 @@ reference (with row).  No format specifier."
 | 0 | 1 | 0 | #ERROR | #ERROR | #ERROR | 2 | 2 |
 | 0 | 1 | 0 | #ERROR | #ERROR | #ERROR | 2 | 2 |
 | z | 1 | z | #ERROR | #ERROR | #ERROR | 2 | 2 |
 | z | 1 | z | #ERROR | #ERROR | #ERROR | 2 | 2 |
 |   | 1 |   | #ERROR | #ERROR | #ERROR | 1 | 1 |
 |   | 1 |   | #ERROR | #ERROR | #ERROR | 1 | 1 |
-|   |   |   | #ERROR | #ERROR | #ERROR | 1 | 1 |
+|   |   |   | #ERROR | 0      | 0      | 0 | 0 |
 "
 "
      1 lisp)
      1 lisp)
     (org-test-table-target-expect
     (org-test-table-target-expect
@@ -348,7 +348,7 @@ reference (with row).  No format specifier."
 | 0 | 1 | 0 |     1 |     1 |     1 | 2 | 2 |
 | 0 | 1 | 0 |     1 |     1 |     1 | 2 | 2 |
 | z | 1 | z | z + 1 | z + 1 | z + 1 | 2 | 2 |
 | z | 1 | z | z + 1 | z + 1 | z + 1 | 2 | 2 |
 |   | 1 | 0 |     1 |     1 |     1 | 1 | 1 |
 |   | 1 | 0 |     1 |     1 |     1 | 1 | 1 |
-|   |   | 0 |     0 |     0 |     0 | 1 | 1 |
+|   |   | 0 |     0 |     0 |     0 | 0 | 0 |
 "
 "
      1 calc)
      1 calc)
     (org-test-table-target-expect
     (org-test-table-target-expect
@@ -381,7 +381,7 @@ reference (with row).  Format specifier N."
 | 0 | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
 | 0 | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
 | z | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
 | z | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
 |   | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
 |   | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
-|   |   | 0 | 0 | 0 | 0 | 1 | 1 |
+|   |   | 0 | 0 | 0 | 0 | 0 | 0 |
 "
 "
      1 lisp calc)
      1 lisp calc)
     (org-test-table-target-expect
     (org-test-table-target-expect
@@ -455,20 +455,34 @@ reference (with row).  Format specifier N."
   ;; Empty fields in simple and complex range reference: Suppress them
   ;; Empty fields in simple and complex range reference: Suppress them
   ;; ($5 and $6) or keep them and use 0 ($7 and $8)
   ;; ($5 and $6) or keep them and use 0 ($7 and $8)
 
 
-  (org-test-table-target-expect
-   "\n|   |   | 5 | 7 | replace | replace | replace | replace |\n"
-   "\n|   |   | 5 | 7 | 6 | 6 | 3 | 3 |\n"
-   1
-   ;; Calc formula
-   (concat "#+TBLFM: "
-	   "$5 = vmean($1..$4)     :: $6 = vmean(@0$1..@0$4) :: "
-	   "$7 = vmean($1..$4); EN :: $8 = vmean(@0$1..@0$4); EN")
-   ;; Lisp formula
-   (concat "#+TBLFM: "
-	   "$5 = '(/ (+   $1..$4  ) (length '(  $1..$4  )));  N :: "
-	   "$6 = '(/ (+ @0$1..@0$4) (length '(@0$1..@0$4)));  N :: "
-	   "$7 = '(/ (+   $1..$4  ) (length '(  $1..$4  ))); EN :: "
-	   "$8 = '(/ (+ @0$1..@0$4) (length '(@0$1..@0$4))); EN"))
+  (let ((calc (concat
+	       "#+TBLFM: "
+	       "$5 = vmean($1..$4)     :: "
+	       "$6 = vmean(@0$1..@0$4) :: "
+	       "$7 = vmean($1..$4); EN :: "
+	       "$8 = vmean(@0$1..@0$4); EN"))
+	(lisp (concat
+	       "#+TBLFM: "
+	       "$5 = '(/ (+   $1..$4  ) (length '(  $1..$4  )));  N :: "
+	       "$6 = '(/ (+ @0$1..@0$4) (length '(@0$1..@0$4)));  N :: "
+	       "$7 = '(/ (+   $1..$4  ) (length '(  $1..$4  ))); EN :: "
+	       "$8 = '(/ (+ @0$1..@0$4) (length '(@0$1..@0$4))); EN")))
+    (org-test-table-target-expect
+     "\n|   |   | 5 | 7 | replace | replace | replace | replace |\n"
+     "\n|   |   | 5 | 7 | 6 | 6 | 3 | 3 |\n"
+     1 calc lisp)
+
+    ;; The mean value of a range with only empty fields is not defined
+    (let ((target
+	   "\n|   |   |   |   | replace | replace | replace | replace |\n"))
+      (org-test-table-target-expect
+       target
+       "\n|   |   |   |   | vmean([]) | vmean([]) | 0 | 0 |\n"
+       1 calc)
+      (org-test-table-target-expect
+       target
+       "\n|   |   |   |   | #ERROR | #ERROR | 0 | 0 |\n"
+       1 lisp)))
 
 
   ;; Test if one field is empty, else do a calculation
   ;; Test if one field is empty, else do a calculation
   (org-test-table-target-expect
   (org-test-table-target-expect
@@ -667,11 +681,11 @@ reference (with row).  Format specifier N."
   ;; For Lisp formula
   ;; For Lisp formula
   (should (equal "\"0\""       (f   "0"         nil nil t)))
   (should (equal "\"0\""       (f   "0"         nil nil t)))
   (should (equal "\"z\""       (f   "z"         nil nil t)))
   (should (equal "\"z\""       (f   "z"         nil nil t)))
-  (should (equal  "\"\""       (f   ""          nil nil t)))
+  (should (equal   ""          (f   ""          nil nil t)))
   (should (equal "\"0\" \"1\"" (f '("0"    "1") nil nil t)))
   (should (equal "\"0\" \"1\"" (f '("0"    "1") nil nil t)))
   (should (equal "\"z\" \"1\"" (f '("z"    "1") nil nil t)))
   (should (equal "\"z\" \"1\"" (f '("z"    "1") nil nil t)))
   (should (equal       "\"1\"" (f '(""     "1") nil nil t)))
   (should (equal       "\"1\"" (f '(""     "1") nil nil t)))
-  (should (equal    "\"\""     (f '(""     "" ) nil nil t)))
+  (should (equal      ""       (f '(""     "" ) nil nil t)))
   ;; For Calc formula
   ;; For Calc formula
   (should (equal  "(0)"        (f   "0"         nil nil nil)))
   (should (equal  "(0)"        (f   "0"         nil nil nil)))
   (should (equal  "(z)"        (f   "z"         nil nil nil)))
   (should (equal  "(z)"        (f   "z"         nil nil nil)))
@@ -679,7 +693,7 @@ reference (with row).  Format specifier N."
   (should (equal  "[0,1]"      (f '("0"    "1") nil nil nil)))
   (should (equal  "[0,1]"      (f '("0"    "1") nil nil nil)))
   (should (equal  "[z,1]"      (f '("z"    "1") nil nil nil)))
   (should (equal  "[z,1]"      (f '("z"    "1") nil nil nil)))
   (should (equal    "[1]"      (f '(""     "1") nil nil nil)))
   (should (equal    "[1]"      (f '(""     "1") nil nil nil)))
-  (should (equal   "[0]"       (f '(""     "" ) nil nil nil)))
+  (should (equal   "[]"        (f '(""     "" ) nil nil nil)))
   ;; For Calc formula, special numbers
   ;; For Calc formula, special numbers
   (should (equal  "(nan)"      (f    "nan"      nil nil nil)))
   (should (equal  "(nan)"      (f    "nan"      nil nil nil)))
   (should (equal "(uinf)"      (f   "uinf"      nil nil nil)))
   (should (equal "(uinf)"      (f   "uinf"      nil nil nil)))
@@ -695,11 +709,11 @@ reference (with row).  Format specifier N."
   ;; For Lisp formula
   ;; For Lisp formula
   (should (equal  "0"    (f   "0"         nil t t)))
   (should (equal  "0"    (f   "0"         nil t t)))
   (should (equal  "0"    (f   "z"         nil t t)))
   (should (equal  "0"    (f   "z"         nil t t)))
-  (should (equal  "0"    (f   ""          nil t t)))
+  (should (equal  ""     (f   ""          nil t t)))
   (should (equal  "0 1"  (f '("0"    "1") nil t t)))
   (should (equal  "0 1"  (f '("0"    "1") nil t t)))
   (should (equal  "0 1"  (f '("z"    "1") nil t t)))
   (should (equal  "0 1"  (f '("z"    "1") nil t t)))
   (should (equal    "1"  (f '(""     "1") nil t t)))
   (should (equal    "1"  (f '(""     "1") nil t t)))
-  (should (equal   "0"   (f '(""     "" ) nil t t)))
+  (should (equal   ""    (f '(""     "" ) nil t t)))
   ;; For Calc formula
   ;; For Calc formula
   (should (equal "(0)"   (f   "0"         nil t nil)))
   (should (equal "(0)"   (f   "0"         nil t nil)))
   (should (equal "(0)"   (f   "z"         nil t nil)))
   (should (equal "(0)"   (f   "z"         nil t nil)))
@@ -707,7 +721,7 @@ reference (with row).  Format specifier N."
   (should (equal "[0,1]" (f '("0"    "1") nil t nil)))
   (should (equal "[0,1]" (f '("0"    "1") nil t nil)))
   (should (equal "[0,1]" (f '("z"    "1") nil t nil)))
   (should (equal "[0,1]" (f '("z"    "1") nil t nil)))
   (should (equal   "[1]" (f '(""     "1") nil t nil)))
   (should (equal   "[1]" (f '(""     "1") nil t nil)))
-  (should (equal  "[0]"  (f '(""     "" ) nil t nil)))
+  (should (equal  "[]"   (f '(""     "" ) nil t nil)))
   ;; For Calc formula, special numbers
   ;; For Calc formula, special numbers
   (should (equal "(0)"   (f    "nan"      nil t nil)))
   (should (equal "(0)"   (f    "nan"      nil t nil)))
   (should (equal "(0)"   (f   "uinf"      nil t nil)))
   (should (equal "(0)"   (f   "uinf"      nil t nil)))

+ 45 - 2
testing/lisp/test-ox.el

@@ -383,10 +383,10 @@ Paragraph"
     (org-test-with-temp-text "CLOSED: [2012-04-29 sun. 10:45]"
     (org-test-with-temp-text "CLOSED: [2012-04-29 sun. 10:45]"
       (org-test-with-backend test
       (org-test-with-backend test
 	(should
 	(should
-	 (equal (org-export-as 'test nil nil nil '(:with-plannings t))
+	 (equal (org-export-as 'test nil nil nil '(:with-planning t))
 		"CLOSED: [2012-04-29 sun. 10:45]\n"))
 		"CLOSED: [2012-04-29 sun. 10:45]\n"))
 	(should
 	(should
-	 (equal (org-export-as 'test nil nil nil '(:with-plannings nil))
+	 (equal (org-export-as 'test nil nil nil '(:with-planning nil))
 		"")))))
 		"")))))
   ;; Statistics cookies.
   ;; Statistics cookies.
   (should
   (should
@@ -687,6 +687,20 @@ body\n")))
 	   :attr_html
 	   :attr_html
 	   (org-test-with-temp-text "#+ATTR_HTML: :a :b\nParagraph"
 	   (org-test-with-temp-text "#+ATTR_HTML: :a :b\nParagraph"
 	     (org-element-at-point)))))
 	     (org-element-at-point)))))
+  ;; Return empty string when value is "".
+  (should
+   (equal '(:a "")
+	  (org-export-read-attribute
+	   :attr_html
+	   (org-test-with-temp-text "#+ATTR_HTML: :a \"\"\nParagraph"
+	     (org-element-at-point)))))
+  ;; Return \"\" when value is """".
+  (should
+   (equal '(:a "\"\"")
+	  (org-export-read-attribute
+	   :attr_html
+	   (org-test-with-temp-text "#+ATTR_HTML: :a \"\"\"\"\nParagraph"
+	     (org-element-at-point)))))
   ;; Ignore text before first property.
   ;; Ignore text before first property.
   (should-not
   (should-not
    (member "ignore"
    (member "ignore"
@@ -1911,6 +1925,35 @@ Another text. (ref:text)
       (mapcar (lambda (row) (org-export-table-row-group row info))
       (mapcar (lambda (row) (org-export-table-row-group row info))
 	      (org-element-map tree 'table-row 'identity))))))
 	      (org-element-map tree 'table-row 'identity))))))
 
 
+(ert-deftest test-org-export/table-row-number ()
+  "Test `org-export-table-row-number' specifications."
+  ;; Standard test.  Number is 0-indexed.
+  (should
+   (equal '(0 1)
+	  (org-test-with-parsed-data "| a | b | c |\n| d | e | f |"
+	    (org-element-map tree 'table-row
+	      (lambda (row) (org-export-table-row-number row info)) info))))
+  ;; Number ignores separators.
+  (should
+   (equal '(0 1)
+	  (org-test-with-parsed-data "
+| a | b | c |
+|---+---+---|
+| d | e | f |"
+	    (org-element-map tree 'table-row
+	      (lambda (row) (org-export-table-row-number row info)) info))))
+  ;; Number ignores special rows.
+  (should
+   (equal '(0 1)
+	  (org-test-with-parsed-data "
+| / | <   | >   |
+|   | b   | c   |
+|---+-----+-----|
+|   | <c> | <c> |
+|   | e   | f   |"
+	    (org-element-map tree 'table-row
+	      (lambda (row) (org-export-table-row-number row info)) info)))))
+
 (ert-deftest test-org-export/table-cell-width ()
 (ert-deftest test-org-export/table-cell-width ()
   "Test `org-export-table-cell-width' specifications."
   "Test `org-export-table-cell-width' specifications."
   ;; 1. Width is primarily determined by width cookies.  If no cookie
   ;; 1. Width is primarily determined by width cookies.  If no cookie

Some files were not shown because too many files changed in this diff