瀏覽代碼

org-table: Use "ox.el" internally for radio tables

* lisp/org-table.el (org-table-clean-before-export, orgtbl-get-fmt,
  orgtbl-apply-fmt, orgtbl-eval-str, orgtbl-format-line,
  orgtbl-format-section): Remove functions.
(org-table-clean-did-remove-column, *orgtbl-table*, *orgtbl-rtn*,
  *orgtbl-hline*, *orgtbl-sep*, *orgtbl-default-fmt*, *orgtbl-fmt*,
  *orgtbl-efmt*, *orgtbl-lfmt*, *orgtbl-llfmt*, *orgtbl-lstart*,
  *orgtbl-llstart*, *orgtbl-lend*, *orgtbl-llend*): Remove variables.

(org-table-export, orgtbl-send-table): Apply function removal.  Do not
set `org-table-last-alignment' and `org-table-last-column-widths'
anymore.
(org-table-to-lisp, orgtbl-send-replace-tbl): Small refactoring.

(org-table--to-generic-table, org-table--to-generic-row,
org-table--to-generic-cell): New functions.
(orgtbl-to-generic): Rewrite function.  Handle :skip and :skipcols
parameters.
(orgtbl-to-latex, orgtbl-to-html, orgtbl-to-texinfo, orgtbl-to-orgtbl,
orgtbl-to-unicode): Use new `orgtbl-to-generic' features.

* testing/lisp/test-org-table.el (test-org-table/to-generic,
  test-org-table/to-latex, test-org-table/to-texinfo,
  test-org-table/to-html, test-org-table/to-unicode,
  test-org-table/send-region): New tests.

* doc/org.texi (Radio tables, A @LaTeX{} example, Translator
  functions): Update documentation.

* etc/ORG-NEWS (argument): Document new features.
Nicolas Goaziou 10 年之前
父節點
當前提交
9209aa3c9d
共有 4 個文件被更改,包括 891 次插入532 次删除
  1. 37 58
      doc/org.texi
  2. 7 0
      etc/ORG-NEWS
  3. 501 474
      lisp/org-table.el
  4. 346 0
      testing/lisp/test-org-table.el

+ 37 - 58
doc/org.texi

@@ -17508,10 +17508,6 @@ calculation marks, that column is automatically discarded as well.
 Please note that the translator function sees the table @emph{after} the
 Please note that the translator function sees the table @emph{after} the
 removal of these columns, the function never knows that there have been
 removal of these columns, the function never knows that there have been
 additional columns.
 additional columns.
-
-@item :no-escape t
-When non-@code{nil}, do not escape special characters @code{&%#_^} when exporting
-the table.  The default value is @code{nil}.
 @end table
 @end table
 
 
 @noindent
 @noindent
@@ -17619,14 +17615,15 @@ Month & \multicolumn@{1@}@{c@}@{Days@} & Nr.\ sold & per day\\
 @end example
 @end example
 
 
 The @LaTeX{} translator function @code{orgtbl-to-latex} is already part of
 The @LaTeX{} translator function @code{orgtbl-to-latex} is already part of
-Orgtbl mode.  It uses a @code{tabular} environment to typeset the table
-and marks horizontal lines with @code{\hline}.  Furthermore, it
-interprets the following parameters (see also @pxref{Translator functions}):
+Orgtbl mode.  By default, it uses a @code{tabular} environment to typeset the
+table and marks horizontal lines with @code{\hline}.  You can control the
+output through several parameters (see also @pxref{Translator functions}),
+including the following ones :
 
 
 @table @code
 @table @code
 @item :splice nil/t
 @item :splice nil/t
-When set to t, return only table body lines, don't wrap them into a
-tabular environment.  Default is @code{nil}.
+When non-nil, return only table body lines, don't wrap them into a tabular
+environment.  Default is @code{nil}.
 
 
 @item :fmt fmt
 @item :fmt fmt
 A format to be used to wrap each field, it should contain @code{%s} for the
 A format to be used to wrap each field, it should contain @code{%s} for the
@@ -17637,14 +17634,14 @@ A function of one argument can be used in place of the strings; the
 function must return a formatted string.
 function must return a formatted string.
 
 
 @item :efmt efmt
 @item :efmt efmt
-Use this format to print numbers with exponentials.  The format should
-have @code{%s} twice for inserting mantissa and exponent, for example
-@code{"%s\\times10^@{%s@}"}.  The default is @code{"%s\\,(%s)"}.  This
-may also be a property list with column numbers and formats, for example
-@code{:efmt (2 "$%s\\times10^@{%s@}$" 4 "$%s\\cdot10^@{%s@}$")}.  After
-@code{efmt} has been applied to a value, @code{fmt} will also be
-applied.  Similar to @code{fmt}, functions of two arguments can be
-supplied instead of strings.
+Use this format to print numbers with exponentials.  The format should have
+@code{%s} twice for inserting mantissa and exponent, for example
+@code{"%s\\times10^@{%s@}"}.  This may also be a property list with column
+numbers and formats, for example @code{:efmt (2 "$%s\\times10^@{%s@}$"
+4 "$%s\\cdot10^@{%s@}$")}.  After @code{efmt} has been applied to a value,
+@code{fmt} will also be applied.  Similar to @code{fmt}, functions of two
+arguments can be supplied instead of strings.  By default, no special
+formatting is applied.
 @end table
 @end table
 
 
 @node Translator functions
 @node Translator functions
@@ -17654,54 +17651,36 @@ supplied instead of strings.
 
 
 Orgtbl mode has several translator functions built-in: @code{orgtbl-to-csv}
 Orgtbl mode has several translator functions built-in: @code{orgtbl-to-csv}
 (comma-separated values), @code{orgtbl-to-tsv} (TAB-separated values)
 (comma-separated values), @code{orgtbl-to-tsv} (TAB-separated values)
-@code{orgtbl-to-latex}, @code{orgtbl-to-html}, and @code{orgtbl-to-texinfo}.
-Except for @code{orgtbl-to-html}@footnote{The HTML translator uses the same
-code that produces tables during HTML export.}, these all use a generic
-translator, @code{orgtbl-to-generic}.  For example, @code{orgtbl-to-latex}
-itself is a very short function that computes the column definitions for the
-@code{tabular} environment, defines a few field and line separators and then
-hands processing over to the generic translator.  Here is the entire code:
-
-@lisp
-@group
-(defun orgtbl-to-latex (table params)
-  "Convert the Orgtbl mode TABLE to LaTeX."
-  (let* ((alignment (mapconcat (lambda (x) (if x "r" "l"))
-                               org-table-last-alignment ""))
-         (params2
-          (list
-           :tstart (concat "\\begin@{tabular@}@{" alignment "@}")
-           :tend "\\end@{tabular@}"
-           :lstart "" :lend " \\\\" :sep " & "
-           :efmt "%s\\,(%s)" :hline "\\hline")))
-    (orgtbl-to-generic table (org-combine-plists params2 params))))
-@end group
-@end lisp
+@code{orgtbl-to-latex}, @code{orgtbl-to-html}, @code{orgtbl-to-texinfo},
+@code{orgtbl-to-unicode} and @code{orgtbl-to-orgtbl}.  These all use
+a generic translator, @code{orgtbl-to-generic}, which, in turn, can delegate
+translations to various export back-ends (@pxref{Export back-ends}).
 
 
-As you can see, the properties passed into the function (variable
-@var{PARAMS}) are combined with the ones newly defined in the function
-(variable @var{PARAMS2}).  The ones passed into the function (i.e., the
-ones set by the @samp{ORGTBL SEND} line) take precedence.  So if you
-would like to use the @LaTeX{} translator, but wanted the line endings to
-be @samp{\\[2mm]} instead of the default @samp{\\}, you could just
-overrule the default with
+In particular, properties passed into the function (i.e., the ones set by the
+@samp{ORGTBL SEND} line) take precedence over translations defined in the
+function.  So if you would like to use the @LaTeX{} translator, but wanted
+the line endings to be @samp{\\[2mm]} instead of the default @samp{\\}, you
+could just overrule the default with
 
 
 @example
 @example
 #+ORGTBL: SEND test orgtbl-to-latex :lend " \\\\[2mm]"
 #+ORGTBL: SEND test orgtbl-to-latex :lend " \\\\[2mm]"
 @end example
 @end example
 
 
-For a new language, you can either write your own converter function in
-analogy with the @LaTeX{} translator, or you can use the generic function
-directly.  For example, if you have a language where a table is started
-with @samp{!BTBL!}, ended with @samp{!ETBL!}, and where table lines are
-started with @samp{!BL!}, ended with @samp{!EL!}, and where the field
-separator is a TAB, you could call the generic translator like this (on
-a single line!):
+For a new language, you can use the generic function to write your own
+converter function.  For example, if you have a language where a table is
+started with @samp{!BTBL!}, ended with @samp{!ETBL!}, and where table lines
+are started with @samp{!BL!}, ended with @samp{!EL!}, and where the field
+separator is a TAB, you could define your generic translator like this:
 
 
-@example
-#+ORGTBL: SEND test orgtbl-to-generic :tstart "!BTBL!" :tend "!ETBL!"
-                              :lstart "!BL! " :lend " !EL!" :sep "\t"
-@end example
+@lisp
+(defun orgtbl-to-language (table params)
+  "Convert the orgtbl-mode TABLE to language."
+  (orgtbl-to-generic
+   table
+   (org-combine-plists
+    '(:tstart "!BTBL!" :tend "!ETBL!" :lstart "!BL!" :lend "!EL!" :sep "\t")
+    params)))
+@end lisp
 
 
 @noindent
 @noindent
 Please check the documentation string of the function
 Please check the documentation string of the function

+ 7 - 0
etc/ORG-NEWS

@@ -77,6 +77,13 @@ These functions now support any element or object, not only headlines.
 *** New filter: ~org-export-filter-body-functions~
 *** New filter: ~org-export-filter-body-functions~
 Functions in this filter are applied on the body of the exported
 Functions in this filter are applied on the body of the exported
 document, befor wrapping it within the template.
 document, befor wrapping it within the template.
+*** Improve radio tables
+Radio tables feature now relies on Org's export framework ("ox.el").
+~:no-escape~ parameter no longer exists, but additional global
+parameters are now supported: ~:raw~, ~:backend~.  Moreover, there are
+new parameters specific to some pre-defined translators, e.g.,
+~:environment~ and ~:booktabs~ for ~orgtbl-to-latex~.  See translators
+docstrings (including ~orgtbl-to-generic~) for details.
 ** Miscellaneous
 ** Miscellaneous
 *** File names in links accept are now compatible with URI syntax
 *** File names in links accept are now compatible with URI syntax
 Absolute file names can now start with =///= in addition to =/=. E.g.,
 Absolute file names can now start with =///= in addition to =/=. E.g.,

文件差異過大導致無法顯示
+ 501 - 474
lisp/org-table.el


+ 346 - 0
testing/lisp/test-org-table.el

@@ -1168,6 +1168,352 @@ See also `test-org-table/copy-field'."
       (should (string= got
       (should (string= got
 		       expect)))))
 		       expect)))))
 
 
