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

This commit is contained in:
Bastien Guerry 2014-09-13 15:52:17 +02:00
commit e6074ec4d7
5 changed files with 946 additions and 571 deletions

View File

@ -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
removal of these columns, the function never knows that there have been
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
@noindent
@ -17619,14 +17615,15 @@ Month & \multicolumn@{1@}@{c@}@{Days@} & Nr.\ sold & per day\\
@end example
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
@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
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.
@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
@node Translator functions
@ -17654,54 +17651,36 @@ supplied instead of strings.
Orgtbl mode has several translator functions built-in: @code{orgtbl-to-csv}
(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:
@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}).
@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
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
#+ORGTBL: SEND test orgtbl-to-latex :lend " \\\\[2mm]"
@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
Please check the documentation string of the function

View File

@ -77,6 +77,13 @@ These functions now support any element or object, not only headlines.
*** New filter: ~org-export-filter-body-functions~
Functions in this filter are applied on the body of the exported
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
*** File names in links accept are now compatible with URI syntax
Absolute file names can now start with =///= in addition to =/=. E.g.,

File diff suppressed because it is too large Load Diff

View File

@ -2801,31 +2801,36 @@ a communication channel."
"Transcode a TABLE-ROW element from Org to LaTeX.
CONTENTS is the contents of the row. INFO is a plist used as
a communication channel."
;; Rules are ignored since table separators are deduced from
;; borders of the current row.
(when (eq (org-element-property :type table-row) 'standard)
(let* ((attr (org-export-read-attribute :attr_latex
(org-export-get-parent table-row)))
(longtablep
(member (or (plist-get attr :environment)
(plist-get info :latex-default-table-environment))
'("longtable" "longtabu")))
(booktabsp (if (plist-member attr :booktabs)
(plist-get attr :booktabs)
(plist-get info :latex-tables-booktabs)))
;; TABLE-ROW's borders are extracted from its first cell.
(borders (org-export-table-cell-borders
(car (org-element-contents table-row)) info)))
(let* ((attr (org-export-read-attribute :attr_latex
(org-export-get-parent table-row)))
(booktabsp (if (plist-member attr :booktabs) (plist-get attr :booktabs)
(plist-get info :latex-tables-booktabs)))
(longtablep
(member (or (plist-get attr :environment)
(plist-get info :latex-default-table-environment))
'("longtable" "longtabu"))))
(if (eq (org-element-property :type table-row) 'rule)
(cond
((not booktabsp) "\\hline")
((not (org-export-get-previous-element table-row info)) "\\toprule")
((not (org-export-get-next-element table-row info)) "\\bottomrule")
((and longtablep
(org-export-table-row-ends-header-p
(org-export-get-previous-element table-row info) info))
"")
(t "\\midrule"))
(concat
;; When BOOKTABS are activated enforce top-rule even when no
;; hline was specifically marked.
(cond ((and booktabsp (memq 'top borders)) "\\toprule\n")
((and (memq 'top borders) (memq 'above borders)) "\\hline\n"))
(and booktabsp (not (org-export-get-previous-element table-row info))
"\\toprule\n")
contents "\\\\\n"
(cond
;; Special case for long tables. Define header and footers.
((and longtablep (org-export-table-row-ends-header-p table-row info))
(format "%s
(let ((columns (cdr (org-export-table-dimensions
(org-export-get-parent-table table-row) info))))
(format "%s
\\endfirsthead
\\multicolumn{%d}{l}{%s} \\\\
%s
@ -2835,26 +2840,23 @@ a communication channel."
%s\\multicolumn{%d}{r}{%s} \\\\
\\endfoot
\\endlastfoot"
(if booktabsp "\\midrule" "\\hline")
(cdr (org-export-table-dimensions
(org-export-get-parent-table table-row) info))
(org-latex--translate "Continued from previous page" info)
(cond ((and booktabsp (memq 'top borders)) "\\toprule\n")
((and (memq 'top borders)
(memq 'above borders)) "\\hline\n")
(t ""))
contents
(if booktabsp "\\midrule" "\\hline")
(if booktabsp "\\midrule" "\\hline")
;; Number of columns.
(cdr (org-export-table-dimensions
(org-export-get-parent-table table-row) info))
(org-latex--translate "Continued on next page" info)))
(if booktabsp "\\midrule" "\\hline")
columns
(org-latex--translate "Continued from previous page" info)
(cond
((not (org-export-table-row-starts-header-p table-row info))
"")
(booktabsp "\\toprule\n")
(t "\\hline\n"))
contents
(if booktabsp "\\midrule" "\\hline")
(if booktabsp "\\midrule" "\\hline")
columns
(org-latex--translate "Continued on next page" info))))
;; When BOOKTABS are activated enforce bottom rule even when
;; no hline was specifically marked.
((and booktabsp (memq 'bottom borders)) "\\bottomrule")
((and (memq 'bottom borders) (memq 'below borders)) "\\hline")
((memq 'below borders) (if booktabsp "\\midrule" "\\hline")))))))
((and booktabsp (not (org-export-get-next-element table-row info)))
"\\bottomrule"))))))
;;;; Target

View File

@ -1168,6 +1168,352 @@ See also `test-org-table/copy-field'."
(should (string= got
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)
;;; test-org-table.el ends here