]> code.delx.au - gnu-emacs/blobdiff - lisp/org/org-table.el
Update copyright year to 2015
[gnu-emacs] / lisp / org / org-table.el
index 00b2eb4d028bfe1b52ffc1dbc3898cb3b48d5b79..d84c51bbbc3970b434da227156b214daed8d20e5 100644 (file)
@@ -1,6 +1,6 @@
 ;;; org-table.el --- The table editor for Org-mode
 
 ;;; org-table.el --- The table editor for Org-mode
 
-;; Copyright (C) 2004-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2004-2015 Free Software Foundation, Inc.
 
 ;; Author: Carsten Dominik <carsten at orgmode dot org>
 ;; Keywords: outlines, hypermedia, calendar, wp
 
 ;; Author: Carsten Dominik <carsten at orgmode dot org>
 ;; Keywords: outlines, hypermedia, calendar, wp
   (require 'cl))
 (require 'org)
 
   (require 'cl))
 (require 'org)
 
-(declare-function org-table-clean-before-export "org-exp"
-                 (lines &optional maybe-quoted))
-(declare-function org-format-org-table-html "org-html" (lines &optional splice))
+(declare-function org-export-string-as "ox"
+                 (string backend &optional body-only ext-plist))
 (declare-function aa2u "ext:ascii-art-to-unicode" ())
 (defvar orgtbl-mode) ; defined below
 (defvar orgtbl-mode-menu) ; defined when orgtbl mode get initialized
 (declare-function aa2u "ext:ascii-art-to-unicode" ())
 (defvar orgtbl-mode) ; defined below
 (defvar orgtbl-mode-menu) ; defined when orgtbl mode get initialized
-(defvar org-export-html-table-tag) ; defined in org-exp.el
 (defvar constants-unit-system)
 (defvar org-table-follow-field-mode)
 
 (defvar constants-unit-system)
 (defvar org-table-follow-field-mode)
 
@@ -54,6 +52,8 @@ This can be used to add additional functionality after the table is sent
 to the receiver position, otherwise, if table is not sent, the functions
 are not run.")
 
 to the receiver position, otherwise, if table is not sent, the functions
 are not run.")
 
+(defvar org-table-TBLFM-begin-regexp "|\n[ \t]*#\\+TBLFM: ")
+
 (defcustom orgtbl-optimized (eq org-enable-table-editor 'optimized)
   "Non-nil means use the optimized table editor version for `orgtbl-mode'.
 In the optimized version, the table editor takes over all simple keys that
 (defcustom orgtbl-optimized (eq org-enable-table-editor 'optimized)
   "Non-nil means use the optimized table editor version for `orgtbl-mode'.
 In the optimized version, the table editor takes over all simple keys that
@@ -94,6 +94,22 @@ this variable requires a restart of Emacs to become effective."
 | | |
 "))
   "Templates for radio tables in different major modes.
 | | |
 "))
   "Templates for radio tables in different major modes.
+Each template must define lines that will be treated as a comment and that
+must contain the \"BEGIN RECEIVE ORGTBL %n\" and \"END RECEIVE ORGTBL\"
+lines where \"%n\" will be replaced with the name of the table during
+insertion of the template.  The transformed table will later be inserted
+between these lines.
+
+The template should also contain a minimal table in a multiline comment.
+If multiline comments are not possible in the buffer language,
+you can pack it into a string that will not be used when the code
+is compiled or executed.  Above the table will you need a line with
+the fixed string \"#+ORGTBL: SEND\", followed by instruction on how to
+convert the table into a data structure useful in the
+language of the buffer.  Check the manual for the section on
+\"Translator functions\", and more generally check out
+http://orgmode.org/manual/Tables-in-arbitrary-syntax.html#Tables-in-arbitrary-syntax
+
 All occurrences of %n in a template will be replaced with the name of the
 table, obtained by prompting the user."
   :group 'org-table
 All occurrences of %n in a template will be replaced with the name of the
 table, obtained by prompting the user."
   :group 'org-table
@@ -112,7 +128,7 @@ table, obtained by prompting the user."
   :type 'string)
 
 (defcustom org-table-number-regexp
   :type 'string)
 
 (defcustom org-table-number-regexp
-  "^\\([<>]?[-+^.0-9]*[0-9][-+^.0-9eEdDx()%:]*\\|\\(0[xX]\\)[0-9a-fA-F]+\\|nan\\)$"
+  "^\\([<>]?[-+^.0-9]*[0-9][-+^.0-9eEdDx()%:]*\\|[<>]?[-+]?0[xX][0-9a-fA-F.]+\\|[<>]?[-+]?[0-9]+#[0-9a-zA-Z.]+\\|nan\\|[-+u]?inf\\)$"
   "Regular expression for recognizing numbers in table columns.
 If a table column contains mostly numbers, it will be aligned to the
 right.  If not, it will be aligned to the left.
   "Regular expression for recognizing numbers in table columns.
 If a table column contains mostly numbers, it will be aligned to the
 right.  If not, it will be aligned to the left.
@@ -136,10 +152,10 @@ Other options offered by the customize interface are more restrictive."
                 "^[-+]?\\([0-9]*\\.[0-9]+\\|[0-9]+\\.?[0-9]*\\)$")
          (const :tag "Exponential, Floating point, Integer"
                 "^[-+]?[0-9.]+\\([eEdD][-+0-9]+\\)?$")
                 "^[-+]?\\([0-9]*\\.[0-9]+\\|[0-9]+\\.?[0-9]*\\)$")
          (const :tag "Exponential, Floating point, Integer"
                 "^[-+]?[0-9.]+\\([eEdD][-+0-9]+\\)?$")
-         (const :tag "Very General Number-Like, including hex"
-                "^\\([<>]?[-+^.0-9]*[0-9][-+^.0-9eEdDx()%]*\\|\\(0[xX]\\)[0-9a-fA-F]+\\|nan\\)$")
-         (const :tag "Very General Number-Like, including hex, allows comma as decimal mark"
-                "^\\([<>]?[-+^.,0-9]*[0-9][-+^.0-9eEdDx()%]*\\|\\(0[xX]\\)[0-9a-fA-F]+\\|nan\\)$")
+         (const :tag "Very General Number-Like, including hex and Calc radix"
+                "^\\([<>]?[-+^.0-9]*[0-9][-+^.0-9eEdDx()%]*\\|[<>]?[-+]?0[xX][0-9a-fA-F.]+\\|[<>]?[-+]?[0-9]+#[0-9a-zA-Z.]+\\|nan\\|[-+u]?inf\\)$")
+         (const :tag "Very General Number-Like, including hex and Calc radix, allows comma as decimal mark"
+                "^\\([<>]?[-+^.,0-9]*[0-9][-+^.0-9eEdDx()%]*\\|[<>]?[-+]?0[xX][0-9a-fA-F.]+\\|[<>]?[-+]?[0-9]+#[0-9a-zA-Z.]+\\|nan\\|[-+u]?inf\\)$")
          (string :tag "Regexp:")))
 
 (defcustom org-table-number-fraction 0.5
          (string :tag "Regexp:")))
 
 (defcustom org-table-number-fraction 0.5
@@ -419,6 +435,40 @@ available parameters."
                         (org-split-string (match-string 1 line)
                                           "[ \t]*|[ \t]*")))))))
 
                         (org-split-string (match-string 1 line)
                                           "[ \t]*|[ \t]*")))))))
 
+(defvar org-table-clean-did-remove-column nil) ; dynamically scoped
+(defun org-table-clean-before-export (lines &optional maybe-quoted)
+  "Check if the table has a marking column.
+If yes remove the column and the special lines."
+  (let ((special (if maybe-quoted
+                    "^[ \t]*| *\\\\?[\#!$*_^/ ] *|"
+                  "^[ \t]*| *[\#!$*_^/ ] *|"))
+       (ignore  (if maybe-quoted
+                    "^[ \t]*| *\\\\?[!$_^/] *|"
+                  "^[ \t]*| *[!$_^/] *|")))
+    (setq org-table-clean-did-remove-column
+         (not (memq nil
+                    (mapcar
+                     (lambda (line)
+                       (or (string-match org-table-hline-regexp line)
+                           (string-match special                line)))
+                     lines))))
+    (delq nil
+         (mapcar
+          (lambda (line)
+            (cond
+             ((or (org-table-colgroup-line-p line)  ;; colgroup info
+                  (org-table-cookie-line-p line)    ;; formatting cookies
+                  (and org-table-clean-did-remove-column
+                       (string-match ignore line))) ;; non-exportable data
+              nil)
+             ((and org-table-clean-did-remove-column
+                   (or (string-match "^\\([ \t]*\\)|-+\\+" line)
+                       (string-match "^\\([ \t]*\\)|[^|]*|" line)))
+              ;; remove the first column
+              (replace-match "\\1|" t nil line))
+             (t line)))
+          lines))))
+
 (defconst org-table-translate-regexp
   (concat "\\(" "@[-0-9I$]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\)")
   "Match a reference that needs translation, for reference display.")
 (defconst org-table-translate-regexp
   (concat "\\(" "@[-0-9I$]+" "\\|" "[a-zA-Z]\\{1,2\\}\\([0-9]+\\|&\\)" "\\)")
   "Match a reference that needs translation, for reference display.")
@@ -503,7 +553,7 @@ nil      When nil, the command tries to be smart and figure out the
          - when each line contains a TAB, assume TAB-separated material
          - when each line contains a comma, assume CSV material
          - else, assume one or more SPACE characters as separator."
          - when each line contains a TAB, assume TAB-separated material
          - when each line contains a comma, assume CSV material
          - else, assume one or more SPACE characters as separator."
-  (interactive "rP")
+  (interactive "r\nP")
   (let* ((beg (min beg0 end0))
         (end (max beg0 end0))
         re)
   (let* ((beg (min beg0 end0))
         (end (max beg0 end0))
         re)
@@ -539,7 +589,7 @@ nil      When nil, the command tries to be smart and figure out the
                ((equal separator '(16)) "^\\|\t")
                ((integerp separator)
                 (if (< separator 1)
                ((equal separator '(16)) "^\\|\t")
                ((integerp separator)
                 (if (< separator 1)
-                    (error "Number of spaces in separator must be >= 1")
+                    (user-error "Number of spaces in separator must be >= 1")
                   (format "^ *\\| *\t *\\| \\{%d,\\}" separator)))
                (t (error "This should not happen"))))
       (while (re-search-forward re end t)
                   (format "^ *\\| *\t *\\| \\{%d,\\}" separator)))
                (t (error "This should not happen"))))
       (while (re-search-forward re end t)
@@ -579,9 +629,7 @@ whether it is set locally or up in the hierarchy, then on the
 extension of the given file name, and finally on the variable
 `org-table-export-default-format'."
   (interactive)
 extension of the given file name, and finally on the variable
 `org-table-export-default-format'."
   (interactive)
-  (unless (org-at-table-p)
-    (error "No table at point"))
-  (require 'org-exp)
+  (unless (org-at-table-p) (user-error "No table at point"))
   (org-table-align) ;; make sure we have everything we need
   (let* ((beg (org-table-begin))
         (end (org-table-end))
   (org-table-align) ;; make sure we have everything we need
   (let* ((beg (org-table-begin))
         (end (org-table-end))
@@ -598,13 +646,13 @@ extension of the given file name, and finally on the variable
       (setq file (read-file-name "Export table to: "))
       (unless (or (not (file-exists-p file))
                  (y-or-n-p (format "Overwrite file %s? " file)))
       (setq file (read-file-name "Export table to: "))
       (unless (or (not (file-exists-p file))
                  (y-or-n-p (format "Overwrite file %s? " file)))
-       (error "Abort")))
+       (user-error "File not written")))
     (if (file-directory-p file)
     (if (file-directory-p file)
-       (error "This is a directory path, not a file"))
+       (user-error "This is a directory path, not a file"))
     (if (and (buffer-file-name)
             (equal (file-truename file)
                    (file-truename (buffer-file-name))))
     (if (and (buffer-file-name)
             (equal (file-truename file)
                    (file-truename (buffer-file-name))))
-       (error "Please specify a file name that is different from current"))
+       (user-error "Please specify a file name that is different from current"))
     (setq fileext (concat (file-name-extension file) "$"))
     (unless format
       (setq deffmt-readable
     (setq fileext (concat (file-name-extension file) "$"))
     (unless format
       (setq deffmt-readable
@@ -641,7 +689,7 @@ extension of the given file name, and finally on the variable
                                     skipcols i0)))
 
          (unless (fboundp transform)
                                     skipcols i0)))
 
          (unless (fboundp transform)
-           (error "No such transformation function %s" transform))
+           (user-error "No such transformation function %s" transform))
          (setq txt (funcall transform table params))
 
          (with-current-buffer (find-file-noselect file)
          (setq txt (funcall transform table params))
 
          (with-current-buffer (find-file-noselect file)
@@ -652,7 +700,7 @@ extension of the given file name, and finally on the variable
            (save-buffer))
          (kill-buffer buf)
          (message "Export done."))
            (save-buffer))
          (kill-buffer buf)
          (message "Export done."))
-      (error "TABLE_EXPORT_FORMAT invalid"))))
+      (user-error "TABLE_EXPORT_FORMAT invalid"))))
 
 (defvar org-table-aligned-begin-marker (make-marker)
   "Marker at the beginning of the table last aligned.
 
 (defvar org-table-aligned-begin-marker (make-marker)
   "Marker at the beginning of the table last aligned.
@@ -760,7 +808,7 @@ When nil, simply write \"#ERROR\" in corrupted fields.")
       (error
        (kill-region beg end)
        (org-table-create org-table-default-size)
       (error
        (kill-region beg end)
        (org-table-create org-table-default-size)
-       (error "Empty table - created default table")))
+       (user-error "Empty table - created default table")))
     ;; A list of empty strings to fill any short rows on output
     (setq emptystrings (make-list maxfields ""))
     ;; Check for special formatting.
     ;; A list of empty strings to fill any short rows on output
     (setq emptystrings (make-list maxfields ""))
     ;; Check for special formatting.
