diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 6b09cdc5b..046244788 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -42,6 +42,9 @@ See [[git:3367ac9457]] for details. ** New features *** Babel **** Add LaTeX output support in PlantUML +*** Allow LaTeX attributes and captions for "table.el" tables +Supported LaTeX attributes are ~:float~, ~:center~, ~:font~ and +~:caption~. *** Attach buffer contents to headline With == key from attachment dispatcher (==), it is now possible to write the contents of a buffer to a file in the headline diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index cae6900f4..1dec461d3 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -3184,6 +3184,58 @@ centered." info) (apply 'concat (nreverse align))))) +(defun org-latex--decorate-table (table attributes caption above? info) + "Decorate TABLE string with caption and float environment. + +ATTRIBUTES is the plist containing is LaTeX attributes. CAPTION +is its caption. It is located above the table if ABOVE? is +non-nil. INFO is the plist containing current export parameters. + +Return new environment, as a string." + (let* ((float-environment + (let ((float (plist-get attributes :float))) + (cond ((and (not float) (plist-member attributes :float)) nil) + ((member float '("sidewaystable" "sideways")) "sidewaystable") + ((equal float "multicolumn") "table*") + ((or float + (org-element-property :caption table) + (org-string-nw-p (plist-get attributes :caption))) + "table") + (t nil)))) + (placement + (or (plist-get attributes :placement) + (format "[%s]" (plist-get info :latex-default-figure-position)))) + (center? (if (plist-member attributes :center) + (plist-get attributes :center) + (plist-get info :latex-tables-centered))) + (fontsize (let ((font (plist-get attributes :font))) + (and font (concat font "\n"))))) + (concat (cond + (float-environment + (concat (format "\\begin{%s}%s\n" float-environment placement) + (if above? caption "") + (when center? "\\centering\n") + fontsize)) + (caption + (concat (and center? "\\begin{center}\n" ) + (if above? caption "") + (cond ((and fontsize center?) fontsize) + (fontsize (concat "{" fontsize)) + (t nil)))) + (center? (concat "\\begin{center}\n" fontsize)) + (fontsize (concat "{" fontsize))) + table + (cond + (float-environment + (concat (if above? "" (concat "\n" caption)) + (format "\n\\end{%s}" float-environment))) + (caption + (concat (if above? "" (concat "\n" caption)) + (and center? "\n\\end{center}") + (and fontsize (not center?) "}"))) + (center? "\n\\end{center}") + (fontsize "}"))))) + (defun org-latex--org-table (table contents info) "Return appropriate LaTeX code for an Org table. @@ -3193,109 +3245,44 @@ channel. This function assumes TABLE has `org' as its `:type' property and `table' as its `:mode' attribute." - (let* ((caption (org-latex--caption/label-string table info)) - (attr (org-export-read-attribute :attr_latex table)) - ;; Determine alignment string. + (let* ((attr (org-export-read-attribute :attr_latex table)) (alignment (org-latex--align-string table info)) - ;; Determine environment for the table: longtable, tabular... (table-env (or (plist-get attr :environment) (plist-get info :latex-default-table-environment))) - ;; If table is a float, determine environment: table, table* - ;; or sidewaystable. - (float-env (unless (member table-env '("longtable" "longtabu")) - (let ((float (plist-get attr :float))) - (cond - ((and (not float) (plist-member attr :float)) nil) - ((or (string= float "sidewaystable") - (string= float "sideways")) "sidewaystable") - ((string= float "multicolumn") "table*") - ((or float - (org-element-property :caption table) - (org-string-nw-p (plist-get attr :caption))) - "table"))))) - ;; Extract others display options. - (fontsize (let ((font (plist-get attr :font))) - (and font (concat font "\n")))) - ;; "tabular" environment doesn't allow to define a width. - (width (and (not (equal table-env "tabular")) (plist-get attr :width))) - (spreadp (plist-get attr :spread)) - (placement - (or (plist-get attr :placement) - (format "[%s]" (plist-get info :latex-default-figure-position)))) - (centerp (if (plist-member attr :center) (plist-get attr :center) - (plist-get info :latex-tables-centered))) - (caption-above-p (org-latex--caption-above-p table info))) - ;; Prepare the final format string for the table. + (width + (let ((w (plist-get attr :width))) + (cond ((not w) "") + ((member table-env '("tabular" "longtable")) "") + ((member table-env '("tabu" "longtabu")) + (format (if (plist-get attr :spread) " spread %s " + " to %s ") + w)) + (t (format "{%s}" w))))) + (caption (org-latex--caption/label-string table info)) + (above? (org-latex--caption-above-p table info))) (cond - ;; Longtable. - ((equal "longtable" table-env) - (concat (and fontsize (concat "{" fontsize)) - (format "\\begin{longtable}{%s}\n" alignment) - (and caption-above-p - (org-string-nw-p caption) - (concat caption "\\\\\n")) - contents - (and (not caption-above-p) - (org-string-nw-p caption) - (concat caption "\\\\\n")) - "\\end{longtable}\n" - (and fontsize "}"))) - ;; Longtabu - ((equal "longtabu" table-env) - (concat (and fontsize (concat "{" fontsize)) - (format "\\begin{longtabu}%s{%s}\n" - (if width - (format " %s %s " - (if spreadp "spread" "to") width) "") - alignment) - (and caption-above-p - (org-string-nw-p caption) - (concat caption "\\\\\n")) - contents - (and (not caption-above-p) - (org-string-nw-p caption) - (concat caption "\\\\\n")) - "\\end{longtabu}\n" - (and fontsize "}"))) - ;; Others. - (t (concat (cond - (float-env - (concat (format "\\begin{%s}%s\n" float-env placement) - (if caption-above-p caption "") - (when centerp "\\centering\n") - fontsize)) - ((and (not float-env) caption) - (concat - (and centerp "\\begin{center}\n" ) - (if caption-above-p caption "") - (cond ((and fontsize centerp) fontsize) - (fontsize (concat "{" fontsize))))) - (centerp (concat "\\begin{center}\n" fontsize)) - (fontsize (concat "{" fontsize))) - (cond ((equal "tabu" table-env) - (format "\\begin{tabu}%s{%s}\n%s\\end{tabu}" - (if width (format - (if spreadp " spread %s " " to %s ") - width) "") - alignment - contents)) - (t (format "\\begin{%s}%s{%s}\n%s\\end{%s}" - table-env - (if width (format "{%s}" width) "") - alignment - contents - table-env))) - (cond - (float-env - (concat (if caption-above-p "" (concat "\n" caption)) - (format "\n\\end{%s}" float-env))) - ((and (not float-env) caption) - (concat - (if caption-above-p "" (concat "\n" caption)) - (and centerp "\n\\end{center}") - (and fontsize (not centerp) "}"))) - (centerp "\n\\end{center}") - (fontsize "}"))))))) + ((member table-env '("longtable" "longtabu")) + (let ((fontsize (let ((font (plist-get attr :font))) + (and font (concat font "\n"))))) + (concat (and fontsize (concat "{" fontsize)) + (format "\\begin{%s}%s{%s}\n" table-env width alignment) + (and above? + (org-string-nw-p caption) + (concat caption "\\\\\n")) + contents + (and (not above?) + (org-string-nw-p caption) + (concat caption "\\\\\n")) + (format "\\end{%s}" table-env) + (and fontsize "}")))) + (t + (let ((output (format "\\begin{%s}%s{%s}\n%s\\end{%s}" + table-env + width + alignment + contents + table-env))) + (org-latex--decorate-table output attr caption above? info)))))) (defun org-latex--table.el-table (table info) "Return appropriate LaTeX code for a table.el table. @@ -3309,18 +3296,20 @@ property." ;; Ensure "*org-export-table*" buffer is empty. (with-current-buffer (get-buffer-create "*org-export-table*") (erase-buffer)) - (let ((output (with-temp-buffer - (insert (org-element-property :value table)) - (goto-char 1) - (re-search-forward "^[ \t]*|[^|]" nil t) - (table-generate-source 'latex "*org-export-table*") - (with-current-buffer "*org-export-table*" - (org-trim (buffer-string)))))) + (let ((output + (replace-regexp-in-string + "^%.*\n" "" ;remove comments + (with-temp-buffer + (save-excursion (insert (org-element-property :value table))) + (re-search-forward "^[ \t]*|[^|]" nil t) + (table-generate-source 'latex "*org-export-table*") + (with-current-buffer "*org-export-table*" + (org-trim (buffer-string)))) + t t))) (kill-buffer (get-buffer "*org-export-table*")) - ;; Remove left out comments. - (while (string-match "^%.*\n" output) - (setq output (replace-match "" t t output))) - (let ((attr (org-export-read-attribute :attr_latex table))) + (let ((attr (org-export-read-attribute :attr_latex table)) + (caption (org-latex--caption/label-string table info)) + (above? (org-latex--caption-above-p table info))) (when (plist-get attr :rmlines) ;; When the "rmlines" attribute is provided, remove all hlines ;; but the the one separating heading from the table body. @@ -3329,10 +3318,7 @@ property." (setq pos (string-match "^\\\\hline\n?" output pos))) (cl-incf n) (unless (= n 2) (setq output (replace-match "" nil nil output)))))) - (let ((centerp (if (plist-member attr :center) (plist-get attr :center) - (plist-get info :latex-tables-centered)))) - (if (not centerp) output - (format "\\begin{center}\n%s\n\\end{center}" output)))))) + (org-latex--decorate-table output attr caption above? info)))) (defun org-latex--math-table (table info) "Return appropriate LaTeX code for a matrix.