+;;; Radio Tables
+
+(ert-deftest test-org-table/to-generic ()
+  "Test `orgtbl-to-generic' specifications."
+  ;; Test :hline parameter.
+  (should
+   (equal "a\nb"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
+			     '(:hline nil))))
+  (should
+   (equal "a\n~\nb"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
+			     '(:hline "~"))))
+  ;; Test :sep parameter.
+  (should
+   (equal "a!b\nc!d"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
+	   '(:sep "!"))))
+  ;; Test :hsep parameter.
+  (should
+   (equal "a!b\nc?d"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
+	   '(:sep "?" :hsep "!"))))
+  ;; Test :tstart parameter.
+  (should
+   (equal "<begin>\na"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |") '(:tstart "<begin>"))))
+  (should
+   (equal "<begin>\na"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |")
+			     '(:tstart (lambda () "<begin>")))))
+  (should
+   (equal "a"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |")
+			     '(:tstart "<begin>" :splice t))))
+  ;; Test :tend parameter.
+  (should
+   (equal "a\n<end>"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |") '(:tend "<end>"))))
+  (should
+   (equal "a\n<end>"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |")
+			     '(:tend (lambda () "<end>")))))
+  (should
+   (equal "a"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |")
+			     '(:tend "<end>" :splice t))))
+  ;; Test :lstart parameter.
+  (should
+   (equal "> a"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| a |") '(:lstart "> "))))
+  (should
+   (equal "> a"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |")
+			     '(:lstart (lambda () "> ")))))
+  ;; Test :llstart parameter.
+  (should
+   (equal "> a\n>> b"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
+			     '(:lstart "> " :llstart ">> "))))
+  ;; Test :hlstart parameter.
+  (should
+   (equal "!> a\n> b"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
+			     '(:lstart "> " :hlstart "!> "))))
+  ;; Test :hllstart parameter.
+  (should
+   (equal "!> a\n!!> b\n> c"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |\n| b |\n|---|\n| c |")
+			     '(:lstart "> " :hlstart "!> " :hllstart "!!> "))))
+  ;; Test :lend parameter.
+  (should
+   (equal "a <"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |") '(:lend " <"))))
+  ;; Test :llend parameter.
+  (should
+   (equal "a <\nb <<"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
+			     '(:lend " <" :llend " <<"))))
+  ;; Test :hlend parameter.
+  (should
+   (equal "a <!\nb <"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
+			     '(:lend " <" :hlend " <!"))))
+  ;; Test :hllend parameter.
+  (should
+   (equal "a <!\nb <!!\nc <"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |\n| b |\n|---|\n| c |")
+			     '(:lend " <" :hlend " <!" :hllend " <!!"))))
+  ;; Test :lfmt parameter.
+  (should
+   (equal "a!b"
+	  (orgtbl-to-generic (org-table-to-lisp "| a | b |")
+			     '(:lfmt "%s!%s"))))
+  (should
+   (equal "a+b"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| a | b |")
+	   '(:lfmt (lambda (c) (concat (car c) "+" (cadr c)))))))
+  (should
+   (equal "a!b"
+	  (orgtbl-to-generic (org-table-to-lisp "| a | b |")
+			     '(:lfmt "%s!%s" :lstart ">" :lend "<" :sep " "))))
+  ;; Test :llfmt parameter.
+  (should
+   (equal "a!b"
+	  (orgtbl-to-generic (org-table-to-lisp "| a | b |")
+			     '(:llfmt "%s!%s"))))
+  (should
+   (equal "a!b\nc+d"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| a | b |\n| c | d |")
+	   '(:lfmt "%s!%s" :llfmt (lambda (c) (concat (car c) "+" (cadr c)))))))
+  (should
+   (equal "a!b"
+	  (orgtbl-to-generic (org-table-to-lisp "| a | b |")
+			     '(:llfmt "%s!%s" :lstart ">" :lend "<" :sep " "))))
+  ;; Test :hlfmt parameter.
+  (should
+   (equal "a!b\ncd"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
+	   '(:hlfmt "%s!%s"))))
+  (should
+   (equal "a+b\ncd"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
+	   '(:hlfmt (lambda (c) (concat (car c) "+" (cadr c)))))))
+  (should
+   (equal "a!b\n>c d<"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
+	   '(:hlfmt "%s!%s" :lstart ">" :lend "<" :sep " "))))
+  ;; Test :hllfmt parameter.
+  (should
+   (equal "a!b\ncd"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
+	   '(:hllfmt "%s!%s"))))
+  (should
+   (equal "a+b\ncd"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
+	   '(:hllfmt (lambda (c) (concat (car c) "+" (cadr c)))))))
+  (should
+   (equal "a!b\n>c d<"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
+	   '(:hllfmt "%s!%s" :lstart ">" :lend "<" :sep " "))))
+  ;; Test :fmt parameter.
+  (should
+   (equal ">a<\n>b<"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
+			     '(:fmt ">%s<"))))
+  (should
+   (equal ">a<b"
+	  (orgtbl-to-generic (org-table-to-lisp "| a | b |")
+			     '(:fmt (1 ">%s<" 2 (lambda (c) c))))))
+  (should
+   (equal "a b"
+	  (orgtbl-to-generic (org-table-to-lisp "| a | b |")
+			     '(:fmt (2 " %s")))))
+  (should
+   (equal ">a<"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |")
+			     '(:fmt (lambda (c) (format ">%s<" c))))))
+  ;; Test :hfmt parameter.
+  (should
+   (equal ">a<\nb"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
+			     '(:hfmt ">%s<"))))
+  (should
+   (equal ">a<b\ncd"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
+	   '(:hfmt (1 ">%s<" 2 identity)))))
+  (should
+   (equal "a b\ncd"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
+	   '(:hfmt (2 " %s")))))
+  (should
+   (equal ">a<\nb"
+	  (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
+			     '(:hfmt (lambda (c) (format ">%s<" c))))))
+  ;; Test :efmt parameter.
+  (should
+   (equal "2x10^3"
+	  (orgtbl-to-generic (org-table-to-lisp "| 2e3 |")
+			     '(:efmt "%sx10^%s"))))
+  (should
+   (equal "2x10^3"
+	  (orgtbl-to-generic (org-table-to-lisp "| 2e3 |")
+			     '(:efmt (lambda (m e) (concat m "x10^" e))))))
+  (should
+   (equal "2x10^3"
+	  (orgtbl-to-generic (org-table-to-lisp "| 2e3 |")
+			     '(:efmt (1 "%sx10^%s")))))
+  (should
+   (equal "2x10^3"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| 2e3 |")
+	   '(:efmt (1 (lambda (m e) (format "%sx10^%s" m e)))))))
+  (should
+   (equal "2e3"
+	  (orgtbl-to-generic (org-table-to-lisp "| 2e3 |") '(:efmt nil))))
+  ;; Test :skip parameter.
+  (should
+   (equal "cd"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| \ | <c> |\n| a | b |\n|---+---|\n| c | d |")
+	   '(:skip 2))))
+  ;; Test :skipcols parameter.
+  (should
+   (equal "a\nc"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp "| a | b |\n| c | d |") '(:skipcols (2)))))
+  (should
+   (equal "a\nc"
+	  (orgtbl-to-generic
+	   (org-table-to-lisp
+	    "| / | <c> | <c> |\n| # | a | b |\n|---+---+---|\n|   | c | d |")
+	   '(:skipcols (2)))))
+  ;; Test :raw parameter.
+  (when (featurep 'ox-latex)
+    (should
+     (org-string-match-p
+      "/a/"
+      (orgtbl-to-generic (org-table-to-lisp "| /a/ | b |")
+			 '(:backend latex :raw t))))))
+
+(ert-deftest test-org-table/to-latex ()
+  "Test `orgtbl-to-latex' specifications."
+  (should
+   (equal "\\begin{tabular}{l}\na\\\\\n\\end{tabular}"
+	  (orgtbl-to-latex (org-table-to-lisp "| a |") nil)))
+  ;; Test :environment parameter.
+  (should
+   (equal "\\begin{tabularx}{l}\na\\\\\n\\end{tabularx}"
+	  (orgtbl-to-latex (org-table-to-lisp "| a |")
+			   '(:environment "tabularx"))))
+  ;; Test :booktabs parameter.
+  (should
+   (org-string-match-p
+    "\\toprule" (orgtbl-to-latex (org-table-to-lisp "| a |") '(:booktabs t)))))
+
+(ert-deftest test-org-table/to-html ()
+  "Test `orgtbl-to-html' specifications."
+  (should
+   (equal (orgtbl-to-html (org-table-to-lisp "| a |") nil)
+	  "<table border=\"2\" cellspacing=\"0\" cellpadding=\"6\" rules=\"groups\" frame=\"hsides\">
+
+
+<colgroup>
+<col  class=\"left\" />
+</colgroup>
+<tbody>
+<tr>
+<td class=\"left\">a</td>
+</tr>
+</tbody>
+</table>"))
+  ;; Test :attributes parameter.
+  (should
+   (org-string-match-p
+    "<table>"
+    (orgtbl-to-html (org-table-to-lisp "| a |") '(:attributes nil))))
+  (should
+   (org-string-match-p
+    "<table border=\"2\">"
+    (orgtbl-to-html (org-table-to-lisp "| a |") '(:attributes (:border "2"))))))
+
+(ert-deftest test-org-table/to-texinfo ()
+  "Test `orgtbl-to-texinfo' specifications."
+  (should
+   (equal "@multitable {a}\n@item a\n@end multitable"
+	  (orgtbl-to-texinfo (org-table-to-lisp "| a |") nil)))
+  ;; Test :columns parameter.
+  (should
+   (equal "@multitable @columnfractions .4 .6\n@item a\n@tab b\n@end multitable"
+	  (orgtbl-to-texinfo (org-table-to-lisp "| a | b |")
+			     '(:columns ".4 .6"))))
+  (should
+   (equal "@multitable @columnfractions .4 .6\n@item a\n@tab b\n@end multitable"
+	  (orgtbl-to-texinfo (org-table-to-lisp "| a | b |")
+			     '(:columns "@columnfractions .4 .6"))))
+  (should
+   (equal "@multitable {xxx} {xx}\n@item a\n@tab b\n@end multitable"
+	  (orgtbl-to-texinfo (org-table-to-lisp "| a | b |")
+			     '(:columns "{xxx} {xx}")))))
+
+(ert-deftest test-org-table/to-orgtbl ()
+  "Test `orgtbl-to-orgtbl' specifications."
+  (should
+   (equal "| a | b |\n|---+---|\n| c | d |"
+	  (orgtbl-to-orgtbl
+	   (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |") nil))))
+
+(ert-deftest test-org-table/to-unicode ()
+  "Test `orgtbl-to-unicode' specifications."
+  (should
+   (equal "━━━\n a \n━━━"
+	  (orgtbl-to-unicode (org-table-to-lisp "| a |") nil)))
+  ;; Test :narrow parameter.
+  (should
+   (equal "━━━━\n => \n━━━━"
+	  (orgtbl-to-unicode (org-table-to-lisp "| <2> |\n| xxx |")
+			     '(:narrow t)))))
+
+(ert-deftest test-org-table/send-region ()
+  "Test `orgtbl-send-table' specifications."
+  ;; Error when not at a table.
+  (should-error
+   (org-test-with-temp-text "Paragraph"
+     (orgtbl-send-table)))
+  ;; Error when destination is missing.
+  (should-error
+   (org-test-with-temp-text "#+ORGTBL: SEND\n<point>| a |"
+     (orgtbl-send-table)))
+  ;; Error when transformation function is not specified.
+  (should-error
+   (org-test-with-temp-text "
+# BEGIN RECEIVE ORGTBL table
+# END RECEIVE ORGTBL table
+#+ORGTBL: SEND table
+<point>| a |"
+     (orgtbl-send-table)))
+  ;; Standard test.
+  (should
+   (equal "| a |\n|---|\n| b |\n"
+	  (org-test-with-temp-text "
+# BEGIN RECEIVE ORGTBL table
+# END RECEIVE ORGTBL table
+#+ORGTBL: SEND table orgtbl-to-orgtbl :hlines nil
+<point>| a |\n|---|\n| b |"
+	    (orgtbl-send-table)
+	    (goto-char (point-min))
+	    (buffer-substring-no-properties
+	     (search-forward "# BEGIN RECEIVE ORGTBL table\n")
+	     (progn (search-forward "# END RECEIVE ORGTBL table")
+		    (match-beginning 0)))))))
+
+
 (provide 'test-org-table)
 (provide 'test-org-table)
 
 
 ;;; test-org-table.el ends here
 ;;; test-org-table.el ends here

部分文件因文件數量過多而無法顯示