@@ -787,7 +835,7 @@ When nil, simply write \"#ERROR\" in corrupted fields.")
                    (concat "Clipped table field, use C-c ` to edit.  Full value is:\n" (org-no-properties (copy-sequence xx))))
                  (setq f1 (min fmax (or (string-match org-bracket-link-regexp xx) fmax)))
                  (unless (> f1 1)
                    (concat "Clipped table field, use C-c ` to edit.  Full value is:\n" (org-no-properties (copy-sequence xx))))
                  (setq f1 (min fmax (or (string-match org-bracket-link-regexp xx) fmax)))
                  (unless (> f1 1)
-                   (error "Cannot narrow field starting with wide link \"%s\""
+                   (user-error "Cannot narrow field starting with wide link \"%s\""
                           (match-string 0 xx)))
                  (add-text-properties f1 (length xx) (list 'org-cwidth t) xx)
                  (add-text-properties (- f1 2) f1
                           (match-string 0 xx)))
                  (add-text-properties f1 (length xx) (list 'org-cwidth t) xx)
                  (add-text-properties (- f1 2) f1
@@ -860,12 +908,14 @@ When nil, simply write \"#ERROR\" in corrupted fields.")
     (org-goto-line winstartline)
     (setq winstart (point-at-bol))
     (org-goto-line linepos)
     (org-goto-line winstartline)
     (setq winstart (point-at-bol))
     (org-goto-line linepos)
-    (set-window-start (selected-window) winstart 'noforce)
+    (when (eq (window-buffer (selected-window)) (current-buffer))
+      (set-window-start (selected-window) winstart 'noforce))
     (org-table-goto-column colpos)
     (and org-table-overlay-coordinates (org-table-overlay-coordinates))
     (setq org-table-may-need-update nil)
     ))
 
     (org-table-goto-column colpos)
     (and org-table-overlay-coordinates (org-table-overlay-coordinates))
     (setq org-table-may-need-update nil)
     ))
 
+;;;###autoload
 (defun org-table-begin (&optional table-type)
   "Find the beginning of the table and return its position.
 With argument TABLE-TYPE, go to the beginning of a table.el-type table."
 (defun org-table-begin (&optional table-type)
   "Find the beginning of the table and return its position.
 With argument TABLE-TYPE, go to the beginning of a table.el-type table."
@@ -879,6 +929,7 @@ With argument TABLE-TYPE, go to the beginning of a table.el-type table."
       (beginning-of-line 2)
       (point))))
 
       (beginning-of-line 2)
       (point))))
 
+;;;###autoload
 (defun org-table-end (&optional table-type)
   "Find the end of the table and return its position.
 With argument TABLE-TYPE, go to the end of a table.el-type table."
 (defun org-table-end (&optional table-type)
   "Find the end of the table and return its position.
 With argument TABLE-TYPE, go to the end of a table.el-type table."
@@ -978,7 +1029,7 @@ Before doing so, re-align the table if necessary."
       (progn
        (re-search-backward "|" (org-table-begin))
        (re-search-backward "|" (org-table-begin)))
       (progn
        (re-search-backward "|" (org-table-begin))
        (re-search-backward "|" (org-table-begin)))
-    (error (error "Cannot move to previous table field")))
+    (error (user-error "Cannot move to previous table field")))
   (while (looking-at "|\\(-\\|[ \t]*$\\)")
     (re-search-backward "|" (org-table-begin)))
   (if (looking-at "| ?")
   (while (looking-at "|\\(-\\|[ \t]*$\\)")
     (re-search-backward "|" (org-table-begin)))
   (if (looking-at "| ?")
@@ -994,7 +1045,7 @@ With numeric argument N, move N-1 fields forward first."
       (setq n (1- n))
       (org-table-previous-field))
     (if (not (re-search-backward "|" (point-at-bol 0) t))
       (setq n (1- n))
       (org-table-previous-field))
     (if (not (re-search-backward "|" (point-at-bol 0) t))
-       (error "No more table fields before the current")
+       (user-error "No more table fields before the current")
       (goto-char (match-end 0))
       (and (looking-at " ") (forward-char 1)))
     (if (>= (point) pos) (org-table-beginning-of-field 2))))
       (goto-char (match-end 0))
       (and (looking-at " ") (forward-char 1)))
     (if (>= (point) pos) (org-table-beginning-of-field 2))))
@@ -1055,7 +1106,7 @@ copying.  In the case of a timestamp, increment by one day."
   (interactive "p")
   (let* ((colpos (org-table-current-column))
         (col (current-column))
   (interactive "p")
   (let* ((colpos (org-table-current-column))
         (col (current-column))
-        (field (org-table-get-field))
+        (field (save-excursion (org-table-get-field)))
         (non-empty (string-match "[^ \t]" field))
         (beg (org-table-begin))
         (orig-n n)
         (non-empty (string-match "[^ \t]" field))
         (beg (org-table-begin))
         (orig-n n)
@@ -1091,7 +1142,7 @@ copying.  In the case of a timestamp, increment by one day."
            (org-table-maybe-recalculate-line))
          (org-table-align)
          (org-move-to-column col))
            (org-table-maybe-recalculate-line))
          (org-table-align)
          (org-move-to-column col))
-      (error "No non-empty field found"))))
+      (user-error "No non-empty field found"))))
 
 (defun org-table-check-inside-data-field (&optional noerror)
   "Is point inside a table data field?
 
 (defun org-table-check-inside-data-field (&optional noerror)
   "Is point inside a table data field?
@@ -1103,7 +1154,7 @@ This actually throws an error, so it aborts the current command."
          (looking-at "[ \t]*$"))
       (if noerror
          nil
          (looking-at "[ \t]*$"))
       (if noerror
          nil
-       (error "Not in table data field"))
+       (user-error "Not in table data field"))
     t))
 
 (defvar org-table-clip nil
     t))
 
 (defvar org-table-clip nil
@@ -1150,6 +1201,7 @@ Return t when the line exists, nil if it does not exist."
                (< (setq cnt (1+ cnt)) N)))
     (= cnt N)))
 
                (< (setq cnt (1+ cnt)) N)))
     (= cnt N)))
 
