Function: orgtbl-to-generic
orgtbl-to-generic is an autoloaded and byte-compiled function defined
in org-table.el.gz.
Signature
(orgtbl-to-generic TABLE PARAMS)
Documentation
Convert the orgtbl-mode(var)/orgtbl-mode(fun) 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.
Valid parameters are:
:backend, :raw
Export backend used as a basis to transcode elements of the
table, when no specific parameter applies to it. It is also
used to translate cells contents. You can prevent this by
setting :raw property to a non-nil value.
:splice
When non-nil, only convert rows, not the table itself. This is
equivalent to setting to the empty string both :tstart
and :tend, which see.
:skip
When set to an integer N, skip the first N lines of the table.
Horizontal separation lines do count for this parameter!
:skipcols
List of columns that should be skipped. If the table has
a column with calculation marks, that column is automatically
discarded beforehand.
:hline
String to be inserted on horizontal separation lines. May be
nil to ignore these lines altogether.
:sep
Separator between two fields, as a string.
Each in the following group may be either a string or a function of no arguments returning a string:
:tstart, :tend
Strings to start and end the table. Ignored when :splice is t.
:lstart, :lend
Strings to start and end a new table line.
:llstart, :llend
Strings to start and end the last table line. Default,
respectively, to :lstart and :lend.
Each in the following group may be a string or a function of one argument (either the cells in the current row, as a list of strings, or the current cell) returning a string:
:lfmt
Format string for an entire row, with enough %s to capture all
fields. When non-nil, :lstart, :lend, and :sep are ignored.
:llfmt
Format for the entire last line, defaults to :lfmt.
:fmt
A format to be used to wrap the field, should contain %s for
the original field value. For example, to wrap everything in
dollars, you could use :fmt "$%s$". This may also be
a property list with column numbers and format strings, or
functions, e.g.,
(:fmt (2 "$%s$" 4 (lambda (c) (format "$%s$" c))))
The format is ignored for empty fields. Use :raw t with non-nil
:backend option to force formatting empty fields.
:hlstart :hllstart :hlend :hllend :hsep :hlfmt :hllfmt :hfmt
Same as above, specific for the header lines in the table.
All lines before the first hline are treated as header. If
any of these is not present, the data line value is used.
This may be either a string or a function of two arguments:
:efmt
Use this format to print numbers with exponential. The format
should have %s twice for inserting mantissa and exponent, for
example "%s\\\\times10^{%s}". This may also be a property
list with column numbers and format strings or functions.
:fmt will still be applied after :efmt.
Source Code
;; Defined in /usr/src/emacs/lisp/org/org-table.el.gz
;;;###autoload
(defun orgtbl-to-generic (table params)
"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.
Valid parameters are:
:backend, :raw
Export backend used as a basis to transcode elements of the
table, when no specific parameter applies to it. It is also
used to translate cells contents. You can prevent this by
setting :raw property to a non-nil value.
:splice
When non-nil, only convert rows, not the table itself. This is
equivalent to setting to the empty string both :tstart
and :tend, which see.
:skip
When set to an integer N, skip the first N lines of the table.
Horizontal separation lines do count for this parameter!
:skipcols
List of columns that should be skipped. If the table has
a column with calculation marks, that column is automatically
discarded beforehand.
:hline
String to be inserted on horizontal separation lines. May be
nil to ignore these lines altogether.
:sep
Separator between two fields, as a string.
Each in the following group may be either a string or a function
of no arguments returning a string:
:tstart, :tend
Strings to start and end the table. Ignored when :splice is t.
:lstart, :lend
Strings to start and end a new table line.
:llstart, :llend
Strings to start and end the last table line. Default,
respectively, to :lstart and :lend.
Each in the following group may be a string or a function of one
argument (either the cells in the current row, as a list of
strings, or the current cell) returning a string:
:lfmt
Format string for an entire row, with enough %s to capture all
fields. When non-nil, :lstart, :lend, and :sep are ignored.
:llfmt
Format for the entire last line, defaults to :lfmt.
:fmt
A format to be used to wrap the field, should contain %s for
the original field value. For example, to wrap everything in
dollars, you could use :fmt \"$%s$\". This may also be
a property list with column numbers and format strings, or
functions, e.g.,
(:fmt (2 \"$%s$\" 4 (lambda (c) (format \"$%s$\" c))))
The format is ignored for empty fields. Use :raw t with non-nil
:backend option to force formatting empty fields.
:hlstart :hllstart :hlend :hllend :hsep :hlfmt :hllfmt :hfmt
Same as above, specific for the header lines in the table.
All lines before the first hline are treated as header. If
any of these is not present, the data line value is used.
This may be either a string or a function of two arguments:
:efmt
Use this format to print numbers with exponential. The format
should have %s twice for inserting mantissa and exponent, for
example \"%s\\\\times10^{%s}\". This may also be a property
list with column numbers and format strings or functions.
:fmt will still be applied after :efmt."
;; Make sure `org-export-create-backend' is available.
(require 'ox)
(let* ((backend (plist-get params :backend))
(custom-backend
;; Build a custom backend according to PARAMS. Before
;; defining a translator, check if there is anything to do.
;; When there isn't, let BACKEND handle the element.
(org-export-create-backend
:parent (or backend 'org)
:transcoders
`((table . ,(org-table--to-generic-table params))
(table-row . ,(org-table--to-generic-row params))
(table-cell . ,(org-table--to-generic-cell params))
;; Macros are not going to be expanded. However, no
;; regular backend has a transcoder for them. We
;; provide one so they are not ignored, but displayed
;; as-is instead.
(macro . (lambda (m c i) (org-element-macro-interpreter m nil))))))
data info)
;; Store TABLE as Org syntax in DATA. Tolerate non-string cells.
;; Initialize communication channel in INFO.
(with-temp-buffer
(let ((org-inhibit-startup t)) (org-mode))
(org-fold-core-ignore-modifications
(let ((standard-output (current-buffer))
(org-element-use-cache nil))
(dolist (e table)
(cond ((eq e 'hline) (princ "|--\n"))
((consp e)
(princ "| ") (dolist (c e) (princ c) (princ " |"))
(princ "\n")))))
(org-element-cache-reset)
;; Add backend specific filters, but not user-defined ones. In
;; particular, make sure to call parse-tree filters on the
;; table.
(setq info
(let ((org-export-filters-alist nil))
(org-export-install-filters
(org-combine-plists
(org-export-get-environment backend nil params)
`(:back-end ,(org-export-get-backend backend))))))
(setq data
(org-export-filter-apply-functions
(plist-get info :filter-parse-tree)
(org-element-map (org-element-parse-buffer) 'table
#'identity nil t)
info))
(when (and backend (symbolp backend) (not (org-export-get-backend backend)))
(user-error "Unknown :backend value"))))
(when (or (not backend) (plist-get info :raw)) (require 'ox-org))
;; Handle :skip parameter.
(let ((skip (plist-get info :skip)))
(when skip
(unless (wholenump skip) (user-error "Wrong :skip value"))
(let ((n 0))
(org-element-map data 'table-row
(lambda (row)
(if (>= n skip) t
(org-element-extract row)
(cl-incf n)
nil))
nil t))))
;; Handle :skipcols parameter.
(let ((skipcols (plist-get info :skipcols)))
(when skipcols
(unless (consp skipcols) (user-error "Wrong :skipcols value"))
(org-element-map data 'table
(lambda (table)
(let ((specialp (org-export-table-has-special-column-p table)))
(dolist (row (org-element-contents table))
(when (eq (org-element-property :type row) 'standard)
(let ((c 1))
(dolist (cell (nthcdr (if specialp 1 0)
(org-element-contents row)))
(when (memq c skipcols)
(org-element-extract cell))
(cl-incf c))))))))))
;; Since we are going to export using a low-level mechanism,
;; ignore special column and special rows manually.
(let ((special? (org-export-table-has-special-column-p data))
ignore)
(org-element-map data (if special? '(table-cell table-row) 'table-row)
(lambda (datum)
(when (if (org-element-type-p datum 'table-row)
(org-export-table-row-is-special-p datum nil)
(org-export-first-sibling-p datum nil))
(push datum ignore))))
(setq info (plist-put info :ignore-list ignore)))
;; We use a low-level mechanism to export DATA so as to skip all
;; usual pre-processing and post-processing, i.e., hooks, Babel
;; code evaluation, include keywords and macro expansion. Only
;; backend specific filters are retained.
(let ((output (org-export-data-with-backend data custom-backend info)))
;; Remove final newline.
(if (org-string-nw-p output) (substring-no-properties output 0 -1) ""))))