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) ""))))