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,30 +2801,35 @@ 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)))
(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")))
(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)))
'("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))
(let ((columns (cdr (org-export-table-dimensions
(org-export-get-parent-table table-row) info))))
(format "%s
\\endfirsthead
\\multicolumn{%d}{l}{%s} \\\\
@ -2836,25 +2841,22 @@ a communication channel."
\\endfoot
\\endlastfoot"
(if booktabsp "\\midrule" "\\hline")
(cdr (org-export-table-dimensions
(org-export-get-parent-table table-row) info))
columns
(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 ""))
(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")
;; Number of columns.
(cdr (org-export-table-dimensions
(org-export-get-parent-table table-row) info))
(org-latex--translate "Continued on next page" info)))
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