+;;;###autoload
 (defun org-table-blank-field ()
   "Blank the current table field or active region."
   (interactive)
 (defun org-table-blank-field ()
   "Blank the current table field or active region."
   (interactive)
@@ -1189,6 +1241,7 @@ is always the old value."
 (defun org-table-field-info (arg)
   "Show info about the current field, and highlight any reference at point."
   (interactive "P")
 (defun org-table-field-info (arg)
   "Show info about the current field, and highlight any reference at point."
   (interactive "P")
+  (unless (org-at-table-p) (user-error "Not at a table"))
   (org-table-get-specials)
   (save-excursion
     (let* ((pos (point))
   (org-table-get-specials)
   (save-excursion
     (let* ((pos (point))
@@ -1286,7 +1339,7 @@ However, when FORCE is non-nil, create new columns if necessary."
   "Insert a new column into the table."
   (interactive)
   (if (not (org-at-table-p))
   "Insert a new column into the table."
   (interactive)
   (if (not (org-at-table-p))
-      (error "Not at a table"))
+      (user-error "Not at a table"))
   (org-table-find-dataline)
   (let* ((col (max 1 (org-table-current-column)))
         (beg (org-table-begin))
   (org-table-find-dataline)
   (let* ((col (max 1 (org-table-current-column)))
         (beg (org-table-begin))
@@ -1326,7 +1379,7 @@ However, when FORCE is non-nil, create new columns if necessary."
       (if (and (org-at-table-p)
               (not (org-at-table-hline-p)))
          t
       (if (and (org-at-table-p)
               (not (org-at-table-hline-p)))
          t
-       (error
+       (user-error
         "Please position cursor in a data line for column operations")))))
 
 (defun org-table-line-to-dline (line &optional above)
         "Please position cursor in a data line for column operations")))))
 
 (defun org-table-line-to-dline (line &optional above)
@@ -1356,7 +1409,7 @@ first dline below it is used.  When ABOVE is non-nil, the one above is used."
   "Delete a column from the table."
   (interactive)
   (if (not (org-at-table-p))
   "Delete a column from the table."
   (interactive)
   (if (not (org-at-table-p))
-      (error "Not at a table"))
+      (user-error "Not at a table"))
   (org-table-find-dataline)
   (org-table-check-inside-data-field)
   (let* ((col (org-table-current-column))
   (org-table-find-dataline)
   (org-table-check-inside-data-field)
   (let* ((col (org-table-current-column))
@@ -1400,7 +1453,7 @@ first dline below it is used.  When ABOVE is non-nil, the one above is used."
   "Move the current column to the right.  With arg LEFT, move to the left."
   (interactive "P")
   (if (not (org-at-table-p))
   "Move the current column to the right.  With arg LEFT, move to the left."
   (interactive "P")
   (if (not (org-at-table-p))
-      (error "Not at a table"))
+      (user-error "Not at a table"))
   (org-table-find-dataline)
   (org-table-check-inside-data-field)
   (let* ((col (org-table-current-column))
   (org-table-find-dataline)
   (org-table-check-inside-data-field)
   (let* ((col (org-table-current-column))
@@ -1411,9 +1464,9 @@ first dline below it is used.  When ABOVE is non-nil, the one above is used."
         (linepos (org-current-line))
         (colpos (if left (1- col) (1+ col))))
     (if (and left (= col 1))
         (linepos (org-current-line))
         (colpos (if left (1- col) (1+ col))))
     (if (and left (= col 1))
-       (error "Cannot move column further left"))
+       (user-error "Cannot move column further left"))
     (if (and (not left) (looking-at "[^|\n]*|[^|\n]*$"))
     (if (and (not left) (looking-at "[^|\n]*|[^|\n]*$"))
-       (error "Cannot move column further right"))
+       (user-error "Cannot move column further right"))
     (goto-char beg)
     (while (< (point) end)
       (if (org-at-table-hline-p)
     (goto-char beg)
     (while (< (point) end)
       (if (org-at-table-hline-p)
@@ -1461,7 +1514,7 @@ first dline below it is used.  When ABOVE is non-nil, the one above is used."
     (beginning-of-line tonew)
     (unless (org-at-table-p)
       (goto-char pos)
     (beginning-of-line tonew)
     (unless (org-at-table-p)
       (goto-char pos)
-      (error "Cannot move row further"))
+      (user-error "Cannot move row further"))
     (setq hline2p (looking-at org-table-hline-regexp))
     (goto-char pos)
     (beginning-of-line 1)
     (setq hline2p (looking-at org-table-hline-regexp))
     (goto-char pos)
     (beginning-of-line 1)
@@ -1486,7 +1539,7 @@ first dline below it is used.  When ABOVE is non-nil, the one above is used."
 With prefix ARG, insert below the current line."
   (interactive "P")
   (if (not (org-at-table-p))
 With prefix ARG, insert below the current line."
   (interactive "P")
   (if (not (org-at-table-p))
-      (error "Not at a table"))
+      (user-error "Not at a table"))
   (let* ((line (buffer-substring (point-at-bol) (point-at-eol)))
         (new (org-table-clean-line line)))
     ;; Fix the first field if necessary
   (let* ((line (buffer-substring (point-at-bol) (point-at-eol)))
         (new (org-table-clean-line line)))
     ;; Fix the first field if necessary
@@ -1508,7 +1561,7 @@ With prefix ARG, insert below the current line."
 With prefix ABOVE, insert above the current line."
   (interactive "P")
   (if (not (org-at-table-p))
 With prefix ABOVE, insert above the current line."
   (interactive "P")
   (if (not (org-at-table-p))
-      (error "Not at a table"))
+      (user-error "Not at a table"))
   (when (eobp) (insert "\n") (backward-char 1))
   (if (not (string-match "|[ \t]*$" (org-current-line-string)))
       (org-table-align))
   (when (eobp) (insert "\n") (backward-char 1))
   (if (not (string-match "|[ \t]*$" (org-current-line-string)))
       (org-table-align))
@@ -1558,7 +1611,7 @@ In particular, this does handle wide and invisible characters."
   "Delete the current row or horizontal line from the table."
   (interactive)
   (if (not (org-at-table-p))
   "Delete the current row or horizontal line from the table."
   (interactive)
   (if (not (org-at-table-p))
-      (error "Not at a table"))
+      (user-error "Not at a table"))
   (let ((col (current-column))
        (dline (org-table-current-dline)))
     (kill-region (point-at-bol) (min (1+ (point-at-eol)) (point-max)))
   (let ((col (current-column))
        (dline (org-table-current-dline)))
     (kill-region (point-at-bol) (min (1+ (point-at-eol)) (point-max)))
@@ -1710,7 +1763,7 @@ the table is enlarged as needed.  The process ignores horizontal separator
 lines."
   (interactive)
   (unless (and org-table-clip (listp org-table-clip))
 lines."
   (interactive)
   (unless (and org-table-clip (listp org-table-clip))
-    (error "First cut/copy a region to paste!"))
+    (user-error "First cut/copy a region to paste!"))
   (org-table-check-inside-data-field)
   (let* ((clip org-table-clip)
         (line (org-current-line))
   (org-table-check-inside-data-field)
   (let* ((clip org-table-clip)
         (line (org-current-line))
@@ -1796,11 +1849,16 @@ will be transposed as
 
 Note that horizontal lines disappeared."
   (interactive)
 
 Note that horizontal lines disappeared."
   (interactive)
-  (let ((contents
-         (apply #'mapcar* #'list
-                ;; remove 'hline from list
-               (delq nil (mapcar (lambda (x) (when (listp x) x))
-                                 (org-table-to-lisp))))))
+  (let* ((table (delete 'hline (org-table-to-lisp)))
+        (contents (mapcar (lambda (p)
+                            (let ((tp table))
+                              (mapcar
+                               (lambda (rown)
+                                 (prog1
+                                     (pop (car tp))
+                                   (setq tp (cdr tp))))
+                               table)))
+                          (car table))))
     (delete-region (org-table-begin) (org-table-end))
     (insert (mapconcat (lambda(x) (concat "| " (mapconcat 'identity x " | " ) "  |\n" ))
                        contents ""))
     (delete-region (org-table-begin) (org-table-end))
     (insert (mapconcat (lambda(x) (concat "| " (mapconcat 'identity x " | " ) "  |\n" ))
                        contents ""))
@@ -1839,7 +1897,7 @@ blank, and the content is appended to the field above."
             nlines)
        (org-table-cut-region (region-beginning) (region-end))
        (if (> (length (car org-table-clip)) 1)
             nlines)
        (org-table-cut-region (region-beginning) (region-end))
        (if (> (length (car org-table-clip)) 1)
-           (error "Region must be limited to single column"))
+           (user-error "Region must be limited to single column"))
        (setq nlines (if arg
                         (if (< arg 1)
                             (+ (length org-table-clip) arg)
        (setq nlines (if arg
                         (if (< arg 1)
                             (+ (length org-table-clip) arg)
@@ -2008,12 +2066,12 @@ If NLAST is a number, only the NLAST fields will actually be summed."
        (setq col (org-table-current-column))
        (goto-char (org-table-begin))
        (unless (re-search-forward "^[ \t]*|[^-]" nil t)
        (setq col (org-table-current-column))
        (goto-char (org-table-begin))
        (unless (re-search-forward "^[ \t]*|[^-]" nil t)
-         (error "No table data"))
+         (user-error "No table data"))
        (org-table-goto-column col)
        (setq beg (point))
        (goto-char (org-table-end))
        (unless (re-search-backward "^[ \t]*|[^-]" nil t)
        (org-table-goto-column col)
        (setq beg (point))
        (goto-char (org-table-end))
        (unless (re-search-backward "^[ \t]*|[^-]" nil t)
-         (error "No table data"))
+         (user-error "No table data"))
        (org-table-goto-column col)
        (setq end (point))))
       (let* ((items (apply 'append (org-table-copy-region beg end)))
        (org-table-goto-column col)
        (setq end (point))))
       (let* ((items (apply 'append (org-table-copy-region beg end)))
@@ -2031,7 +2089,7 @@ If NLAST is a number, only the NLAST fields will actually be summed."
                           h (floor (/ diff 3600)) diff (mod diff 3600)
                           m (floor (/ diff 60)) diff (mod diff 60)
                           s diff)
                           h (floor (/ diff 3600)) diff (mod diff 3600)
                           m (floor (/ diff 60)) diff (mod diff 60)
                           s diff)
-                    (format "%d:%02d:%02d" h m s))))
+                    (format "%.0f:%02.0f:%02.0f" h m s))))
        (kill-new sres)
        (if (org-called-interactively-p 'interactive)
            (message "%s"
        (kill-new sres)
        (if (org-called-interactively-p 'interactive)
            (message "%s"
@@ -2098,7 +2156,7 @@ When NAMED is non-nil, look for a named equation."
                 (int-to-string (org-table-current-column))))
         (dummy (and (or nameass refass) (not named)
                     (not (y-or-n-p "Replace existing field formula with column formula? " ))
                 (int-to-string (org-table-current-column))))
         (dummy (and (or nameass refass) (not named)
                     (not (y-or-n-p "Replace existing field formula with column formula? " ))
-                    (error "Abort")))
+                    (message "Formula not replaced")))
         (name (or name ref))
         (org-table-may-need-update nil)
         (stored (cdr (assoc scol stored-list)))
         (name (or name ref))
         (org-table-may-need-update nil)
         (stored (cdr (assoc scol stored-list)))
@@ -2122,7 +2180,7 @@ When NAMED is non-nil, look for a named equation."
       ;; remove formula
       (setq stored-list (delq (assoc scol stored-list) stored-list))
       (org-table-store-formulas stored-list)
       ;; remove formula
       (setq stored-list (delq (assoc scol stored-list) stored-list))
       (org-table-store-formulas stored-list)
-      (error "Formula removed"))
+      (user-error "Formula removed"))
     (if (string-match "^ *=?" eq) (setq eq (replace-match "" t t eq)))
     (if (string-match " *$" eq) (setq eq (replace-match "" t t eq)))
     (if (and name (not named))
     (if (string-match "^ *=?" eq) (setq eq (replace-match "" t t eq)))
     (if (string-match " *$" eq) (setq eq (replace-match "" t t eq)))
     (if (and name (not named))
@@ -2207,7 +2265,7 @@ When NAMED is non-nil, look for a named equation."
                      (message "Double definition `$%s=' in TBLFM line, please fix by hand" scol)
                      (ding)
                      (sit-for 2))
                      (message "Double definition `$%s=' in TBLFM line, please fix by hand" scol)
                      (ding)
                      (sit-for 2))
-                 (error "Double definition `$%s=' in TBLFM line, please fix by hand" scol))
+                 (user-error "Double definition `$%s=' in TBLFM line, please fix by hand" scol))
              (push scol seen))))))
     (nreverse eq-alist)))
 
              (push scol seen))))))
     (nreverse eq-alist)))
 
@@ -2217,7 +2275,7 @@ KEY is \"@\" or \"$\".  REPLACE is an alist of numbers to replace.
 For all numbers larger than LIMIT, shift them by DELTA."
   (save-excursion
     (goto-char (org-table-end))
 For all numbers larger than LIMIT, shift them by DELTA."
   (save-excursion
     (goto-char (org-table-end))
-    (when (let ((case-fold-search t)) (looking-at "[ \t]*#\\+tblfm:"))
+    (while (let ((case-fold-search t)) (looking-at "[ \t]*#\\+tblfm:"))
       (let ((msg "The formulas in #+TBLFM have been updated")
            (re (concat key "\\([0-9]+\\)"))
            (re2
       (let ((msg "The formulas in #+TBLFM have been updated")
            (re (concat key "\\([0-9]+\\)"))
            (re2
@@ -2231,8 +2289,9 @@ For all numbers larger than LIMIT, shift them by DELTA."
          (while (re-search-forward re2 (point-at-eol) t)
            (unless (save-match-data (org-in-regexp "remote([^)]+?)"))
              (if (equal (char-before (match-beginning 0)) ?.)
          (while (re-search-forward re2 (point-at-eol) t)
            (unless (save-match-data (org-in-regexp "remote([^)]+?)"))
              (if (equal (char-before (match-beginning 0)) ?.)
-                 (error "Change makes TBLFM term %s invalid, use undo to recover"
-                        (match-string 0))
+                 (user-error
+                  "Change makes TBLFM term %s invalid, use undo to recover"
+                  (match-string 0))
                (replace-match "")))))
        (while (re-search-forward re (point-at-eol) t)
          (unless (save-match-data (org-in-regexp "remote([^)]+?)"))
                (replace-match "")))))
        (while (re-search-forward re (point-at-eol) t)
          (unless (save-match-data (org-in-regexp "remote([^)]+?)"))
@@ -2243,7 +2302,8 @@ For all numbers larger than LIMIT, shift them by DELTA."
              (message msg))
             ((and limit (> n limit))
              (replace-match (concat key (int-to-string (+ n delta))) t t)
              (message msg))
             ((and limit (> n limit))
              (replace-match (concat key (int-to-string (+ n delta))) t t)
-             (message msg)))))))))
+             (message msg))))))
+      (forward-line))))
 
 (defun org-table-get-specials ()
   "Get the column names and local parameters for this table."
 
 (defun org-table-get-specials ()
   "Get the column names and local parameters for this table."
@@ -2291,7 +2351,7 @@ For all numbers larger than LIMIT, shift them by DELTA."
                     (string-match "^[a-zA-Z][_a-zA-Z0-9]*$" field))
            (push (cons field v) org-table-local-parameters)
            (push (list field line col) org-table-named-field-locations))))
                     (string-match "^[a-zA-Z][_a-zA-Z0-9]*$" field))
            (push (cons field v) org-table-local-parameters)
            (push (list field line col) org-table-named-field-locations))))
-      ;; Analyse the line types
+      ;; Analyze the line types.
       (goto-char beg)
       (setq org-table-current-begin-line (org-current-line)
            org-table-current-begin-pos (point)
       (goto-char beg)
       (setq org-table-current-begin-line (org-current-line)
            org-table-current-begin-pos (point)
@@ -2338,7 +2398,7 @@ If yes, store the formula and apply it."
                (equal (substring eq 0 (min 2 (length eq))) "'("))
            (org-table-eval-formula (if named '(4) nil)
                                    (org-table-formula-from-user eq))
                (equal (substring eq 0 (min 2 (length eq))) "'("))
            (org-table-eval-formula (if named '(4) nil)
                                    (org-table-formula-from-user eq))
-         (error "Calc does not seem to be installed, and is needed to evaluate the formula"))))))
+         (user-error "Calc does not seem to be installed, and is needed to evaluate the formula"))))))
 
 (defvar org-recalc-commands nil
   "List of commands triggering the recalculation of a line.
 
 (defvar org-recalc-commands nil
   "List of commands triggering the recalculation of a line.
@@ -2363,7 +2423,7 @@ after prompting for the marking character.
 After each change, a message will be displayed indicating the meaning
 of the new mark."
   (interactive)
 After each change, a message will be displayed indicating the meaning
 of the new mark."
   (interactive)
-  (unless (org-at-table-p) (error "Not at a table"))
+  (unless (org-at-table-p) (user-error "Not at a table"))
   (let* ((marks (append (mapcar 'car org-recalc-marks) '(" ")))
         (beg (org-table-begin))
         (end (org-table-end))
   (let* ((marks (append (mapcar 'car org-recalc-marks) '(" ")))
         (beg (org-table-begin))
         (end (org-table-end))
@@ -2382,13 +2442,13 @@ of the new mark."
       (setq newchar (char-to-string (read-char-exclusive))
            forcenew (car (assoc newchar org-recalc-marks))))
     (if (and newchar (not forcenew))
       (setq newchar (char-to-string (read-char-exclusive))
            forcenew (car (assoc newchar org-recalc-marks))))
     (if (and newchar (not forcenew))
-       (error "Invalid NEWCHAR `%s' in `org-table-rotate-recalc-marks'"
+       (user-error "Invalid NEWCHAR `%s' in `org-table-rotate-recalc-marks'"
               newchar))
     (if l1 (org-goto-line l1))
     (save-excursion
       (beginning-of-line 1)
       (unless (looking-at org-table-dataline-regexp)
               newchar))
     (if l1 (org-goto-line l1))
     (save-excursion
       (beginning-of-line 1)
       (unless (looking-at org-table-dataline-regexp)
-       (error "Not at a table data line")))
+       (user-error "Not at a table data line")))
     (unless have-col
       (org-table-goto-column 1)
       (org-table-insert-column)
     (unless have-col
       (org-table-goto-column 1)
       (org-table-insert-column)
@@ -2483,7 +2543,7 @@ not overwrite the stored one."
   (or suppress-analysis (org-table-get-specials))
   (if (equal arg '(16))
       (let ((eq (org-table-current-field-formula)))
   (or suppress-analysis (org-table-get-specials))
   (if (equal arg '(16))
       (let ((eq (org-table-current-field-formula)))
-       (or eq (error "No equation active for current field"))
+       (or eq (user-error "No equation active for current field"))
        (org-table-get-field nil eq)
        (org-table-align)
        (setq org-table-may-need-update t))
        (org-table-get-field nil eq)
        (org-table-align)
        (setq org-table-may-need-update t))
@@ -2557,7 +2617,10 @@ not overwrite the stored one."
                          fields)))
        (if (eq numbers t)
            (setq fields (mapcar
                          fields)))
        (if (eq numbers t)
            (setq fields (mapcar
-                         (lambda (x) (number-to-string (string-to-number x)))
+                         (lambda (x)
+                           (if (string-match "\\S-" x)
+                               (number-to-string (string-to-number x))
+                             x))
                          fields)))
        (setq ndown (1- ndown))
        (setq form (copy-sequence formula)
                          fields)))
        (setq ndown (1- ndown))
        (setq form (copy-sequence formula)
@@ -2612,7 +2675,7 @@ not overwrite the stored one."
          (if (not (save-match-data
                     (string-match (regexp-quote form) formrpl)))
              (setq form (replace-match formrpl t t form))
          (if (not (save-match-data
                     (string-match (regexp-quote form) formrpl)))
              (setq form (replace-match formrpl t t form))
-           (error "Spreadsheet error: invalid reference \"%s\"" form)))
+           (user-error "Spreadsheet error: invalid reference \"%s\"" form)))
        ;; Insert simple ranges
        (while (string-match "\\$\\([0-9]+\\)\\.\\.\\$\\([0-9]+\\)"  form)
          (setq form
        ;; Insert simple ranges
        (while (string-match "\\$\\([0-9]+\\)\\.\\.\\$\\([0-9]+\\)"  form)
          (setq form
@@ -2630,11 +2693,12 @@ not overwrite the stored one."
          (setq n (+ (string-to-number (match-string 1 form))
                     (if (match-end 2) n0 0))
                x (nth (1- (if (= n 0) n0 (max n 1))) fields))
          (setq n (+ (string-to-number (match-string 1 form))
                     (if (match-end 2) n0 0))
                x (nth (1- (if (= n 0) n0 (max n 1))) fields))
-         (unless x (error "Invalid field specifier \"%s\""
+         (unless x (user-error "Invalid field specifier \"%s\""
                           (match-string 0 form)))
          (setq form (replace-match
                      (save-match-data
                           (match-string 0 form)))
          (setq form (replace-match
                      (save-match-data
-                       (org-table-make-reference x nil numbers lispp))
+                       (org-table-make-reference
+                        x keep-empty numbers lispp))
                      t t form)))
 
        (if lispp
                      t t form)))
 
        (if lispp
@@ -2646,12 +2710,24 @@ not overwrite the stored one."
                                   (string-to-number ev)
                                   duration-output-format) ev))
          (or (fboundp 'calc-eval)
                                   (string-to-number ev)
                                   duration-output-format) ev))
          (or (fboundp 'calc-eval)
-             (error "Calc does not seem to be installed, and is needed to evaluate the formula"))
-         ;; "Inactivate" time-stamps so that Calc can handle them
-         (setq form (replace-regexp-in-string org-ts-regexp3 "<\\1>" form))
+             (user-error "Calc does not seem to be installed, and is needed to evaluate the formula"))
+         ;; Use <...> time-stamps so that Calc can handle them
+         (while (string-match (concat "\\[" org-ts-regexp1 "\\]") form)
+           (setq form (replace-match "<\\1>" nil nil form)))
+         ;; I18n-ize local time-stamps by setting (system-time-locale "C")
+         (when (string-match org-ts-regexp2 form)
+           (let* ((ts (match-string 0 form))
+                  (tsp (apply 'encode-time (save-match-data (org-parse-time-string ts))))
+                  (system-time-locale "C")
+                  (tf (or (and (save-match-data (string-match "[0-9]\\{1,2\\}:[0-9]\\{2\\}" ts))
+                               (cdr org-time-stamp-formats))
+                          (car org-time-stamp-formats))))
+             (setq form (replace-match (format-time-string tf tsp) t t form))))
+
          (setq ev (if (and duration (string-match "^[0-9]+:[0-9]+\\(?::[0-9]+\\)?$" form))
                       form
          (setq ev (if (and duration (string-match "^[0-9]+:[0-9]+\\(?::[0-9]+\\)?$" form))
                       form
-                    (calc-eval (cons form org-tbl-calc-modes) (if numbers 'num)))
+                    (calc-eval (cons form org-tbl-calc-modes)
+                               (when (and (not keep-empty) numbers) 'num)))
                ev (if duration (org-table-time-seconds-to-string
                                 (if (string-match "^[0-9]+:[0-9]+\\(?::[0-9]+\\)?$" ev)
                                     (string-to-number (org-table-time-string-to-seconds ev))
                ev (if duration (org-table-time-seconds-to-string
                                 (if (string-match "^[0-9]+:[0-9]+\\(?::[0-9]+\\)?$" ev)
                                     (string-to-number (org-table-time-string-to-seconds ev))
@@ -2667,7 +2743,7 @@ $xyz->  %s
 @r$c->  %s
 $1->    %s\n" orig formula form0 form))
            (if (listp ev)
 @r$c->  %s
 $1->    %s\n" orig formula form0 form))
            (if (listp ev)
-               (princ (format "       %s^\nError:  %s"
+               (princ (format "        %s^\nError:  %s"
                               (make-string (car ev) ?\-) (nth 1 ev)))
              (princ (format "Result: %s\nFormat: %s\nFinal:  %s"
                             ev (or fmt "NONE")
                               (make-string (car ev) ?\-) (nth 1 ev)))
              (princ (format "Result: %s\nFormat: %s\nFinal:  %s"
                             ev (or fmt "NONE")
@@ -2678,7 +2754,7 @@ $1->    %s\n" orig formula form0 form))
            (unless (let (inhibit-redisplay)
                      (y-or-n-p "Debugging Formula.  Continue to next? "))
              (org-table-align)
            (unless (let (inhibit-redisplay)
                      (y-or-n-p "Debugging Formula.  Continue to next? "))
              (org-table-align)
-             (error "Abort"))
+             (user-error "Abort"))
            (delete-window bw)
            (message "")))
        (if (listp ev) (setq fmt nil ev "#ERROR"))
            (delete-window bw)
            (message "")))
        (if (listp ev) (setq fmt nil ev "#ERROR"))
@@ -2716,7 +2792,7 @@ in the buffer and column1 and column2 are table column numbers."
     (let ((thisline (org-current-line))
          beg end c1 c2 r1 r2 rangep tmp)
       (unless (string-match org-table-range-regexp desc)
     (let ((thisline (org-current-line))
          beg end c1 c2 r1 r2 rangep tmp)
       (unless (string-match org-table-range-regexp desc)
-       (error "Invalid table range specifier `%s'" desc))
+       (user-error "Invalid table range specifier `%s'" desc))
       (setq rangep (match-end 3)
            r1 (and (match-end 1) (match-string 1 desc))
            r2 (and (match-end 4) (match-string 4 desc))
       (setq rangep (match-end 3)
            r1 (and (match-end 1) (match-string 1 desc))
            r2 (and (match-end 4) (match-string 4 desc))
@@ -2784,7 +2860,7 @@ and TABLE is a vector with line types."
         ;;                     1  2          3           4  5          6
         (and (not (match-end 3)) (not (match-end 6)))
         (and (match-end 3) (match-end 6) (not (match-end 5))))
         ;;                     1  2          3           4  5          6
         (and (not (match-end 3)) (not (match-end 6)))
         (and (match-end 3) (match-end 6) (not (match-end 5))))
-       (error "Invalid row descriptor `%s'" desc))
+       (user-error "Invalid row descriptor `%s'" desc))
     (let* ((hdir (and (match-end 2) (match-string 2 desc)))
           (hn (if (match-end 3) (- (match-end 3) (match-beginning 3)) nil))
           (odir (and (match-end 5) (match-string 5 desc)))
     (let* ((hdir (and (match-end 2) (match-string 2 desc)))
           (hn (if (match-end 3) (- (match-end 3) (match-beginning 3)) nil))
           (odir (and (match-end 5) (match-string 5 desc)))
@@ -2798,7 +2874,7 @@ and TABLE is a vector with line types."
            (setq i 0 hdir "+")
            (if (eq (aref table 0) 'hline) (setq hn (1- hn)))))
       (if (and (not hn) on (not odir))
            (setq i 0 hdir "+")
            (if (eq (aref table 0) 'hline) (setq hn (1- hn)))))
       (if (and (not hn) on (not odir))
-         (error "Should never happen");;(aref org-table-dlines on)
+         (user-error "Should never happen");;(aref org-table-dlines on)
        (if (and hn (> hn 0))
            (setq i (org-table-find-row-type table i 'hline (equal hdir "-")
                                             nil hn cline desc)))
        (if (and hn (> hn 0))
            (setq i (org-table-find-row-type table i 'hline (equal hdir "-")
                                             nil hn cline desc)))
@@ -2818,41 +2894,56 @@ and TABLE is a vector with line types."
                      (cond
                       ((eq org-table-relative-ref-may-cross-hline t) t)
                       ((eq org-table-relative-ref-may-cross-hline 'error)
                      (cond
                       ((eq org-table-relative-ref-may-cross-hline t) t)
                       ((eq org-table-relative-ref-may-cross-hline 'error)
-                       (error "Row descriptor %s used in line %d crosses hline" desc cline))
+                       (user-error "Row descriptor %s used in line %d crosses hline" desc cline))
                       (t (setq i (- i (if backwards -1 1))
                                n 1)
                          nil))
                    t)))
       (setq n (1- n)))
     (if (or (< i 0) (>= i l))
                       (t (setq i (- i (if backwards -1 1))
                                n 1)
                          nil))
                    t)))
       (setq n (1- n)))
     (if (or (< i 0) (>= i l))
-       (error "Row descriptor %s used in line %d leads outside table"
+       (user-error "Row descriptor %s used in line %d leads outside table"
               desc cline)
       i)))
 
 (defun org-table-rewrite-old-row-references (s)
   (if (string-match "&[-+0-9I]" s)
               desc cline)
       i)))
 
 (defun org-table-rewrite-old-row-references (s)
   (if (string-match "&[-+0-9I]" s)
-      (error "Formula contains old &row reference, please rewrite using @-syntax")
+      (user-error "Formula contains old &row reference, please rewrite using @-syntax")
     s))
 
 (defun org-table-make-reference (elements keep-empty numbers lispp)
   "Convert list ELEMENTS to something appropriate to insert into formula.
 KEEP-EMPTY indicated to keep empty fields, default is to skip them.
 NUMBERS indicates that everything should be converted to numbers.
     s))
 
 (defun org-table-make-reference (elements keep-empty numbers lispp)
   "Convert list ELEMENTS to something appropriate to insert into formula.
 KEEP-EMPTY indicated to keep empty fields, default is to skip them.
 NUMBERS indicates that everything should be converted to numbers.
-LISPP means to return something appropriate for a Lisp list."
-  (if (stringp elements) ; just a single val
+LISPP non-nil means to return something appropriate for a Lisp
+list, 'literal is for the format specifier L."
+  ;; Calc nan (not a number) is used for the conversion of the empty
+  ;; field to a reference for several reasons: (i) It is accepted in a
+  ;; Calc formula (e. g. "" or "()" would result in a Calc error).
+  ;; (ii) In a single field (not in range) it can be distinguished
+  ;; from "(nan)" which is the reference made from a single field
+  ;; containing "nan".
+  (if (stringp elements)
+      ;; field reference
       (if lispp
          (if (eq lispp 'literal)
              elements
       (if lispp
          (if (eq lispp 'literal)
              elements
-           (prin1-to-string (if numbers (string-to-number elements) elements)))
-       (if (equal elements "") (setq elements "0"))
-       (if numbers (setq elements (number-to-string (string-to-number elements))))
-       (concat "(" elements ")"))
+           (if (and (eq elements "") (not keep-empty))
+               ""
+             (prin1-to-string
+              (if numbers (string-to-number elements) elements))))
+       (if (string-match "\\S-" elements)
+           (progn
+             (when numbers (setq elements (number-to-string
+                                           (string-to-number elements))))
+             (concat "(" elements ")"))
+         (if (or (not keep-empty) numbers) "(0)" "nan")))
+    ;; range reference
     (unless keep-empty
       (setq elements
            (delq nil
                  (mapcar (lambda (x) (if (string-match "\\S-" x) x nil))
                          elements))))
     (unless keep-empty
       (setq elements
            (delq nil
                  (mapcar (lambda (x) (if (string-match "\\S-" x) x nil))
                          elements))))
-    (setq elements (or elements '("0")))
+    (setq elements (or elements '()))  ; if delq returns nil then we need '()
     (if lispp
        (mapconcat
         (lambda (x)
     (if lispp
        (mapconcat
         (lambda (x)
@@ -2862,10 +2953,32 @@ LISPP means to return something appropriate for a Lisp list."
         elements " ")
       (concat "[" (mapconcat
                   (lambda (x)
         elements " ")
       (concat "[" (mapconcat
                   (lambda (x)
-                    (if numbers (number-to-string (string-to-number x)) x))
+                    (if (string-match "\\S-" x)
+                        (if numbers
+                            (number-to-string (string-to-number x))
+                          x)
+                      (if (or (not keep-empty) numbers) "0" "nan")))
                   elements
                   ",") "]"))))
 
                   elements
                   ",") "]"))))
 
+;;;###autoload
+(defun org-table-set-constants ()
+  "Set `org-table-formula-constants-local' in the current buffer."
+  (let (cst consts const-str)
+    (save-excursion
+      (goto-char (point-min))
+      (while (re-search-forward "^[ \t]*#\\+CONSTANTS: \\(.*\\)" nil t)
+       (setq const-str (substring-no-properties (match-string 1)))
+       (setq consts (append consts (org-split-string const-str "[ \t]+")))
+       (when consts
+         (let (e)
+           (while (setq e (pop consts))
+             (when (string-match "^\\([a-zA-Z0][_a-zA-Z0-9]*\\)=\\(.*\\)" e)
+               (if (assoc-string (match-string 1 e) cst)
+                   (setq cst (delete (assoc-string (match-string 1 e) cst) cst)))
+               (push (cons (match-string 1 e) (match-string 2 e)) cst)))
+           (setq org-table-formula-constants-local cst)))))))
+
 ;;;###autoload
 (defun org-table-recalculate (&optional all noalign)
   "Recalculate the current table line by applying all stored formulas.
 ;;;###autoload
 (defun org-table-recalculate (&optional all noalign)
   "Recalculate the current table line by applying all stored formulas.
@@ -2879,7 +2992,7 @@ known that the table will be realigned a little later anyway."
   (interactive "P")
   (or (memq this-command org-recalc-commands)
       (setq org-recalc-commands (cons this-command org-recalc-commands)))
   (interactive "P")
   (or (memq this-command org-recalc-commands)
       (setq org-recalc-commands (cons this-command org-recalc-commands)))
-  (unless (org-at-table-p) (error "Not at a table"))
+  (unless (org-at-table-p) (user-error "Not at a table"))
   (if (or (eq all 'iterate) (equal all '(16)))
       (org-table-iterate)
     (org-table-get-specials)
   (if (or (eq all 'iterate) (equal all '(16)))
       (org-table-iterate)
     (org-table-get-specials)
@@ -2902,7 +3015,7 @@ known that the table will be realigned a little later anyway."
                                        (car x)) 1)
                                      (cdr x)))
                        (if (assoc (car x) eqlist1)
                                        (car x)) 1)
                                      (cdr x)))
                        (if (assoc (car x) eqlist1)
-                           (error "\"%s=\" formula tries to overwrite existing formula for column %s"
+                           (user-error "\"%s=\" formula tries to overwrite existing formula for column %s"
                                   lhs1 (car x))))
                      (cons
                       (org-table-formula-handle-first/last-rc (car x))
                                   lhs1 (car x))))
                      (cons
                       (org-table-formula-handle-first/last-rc (car x))
@@ -2947,7 +3060,7 @@ known that the table will be realigned a little later anyway."
        (if a (setq name1 (format "@%d$%d" (org-table-line-to-dline (nth 1 a))
                                  (nth 2 a))))
        (when (member name1 seen-fields)
        (if a (setq name1 (format "@%d$%d" (org-table-line-to-dline (nth 1 a))
                                  (nth 2 a))))
        (when (member name1 seen-fields)
-         (error "Several field/range formulas try to set %s" name1))
+         (user-error "Several field/range formulas try to set %s" name1))
        (push name1 seen-fields)
 
        (and (not a)
        (push name1 seen-fields)
 
        (and (not a)
@@ -2956,7 +3069,7 @@ known that the table will be realigned a little later anyway."
                           (condition-case nil
                               (aref org-table-dlines
                                     (string-to-number (match-string 1 name)))
                           (condition-case nil
                               (aref org-table-dlines
                                     (string-to-number (match-string 1 name)))
-                            (error (error "Invalid row number in %s"
+                            (error (user-error "Invalid row number in %s"
                                           name)))
                           (string-to-number (match-string 2 name)))))
        (when (and a (or all (equal (nth 1 a) thisline)))
                                           name)))
                           (string-to-number (match-string 2 name)))))
        (when (and a (or all (equal (nth 1 a) thisline)))
@@ -3026,7 +3139,7 @@ with the prefix ARG."
              (message "Convergence after %d iterations" i)
            (message "Table was already stable"))
          (throw 'exit t)))
              (message "Convergence after %d iterations" i)
            (message "Table was already stable"))
          (throw 'exit t)))
-      (error "No convergence after %d iterations" i))))
+      (user-error "No convergence after %d iterations" i))))
 
 ;;;###autoload
 (defun org-table-recalculate-buffer-tables ()
 
 ;;;###autoload
 (defun org-table-recalculate-buffer-tables ()
@@ -3057,7 +3170,40 @@ with the prefix ARG."
                  (message "Convergence after %d iterations" (- imax i))
                  (throw 'exit t))
              (setq checksum c1)))
                  (message "Convergence after %d iterations" (- imax i))
                  (throw 'exit t))
              (setq checksum c1)))
-         (error "No convergence after %d iterations" imax))))))
+         (user-error "No convergence after %d iterations" imax))))))
+
+(defun org-table-calc-current-TBLFM (&optional arg)
+  "Apply the #+TBLFM in the line at point to the table."
+  (interactive "P")
+  (unless (org-at-TBLFM-p) (user-error "Not at a #+TBLFM line"))
+  (let ((formula (buffer-substring
+                 (point-at-bol)
+                 (point-at-eol)))
+       s e)
+    (save-excursion
+      ;; Insert a temporary formula at right after the table
+      (goto-char (org-table-TBLFM-begin))
+      (setq s (point-marker))
+      (insert (concat formula "\n"))
+      (setq e (point-marker))
+      ;; Recalculate the table
+      (beginning-of-line 0)            ; move to the inserted line
+      (skip-chars-backward " \r\n\t")
+      (if (org-at-table-p)
+         (unwind-protect
+             (org-call-with-arg 'org-table-recalculate (or arg t))
+           ;; delete the formula inserted temporarily
+           (delete-region s e))))))
+
+(defun org-table-TBLFM-begin ()
+  "Find the beginning of the TBLFM lines and return its position.
+Return nil when the beginning of TBLFM line was not found."
+  (save-excursion
+    (when (progn (forward-line 1)
+             (re-search-backward
+              org-table-TBLFM-begin-regexp
+              nil t))
+         (point-at-bol 2))))
 
 (defun org-table-expand-lhs-ranges (equations)
   "Expand list of formulas.
 
 (defun org-table-expand-lhs-ranges (equations)
   "Expand list of formulas.
@@ -3115,7 +3261,7 @@ borders of the table using the @< @> $< $> makers."
                    len
                  (- nmax len -1)))
        (if (or (< n 1) (> n nmax))
                    len
                  (- nmax len -1)))
        (if (or (< n 1) (> n nmax))
-           (error "Reference \"%s\" in expression \"%s\" points outside table"
+           (user-error "Reference \"%s\" in expression \"%s\" points outside table"
                   (match-string 0 s) s))
        (setq start (match-beginning 0))
        (setq s (replace-match (format "%s%d" (match-string 1 s) n) t t s)))))
                   (match-string 0 s) s))
        (setq start (match-beginning 0))
        (setq s (replace-match (format "%s%d" (match-string 1 s) n) t t s)))))
@@ -3214,7 +3360,7 @@ Parameters get priority."
   (interactive)
   (when (save-excursion (beginning-of-line 1) (let ((case-fold-search t)) (looking-at "[ \t]*#\\+TBLFM")))
     (beginning-of-line 0))
   (interactive)
   (when (save-excursion (beginning-of-line 1) (let ((case-fold-search t)) (looking-at "[ \t]*#\\+TBLFM")))
     (beginning-of-line 0))
-  (unless (org-at-table-p) (error "Not at a table"))
+  (unless (org-at-table-p) (user-error "Not at a table"))
   (org-table-get-specials)
   (let ((key (org-table-current-field-formula 'key 'noerror))
        (eql (sort (org-table-get-stored-formulas 'noerror)
   (org-table-get-specials)
   (let ((key (org-table-current-field-formula 'key 'noerror))
        (eql (sort (org-table-get-stored-formulas 'noerror)
@@ -3436,7 +3582,7 @@ minutes or seconds."
    ((org-at-regexp-p "\\(\\<[a-zA-Z]\\)&")
     (if (memq dir '(left right))
        (org-rematch-and-replace 1 (eq dir 'left))
    ((org-at-regexp-p "\\(\\<[a-zA-Z]\\)&")
     (if (memq dir '(left right))
        (org-rematch-and-replace 1 (eq dir 'left))
-      (error "Cannot shift reference in this direction")))
+      (user-error "Cannot shift reference in this direction")))
    ((org-at-regexp-p "\\(\\<[a-zA-Z]\\{1,2\\}\\)\\([0-9]+\\)")
     ;; A B3-like reference
     (if (memq dir '(up down))
    ((org-at-regexp-p "\\(\\<[a-zA-Z]\\{1,2\\}\\)\\([0-9]+\\)")
     ;; A B3-like reference
     (if (memq dir '(up down))
@@ -3451,7 +3597,7 @@ minutes or seconds."
 
 (defun org-rematch-and-replace (n &optional decr hline)
   "Re-match the group N, and replace it with the shifted reference."
 
 (defun org-rematch-and-replace (n &optional decr hline)
   "Re-match the group N, and replace it with the shifted reference."
-  (or (match-end n) (error "Cannot shift reference in this direction"))
+  (or (match-end n) (user-error "Cannot shift reference in this direction"))
   (goto-char (match-beginning n))
   (and (looking-at (regexp-quote (match-string n)))
        (replace-match (org-table-shift-refpart (match-string 0) decr hline)
   (goto-char (match-beginning n))
   (and (looking-at (regexp-quote (match-string n)))
        (replace-match (org-table-shift-refpart (match-string 0) decr hline)
@@ -3487,7 +3633,7 @@ a translation reference."
        (org-number-to-letters
         (max 1 (+ (org-letters-to-number ref) (if decr -1 1)))))
 
        (org-number-to-letters
         (max 1 (+ (org-letters-to-number ref) (if decr -1 1)))))
 
-       (t (error "Cannot shift reference"))))))
+       (t (user-error "Cannot shift reference"))))))
 
 (defun org-table-fedit-toggle-coordinates ()
   "Toggle the display of coordinates in the referenced table."
 
 (defun org-table-fedit-toggle-coordinates ()
   "Toggle the display of coordinates in the referenced table."
@@ -3519,14 +3665,14 @@ With prefix ARG, apply the new formulas to the table."
        (while (string-match "[ \t]*\n[ \t]*" form)
          (setq form (replace-match " " t t form)))
        (when (assoc var eql)
        (while (string-match "[ \t]*\n[ \t]*" form)
          (setq form (replace-match " " t t form)))
        (when (assoc var eql)
-         (error "Double formulas for %s" var))
+         (user-error "Double formulas for %s" var))
        (push (cons var form) eql)))
     (setq org-pos nil)
     (set-window-configuration org-window-configuration)
     (select-window sel-win)
     (goto-char pos)
     (unless (org-at-table-p)
        (push (cons var form) eql)))
     (setq org-pos nil)
     (set-window-configuration org-window-configuration)
     (select-window sel-win)
     (goto-char pos)
     (unless (org-at-table-p)
-      (error "Lost table position - cannot install formulas"))
+      (user-error "Lost table position - cannot install formulas"))
     (org-table-store-formulas eql)
     (move-marker pos nil)
     (kill-buffer "*Edit Formulas*")
     (org-table-store-formulas eql)
     (move-marker pos nil)
     (kill-buffer "*Edit Formulas*")
@@ -3556,14 +3702,14 @@ With prefix ARG, apply the new formulas to the table."
       (call-interactively 'lisp-indent-line))
      ((looking-at "[$&@0-9a-zA-Z]+ *= *[^ \t\n']") (goto-char pos))
      ((not (fboundp 'pp-buffer))
       (call-interactively 'lisp-indent-line))
      ((looking-at "[$&@0-9a-zA-Z]+ *= *[^ \t\n']") (goto-char pos))
      ((not (fboundp 'pp-buffer))
-      (error "Cannot pretty-print.  Command `pp-buffer' is not available"))
+      (user-error "Cannot pretty-print.  Command `pp-buffer' is not available"))
      ((looking-at "[$&@0-9a-zA-Z]+ *= *'(")
       (goto-char (- (match-end 0) 2))
       (setq beg (point))
       (setq ind (make-string (current-column) ?\ ))
       (condition-case nil (forward-sexp 1)
        (error
      ((looking-at "[$&@0-9a-zA-Z]+ *= *'(")
       (goto-char (- (match-end 0) 2))
       (setq beg (point))
       (setq ind (make-string (current-column) ?\ ))
       (condition-case nil (forward-sexp 1)
        (error
-        (error "Cannot pretty-print Lisp expression: Unbalanced parenthesis")))
+        (user-error "Cannot pretty-print Lisp expression: Unbalanced parenthesis")))
       (setq end (point))
       (save-restriction
        (narrow-to-region beg end)
       (setq end (point))
       (save-restriction
        (narrow-to-region beg end)
@@ -3615,7 +3761,7 @@ With prefix ARG, apply the new formulas to the table."
                  ((org-at-regexp-p "\\$[a-zA-Z][a-zA-Z0-9]*") 'name)
                  ((org-at-regexp-p "\\$[0-9]+") 'column)
                  ((not local) nil)
                  ((org-at-regexp-p "\\$[a-zA-Z][a-zA-Z0-9]*") 'name)
                  ((org-at-regexp-p "\\$[0-9]+") 'column)
                  ((not local) nil)
-                 (t (error "No reference at point")))
+                 (t (user-error "No reference at point")))
            match (and what (or match (match-string 0))))
       (when (and  match (not (equal (match-beginning 0) (point-at-bol))))
        (org-table-add-rectangle-overlay (match-beginning 0) (match-end 0)
            match (and what (or match (match-string 0))))
       (when (and  match (not (equal (match-beginning 0) (point-at-bol))))
        (org-table-add-rectangle-overlay (match-beginning 0) (match-end 0)
@@ -3682,7 +3828,7 @@ With prefix ARG, apply the new formulas to the table."
              (goto-char (match-beginning 1))
              (org-table-highlight-rectangle)
              (message "Named column (column %s)" (cdr e)))
              (goto-char (match-beginning 1))
              (org-table-highlight-rectangle)
              (message "Named column (column %s)" (cdr e)))
-         (error "Column name not found")))
+         (user-error "Column name not found")))
        ((eq what 'column)
        ;; column number
        (org-table-goto-column (string-to-number (substring match 1)))
        ((eq what 'column)
        ;; column number
        (org-table-goto-column (string-to-number (substring match 1)))
@@ -3695,10 +3841,10 @@ With prefix ARG, apply the new formulas to the table."
              (goto-char (match-beginning 1))
              (org-table-highlight-rectangle)
              (message "Local parameter."))
              (goto-char (match-beginning 1))
              (org-table-highlight-rectangle)
              (message "Local parameter."))
-         (error "Parameter not found")))
+         (user-error "Parameter not found")))
        (t
        (cond
        (t
        (cond
-        ((not var) (error "No reference at point"))
+        ((not var) (user-error "No reference at point"))
         ((setq e (assoc var org-table-formula-constants-local))
          (message "Local Constant: $%s=%s in #+CONSTANTS line."
                   var (cdr e)))
         ((setq e (assoc var org-table-formula-constants-local))
          (message "Local Constant: $%s=%s in #+CONSTANTS line."
                   var (cdr e)))
@@ -3708,7 +3854,7 @@ With prefix ARG, apply the new formulas to the table."
         ((setq e (and (fboundp 'constants-get) (constants-get var)))
          (message "Constant: $%s=%s, from `constants.el'%s."
                   var e (format " (%s units)" constants-unit-system)))
         ((setq e (and (fboundp 'constants-get) (constants-get var)))
          (message "Constant: $%s=%s, from `constants.el'%s."
                   var e (format " (%s units)" constants-unit-system)))
-        (t (error "Undefined name $%s" var)))))
+        (t (user-error "Undefined name $%s" var)))))
       (goto-char pos)
       (when (and org-show-positions
                 (not (memq this-command '(org-table-fedit-scroll
       (goto-char pos)
       (when (and org-show-positions
                 (not (memq this-command '(org-table-fedit-scroll
@@ -3717,9 +3863,10 @@ With prefix ARG, apply the new formulas to the table."
        (push org-table-current-begin-pos org-show-positions)
        (let ((min (apply 'min org-show-positions))
              (max (apply 'max org-show-positions)))
        (push org-table-current-begin-pos org-show-positions)
        (let ((min (apply 'min org-show-positions))
              (max (apply 'max org-show-positions)))
-         (goto-char min) (recenter 0)
+         (set-window-start (selected-window) min)
          (goto-char max)
          (goto-char max)
-         (or (pos-visible-in-window-p max) (recenter -1))))
+         (or (pos-visible-in-window-p max)
+             (set-window-start (selected-window) max))))
       (select-window win))))
 
 (defun org-table-force-dataline ()
       (select-window win))))
 
 (defun org-table-force-dataline ()
@@ -3734,7 +3881,7 @@ With prefix ARG, apply the new formulas to the table."
             (goto-char (if (< (abs (- p1 (point))) (abs (- p2 (point))))
                            p1 p2)))
            ((or p1 p2) (goto-char (or p1 p2)))
             (goto-char (if (< (abs (- p1 (point))) (abs (- p2 (point))))
                            p1 p2)))
            ((or p1 p2) (goto-char (or p1 p2)))
-           (t (error "No table dataline around here"))))))
+           (t (user-error "No table dataline around here"))))))
 
 (defun org-table-fedit-line-up ()
   "Move cursor one line up in the window showing the table."
 
 (defun org-table-fedit-line-up ()
   "Move cursor one line up in the window showing the table."
@@ -3982,7 +4129,7 @@ to execute outside of tables."
         '(arg)
         (concat "In tables, run `" (symbol-name fun) "'.\n"
                 "Outside of tables, run the binding of `"
         '(arg)
         (concat "In tables, run `" (symbol-name fun) "'.\n"
                 "Outside of tables, run the binding of `"
-                (mapconcat (lambda (x) (format "%s" x)) keys "' or `")
+                (mapconcat #'key-description keys "' or `")
                 "'.")
         '(interactive "p")
         (list 'if
                 "'.")
         '(interactive "p")
         (list 'if
@@ -3999,7 +4146,7 @@ to execute outside of tables."
 (defun orgtbl-error ()
   "Error when there is no default binding for a table key."
   (interactive)
 (defun orgtbl-error ()
   "Error when there is no default binding for a table key."
   (interactive)
-  (error "This key has no function outside tables"))
+  (user-error "This key has no function outside tables"))
 
 (defun orgtbl-setup ()
   "Setup orgtbl keymaps."
 
 (defun orgtbl-setup ()
   "Setup orgtbl keymaps."
@@ -4151,7 +4298,7 @@ to execute outside of tables."
 If it is a table to be sent away to a receiver, do it.
 With prefix arg, also recompute table."
   (interactive "P")
 If it is a table to be sent away to a receiver, do it.
 With prefix arg, also recompute table."
   (interactive "P")
-  (let ((case-fold-search t) (pos (point)) action consts-str consts cst const-str)
+  (let ((case-fold-search t) (pos (point)) action)
     (save-excursion
       (beginning-of-line 1)
       (setq action (cond
     (save-excursion
       (beginning-of-line 1)
       (setq action (cond
@@ -4169,17 +4316,7 @@ With prefix arg, also recompute table."
       (when (orgtbl-send-table 'maybe)
        (run-hooks 'orgtbl-after-send-table-hook)))
      ((eq action 'recalc)
       (when (orgtbl-send-table 'maybe)
        (run-hooks 'orgtbl-after-send-table-hook)))
      ((eq action 'recalc)
-      (save-excursion
-       (goto-char (point-min))
-       (while (re-search-forward "^[ \t]*#\\+CONSTANTS: \\(.*\\)" nil t)
-         (setq const-str (substring-no-properties (match-string 1)))
-         (setq consts (append consts (org-split-string const-str "[ \t]+")))
-         (when consts
-           (let (e)
-             (while (setq e (pop consts))
-               (if (string-match "^\\([a-zA-Z0][_a-zA-Z0-9]*\\)=\\(.*\\)" e)
-                   (push (cons (match-string 1 e) (match-string 2 e)) cst)))
-             (setq org-table-formula-constants-local cst)))))
+      (org-table-set-constants)
       (save-excursion
        (beginning-of-line 1)
        (skip-chars-backward " \r\n\t")
       (save-excursion
        (beginning-of-line 1)
        (skip-chars-backward " \r\n\t")
@@ -4264,31 +4401,6 @@ overwritten, and the table is not marked as requiring realignment."
 (defvar orgtbl-exp-regexp "^\\([-+]?[0-9][0-9.]*\\)[eE]\\([-+]?[0-9]+\\)$"
   "Regular expression matching exponentials as produced by calc.")
 
 (defvar orgtbl-exp-regexp "^\\([-+]?[0-9][0-9.]*\\)[eE]\\([-+]?[0-9]+\\)$"
   "Regular expression matching exponentials as produced by calc.")
 
-(defun orgtbl-export (table target)
-  (require 'org-exp)
-  (let ((func (intern (concat "orgtbl-to-" (symbol-name target))))
-       (lines (org-split-string table "[ \t]*\n[ \t]*"))
-       org-table-last-alignment org-table-last-column-widths
-       maxcol column)
-    (if (not (fboundp func))
-       (error "Cannot export orgtbl table to %s" target))
-    (setq lines (org-table-clean-before-export lines))
-    (setq table
-         (mapcar
-          (lambda (x)
-            (if (string-match org-table-hline-regexp x)
-                'hline
-              (org-split-string (org-trim x) "\\s-*|\\s-*")))
-          lines))
-    (setq maxcol (apply 'max (mapcar (lambda (x) (if (listp x) (length x) 0))
-                                    table)))
-    (loop for i from (1- maxcol) downto 0 do
-         (setq column (mapcar (lambda (x) (if (listp x) (nth i x) nil)) table))
-         (setq column (delq nil column))
-         (push (apply 'max (mapcar 'string-width column)) org-table-last-column-widths)
-         (push (> (/ (apply '+ (mapcar (lambda (x) (if (string-match org-table-number-regexp x) 1 0)) column)) maxcol) org-table-number-fraction) org-table-last-alignment))
-    (funcall func table nil)))
-
 (defun orgtbl-gather-send-defs ()
   "Gather a plist of :name, :transform, :params for each destination before
 a radio table."
 (defun orgtbl-gather-send-defs ()
   "Gather a plist of :name, :transform, :params for each destination before
 a radio table."
@@ -4311,15 +4423,15 @@ a radio table."
   (save-excursion
     (goto-char (point-min))
     (unless (re-search-forward
   (save-excursion
     (goto-char (point-min))
     (unless (re-search-forward
-            (concat "BEGIN RECEIVE ORGTBL +" name "\\([ \t]\\|$\\)") nil t)
-      (error "Don't know where to insert translated table"))
+            (concat "BEGIN +RECEIVE +ORGTBL +" name "\\([ \t]\\|$\\)") nil t)
+      (user-error "Don't know where to insert translated table"))
     (goto-char (match-beginning 0))
     (beginning-of-line 2)
     (save-excursion
       (let ((beg (point)))
        (unless (re-search-forward
     (goto-char (match-beginning 0))
     (beginning-of-line 2)
     (save-excursion
       (let ((beg (point)))
        (unless (re-search-forward
-                (concat "END RECEIVE ORGTBL +" name) nil t)
-         (error "Cannot find end of insertion region"))
+                (concat "END +RECEIVE +ORGTBL +" name) nil t)
+         (user-error "Cannot find end of insertion region"))
        (beginning-of-line 1)
        (delete-region beg (point))))
     (insert txt "\n")))
        (beginning-of-line 1)
        (delete-region beg (point))))
     (insert txt "\n")))
@@ -4332,7 +4444,7 @@ for a horizontal separator line, or a list of field values as strings.
 The table is taken from the parameter TXT, or from the buffer at point."
   (unless txt
     (unless (org-at-table-p)
 The table is taken from the parameter TXT, or from the buffer at point."
   (unless txt
     (unless (org-at-table-p)
-      (error "No table at point")))
+      (user-error "No table at point")))
   (let* ((txt (or txt
                  (buffer-substring-no-properties (org-table-begin)
                                                  (org-table-end))))
   (let* ((txt (or txt
                  (buffer-substring-no-properties (org-table-begin)
                                                  (org-table-end))))
@@ -4351,7 +4463,7 @@ With argument MAYBE, fail quietly if no transformation is defined for
 this table."
   (interactive)
   (catch 'exit
 this table."
   (interactive)
   (catch 'exit
-    (unless (org-at-table-p) (error "Not at a table"))
+    (unless (org-at-table-p) (user-error "Not at a table"))
     ;; when non-interactive, we assume align has just happened.
     (when (org-called-interactively-p 'any) (org-table-align))
     (let ((dests (orgtbl-gather-send-defs))
     ;; when non-interactive, we assume align has just happened.
     (when (org-called-interactively-p 'any) (org-table-align))
     (let ((dests (orgtbl-gather-send-defs))
@@ -4359,7 +4471,7 @@ this table."
                                               (org-table-end)))
          (ntbl 0))
       (unless dests (if maybe (throw 'exit nil)
                                               (org-table-end)))
          (ntbl 0))
       (unless dests (if maybe (throw 'exit nil)
-                     (error "Don't know how to transform this table")))
+                     (user-error "Don't know how to transform this table")))
       (dolist (dest dests)
        (let* ((name (plist-get dest :name))
               (transform (plist-get dest :transform))
       (dolist (dest dests)
        (let* ((name (plist-get dest :name))
               (transform (plist-get dest :transform))
@@ -4392,7 +4504,7 @@ this table."
                                     skipcols i0))
               (txt (if (fboundp transform)
                        (funcall transform table params)
                                     skipcols i0))
               (txt (if (fboundp transform)
                        (funcall transform table params)
-                     (error "No such transformation function %s" transform))))
+                     (user-error "No such transformation function %s" transform))))
          (orgtbl-send-replace-tbl name txt))
        (setq ntbl (1+ ntbl)))
       (message "Table converted and installed at %d receiver location%s"
          (orgtbl-send-replace-tbl name txt))
        (setq ntbl (1+ ntbl)))
       (message "Table converted and installed at %d receiver location%s"
@@ -4422,7 +4534,7 @@ First element has index 0, or I0 if given."
         (commented (save-excursion (beginning-of-line 1)
                                    (cond ((looking-at re1) t)
                                          ((looking-at re2) nil)
         (commented (save-excursion (beginning-of-line 1)
                                    (cond ((looking-at re1) t)
                                          ((looking-at re2) nil)
-                                         (t (error "Not at an org table")))))
+                                         (t (user-error "Not at an org table")))))
         (re (if commented re1 re2))
         beg end)
     (save-excursion
         (re (if commented re1 re2))
         beg end)
     (save-excursion
@@ -4440,7 +4552,7 @@ First element has index 0, or I0 if given."
   (let* ((e (assq major-mode orgtbl-radio-table-templates))
         (txt (nth 1 e))
         name pos)
   (let* ((e (assq major-mode orgtbl-radio-table-templates))
         (txt (nth 1 e))
         name pos)
-    (unless e (error "No radio table setup defined for %s" major-mode))
+    (unless e (user-error "No radio table setup defined for %s" major-mode))
     (setq name (read-string "Table name: "))
     (while (string-match "%n" txt)
       (setq txt (replace-match name t t txt)))
     (setq name (read-string "Table name: "))
     (while (string-match "%n" txt)
       (setq txt (replace-match name t t txt)))
@@ -4474,7 +4586,8 @@ First element has index 0, or I0 if given."
     fmt))
 
 (defsubst orgtbl-apply-fmt (fmt &rest args)
     fmt))
 
 (defsubst orgtbl-apply-fmt (fmt &rest args)
-  "Apply format FMT to the arguments.  NIL FMTs return the first argument."
+  "Apply format FMT to arguments ARGS.
+When FMT is nil, return the first argument from ARGS."
   (cond ((functionp fmt) (apply fmt args))
        (fmt (apply 'format fmt args))
        (args (car args))
   (cond ((functionp fmt) (apply fmt args))
        (fmt (apply 'format fmt args))
        (args (car args))
@@ -4504,7 +4617,7 @@ First element has index 0, or I0 if given."
                                   f)))
             line)))
       (push (if *orgtbl-lfmt*
                                   f)))
             line)))
       (push (if *orgtbl-lfmt*
-               (orgtbl-apply-fmt *orgtbl-lfmt* line)
+               (apply #'orgtbl-apply-fmt *orgtbl-lfmt* line)
              (concat (orgtbl-eval-str *orgtbl-lstart*)
                      (mapconcat 'identity line *orgtbl-sep*)
                      (orgtbl-eval-str *orgtbl-lend*)))
              (concat (orgtbl-eval-str *orgtbl-lstart*)
                      (mapconcat 'identity line *orgtbl-sep*)
                      (orgtbl-eval-str *orgtbl-lend*)))
@@ -4523,12 +4636,15 @@ First element has index 0, or I0 if given."
                     (orgtbl-format-line prevline))))))
 
 ;;;###autoload
                     (orgtbl-format-line prevline))))))
 
 ;;;###autoload
-(defun orgtbl-to-generic (table params)
+(defun orgtbl-to-generic (table params &optional backend)
   "Convert the orgtbl-mode TABLE to some other format.
 This generic routine can be used for many standard cases.
 TABLE is a list, each entry either the symbol `hline' for a horizontal
 separator line, or a list of fields for that line.
 PARAMS is a property list of parameters that can influence the conversion.
   "Convert the orgtbl-mode TABLE to some other format.
 This generic routine can be used for many standard cases.
 TABLE is a list, each entry either the symbol `hline' for a horizontal
 separator line, or a list of fields for that line.
 PARAMS is a property list of parameters that can influence the conversion.
+A third optional argument BACKEND can be used to convert the content of
+the cells using a specific export back-end.
+
 For the generic converter, some parameters are obligatory: you need to
 specify either :lfmt, or all of (:lstart :lend :sep).
 
 For the generic converter, some parameters are obligatory: you need to
 specify either :lfmt, or all of (:lstart :lend :sep).
 
@@ -4599,22 +4715,31 @@ directly by `orgtbl-send-table'.  See manual."
         (*orgtbl-llfmt* (or (plist-get params :llfmt) *orgtbl-lfmt*))
         (*orgtbl-fmt* (plist-get params :fmt))
         *orgtbl-rtn*)
         (*orgtbl-llfmt* (or (plist-get params :llfmt) *orgtbl-lfmt*))
         (*orgtbl-fmt* (plist-get params :fmt))
         *orgtbl-rtn*)
-
+    ;; Convert cells content to backend BACKEND
+    (when backend
+      (setq *orgtbl-table*
+           (mapcar
+            (lambda(r)
+              (if (listp r)
+                  (mapcar
+                   (lambda (c)
+                     (org-trim (org-export-string-as c backend t '(:with-tables t))))
+                   r)
+                r))
+            *orgtbl-table*)))
     ;; Put header
     (unless splicep
       (when (plist-member params :tstart)
        (let ((tstart (orgtbl-eval-str (plist-get params :tstart))))
          (if tstart (push tstart *orgtbl-rtn*)))))
     ;; Put header
     (unless splicep
       (when (plist-member params :tstart)
        (let ((tstart (orgtbl-eval-str (plist-get params :tstart))))
          (if tstart (push tstart *orgtbl-rtn*)))))
-
-    ;; Do we have a heading section?  If so, format it and handle the
-    ;; trailing hline.
+    ;; If we have a heading, format it and handle the trailing hline.
     (if (and (not splicep)
             (or (consp (car *orgtbl-table*))
                 (consp (nth 1 *orgtbl-table*)))
             (memq 'hline (cdr *orgtbl-table*)))
        (progn
          (when (eq 'hline (car *orgtbl-table*))
     (if (and (not splicep)
             (or (consp (car *orgtbl-table*))
                 (consp (nth 1 *orgtbl-table*)))
             (memq 'hline (cdr *orgtbl-table*)))
        (progn
          (when (eq 'hline (car *orgtbl-table*))
-           ;; there is a hline before the first data line
+           ;; There is a hline before the first data line
            (and hline (push hline *orgtbl-rtn*))
            (pop *orgtbl-table*))
          (let* ((*orgtbl-lstart* (or (plist-get params :hlstart)
            (and hline (push hline *orgtbl-rtn*))
            (pop *orgtbl-table*))
          (let* ((*orgtbl-lstart* (or (plist-get params :hlstart)
@@ -4632,15 +4757,12 @@ directly by `orgtbl-send-table'.  See manual."
            (orgtbl-format-section 'hline))
          (if (and hline (not skipheadrule)) (push hline *orgtbl-rtn*))
          (pop *orgtbl-table*)))
            (orgtbl-format-section 'hline))
          (if (and hline (not skipheadrule)) (push hline *orgtbl-rtn*))
          (pop *orgtbl-table*)))
-
     ;; Now format the main section.
     (orgtbl-format-section nil)
     ;; Now format the main section.
     (orgtbl-format-section nil)
-
     (unless splicep
       (when (plist-member params :tend)
        (let ((tend (orgtbl-eval-str (plist-get params :tend))))
          (if tend (push tend *orgtbl-rtn*)))))
     (unless splicep
       (when (plist-member params :tend)
        (let ((tend (orgtbl-eval-str (plist-get params :tend))))
          (if tend (push tend *orgtbl-rtn*)))))
-
     (mapconcat (if remove-newlines
                   (lambda (tend)
                     (replace-regexp-in-string "[\n\r\t\f]" "\\\\n" tend))
     (mapconcat (if remove-newlines
                   (lambda (tend)
                     (replace-regexp-in-string "[\n\r\t\f]" "\\\\n" tend))
@@ -4698,7 +4820,8 @@ this function is called."
           :tend "\\end{tabular}"
           :lstart "" :lend " \\\\" :sep " & "
           :efmt "%s\\,(%s)" :hline "\\hline")))
           :tend "\\end{tabular}"
           :lstart "" :lend " \\\\" :sep " & "
           :efmt "%s\\,(%s)" :hline "\\hline")))
-    (orgtbl-to-generic table (org-combine-plists params2 params))))
+    (require 'ox-latex)
+    (orgtbl-to-generic table (org-combine-plists params2 params) 'latex)))
 
 ;;;###autoload
 (defun orgtbl-to-html (table params)
 
 ;;;###autoload
 (defun orgtbl-to-html (table params)
@@ -4714,22 +4837,14 @@ Currently this function recognizes the following parameters:
 The general parameters :skip and :skipcols have already been applied when
 this function is called.  The function does *not* use `orgtbl-to-generic',
 so you cannot specify parameters for it."
 The general parameters :skip and :skipcols have already been applied when
 this function is called.  The function does *not* use `orgtbl-to-generic',
 so you cannot specify parameters for it."
-  (let* ((splicep (plist-get params :splice))
-        (html-table-tag org-export-html-table-tag)
-        html)
-    ;; Just call the formatter we already have
-    ;; We need to make text lines for it, so put the fields back together.
-    (setq html (org-format-org-table-html
-               (mapcar
-                (lambda (x)
-                  (if (eq x 'hline)
-                      "|----+----|"
-                    (concat "| " (mapconcat 'org-html-expand x " | ") " |")))
-                table)
-               splicep))
-    (if (string-match "\n+\\'" html)
-       (setq html (replace-match "" t t html)))
-    html))
+  (require 'ox-html)
+  (let ((output (org-export-string-as
+                (orgtbl-to-orgtbl table nil) 'html t '(:with-tables t))))
+    (if (not (plist-get params :splice)) output
+      (org-trim
+       (replace-regexp-in-string
+       "\\`<table .*>\n" ""
+       (replace-regexp-in-string "</table>\n*\\'" "" output))))))
 
 ;;;###autoload
 (defun orgtbl-to-texinfo (table params)
 
 ;;;###autoload
 (defun orgtbl-to-texinfo (table params)
@@ -4768,7 +4883,8 @@ this function is called."
           :tend "@end multitable"
           :lstart "@item " :lend "" :sep " @tab "
           :hlstart "@headitem ")))
           :tend "@end multitable"
           :lstart "@item " :lend "" :sep " @tab "
           :hlstart "@headitem ")))
-    (orgtbl-to-generic table (org-combine-plists params2 params))))
+    (require 'ox-texinfo)
+    (orgtbl-to-generic table (org-combine-plists params2 params) 'texinfo)))
 
 ;;;###autoload
 (defun orgtbl-to-orgtbl (table params)
 
 ;;;###autoload
 (defun orgtbl-to-orgtbl (table params)
@@ -4815,22 +4931,22 @@ it here: http://gnuvola.org/software/j/aa2u/ascii-art-to-unicode.el."
       (unless (delq nil (mapcar (lambda (l) (string-match "aa2u" (car l))) org-stored-links))
        (push '("http://gnuvola.org/software/j/aa2u/ascii-art-to-unicode.el"
                "Link to ascii-art-to-unicode.el") org-stored-links))
       (unless (delq nil (mapcar (lambda (l) (string-match "aa2u" (car l))) org-stored-links))
        (push '("http://gnuvola.org/software/j/aa2u/ascii-art-to-unicode.el"
                "Link to ascii-art-to-unicode.el") org-stored-links))
-      (error "Please download ascii-art-to-unicode.el (use C-c C-l to insert the link to it)"))
+      (user-error "Please download ascii-art-to-unicode.el (use C-c C-l to insert the link to it)"))
     (buffer-string)))
 
 (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.
 
     (buffer-string)))
 
 (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.
 
-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
 \"@I$2..@II$2\".  All the references must be absolute, not relative.
 
 The return value is either a single string for a single field, or a
 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.
 
 The return value is either a single string for a single field, or a
-list of the fields in the rectangle ."
+list of the fields in the rectangle."
   (save-match-data
     (let ((case-fold-search t) (id-loc nil)
          ;; Protect a bunch of variables from being overwritten
   (save-match-data
     (let ((case-fold-search t) (id-loc nil)
          ;; Protect a bunch of variables from being overwritten
@@ -4851,12 +4967,13 @@ list of the fields in the rectangle ."
          (save-excursion
            (goto-char (point-min))
            (if (re-search-forward
          (save-excursion
            (goto-char (point-min))
            (if (re-search-forward
-                (concat "^[ \t]*#\\+tblname:[ \t]*" (regexp-quote name-or-id) "[ \t]*$")
+                (concat "^[ \t]*#\\+\\(tbl\\)?name:[ \t]*"
+                        (regexp-quote name-or-id) "[ \t]*$")
                 nil t)
                (setq buffer (current-buffer) loc (match-beginning 0))
              (setq id-loc (org-id-find name-or-id 'marker))
              (unless (and id-loc (markerp id-loc))
                 nil t)
                (setq buffer (current-buffer) loc (match-beginning 0))
              (setq id-loc (org-id-find name-or-id 'marker))
              (unless (and id-loc (markerp id-loc))
-               (error "Can't find remote table \"%s\"" name-or-id))
+               (user-error "Can't find remote table \"%s\"" name-or-id))
              (setq buffer (marker-buffer id-loc)
                    loc (marker-position id-loc))
              (move-marker id-loc nil)))
              (setq buffer (marker-buffer id-loc)
                    loc (marker-position id-loc))
              (move-marker id-loc nil)))
@@ -4868,7 +4985,7 @@ list of the fields in the rectangle ."
                (forward-char 1)
                (unless (and (re-search-forward "^\\(\\*+ \\)\\|[ \t]*|" nil t)
                             (not (match-beginning 1)))
                (forward-char 1)
                (unless (and (re-search-forward "^\\(\\*+ \\)\\|[ \t]*|" nil t)
                             (not (match-beginning 1)))
-                 (error "Cannot find a table at NAME or ID %s" name-or-id))
+                 (user-error "Cannot find a table at NAME or ID %s" name-or-id))
                (setq tbeg (point-at-bol))
                (org-table-get-specials)
                (setq form (org-table-formula-substitute-names
                (setq tbeg (point-at-bol))
                (org-table-get-specials)
                (setq form (org-table-formula-substitute-names
@@ -4879,6 +4996,38 @@ list of the fields in the rectangle ."
                      (org-table-get-range (match-string 0 form) tbeg 1))
                  form)))))))))
 
                      (org-table-get-range (match-string 0 form) tbeg 1))
                  form)))))))))
 
+(defmacro org-define-lookup-function (mode)
+  (let ((mode-str (symbol-name mode))
+       (first-p (equal mode 'first))
+       (all-p (equal mode 'all)))
+    (let ((plural-str (if all-p "s" "")))
+      `(defun ,(intern (format "org-lookup-%s" mode-str)) (val s-list r-list &optional predicate)
+        ,(format "Find %s occurrence%s of VAL in S-LIST; return corresponding element%s of R-LIST.
+If R-LIST is nil, return matching element%s of S-LIST.
+If PREDICATE is not nil, use it instead of `equal' to match VAL.
+Matching is done by (PREDICATE VAL S), where S is an element of S-LIST.
+This function is generated by a call to the macro `org-define-lookup-function'."
+                 mode-str plural-str plural-str plural-str)
+        (let ,(let ((lvars '((p (or predicate 'equal))
+                             (sl s-list)
+                             (rl (or r-list s-list))
+                             (ret nil))))
+                (if first-p (add-to-list 'lvars '(match-p nil)))
+                lvars)
+          (while ,(if first-p '(and (not match-p) sl) 'sl)
+            (progn
+              (if (funcall p val (car sl))
+                  (progn
+                    ,(if first-p '(setq match-p t))
+                    (let ((rval (car rl)))
+                      (setq ret ,(if all-p '(append ret (list rval)) 'rval)))))
+              (setq sl (cdr sl) rl (cdr rl))))
+          ret)))))
+
+(org-define-lookup-function first)
+(org-define-lookup-function last)
+(org-define-lookup-function all)
+
 (provide 'org-table)
 
 ;; Local variables:
 (provide 'org-table)
 
 ;; Local variables: