123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- ;;; ox-latex-subfigure.el --- Subfigure for latex export
- ;; Copyright (C) 2014-2019 Quang Linh LE
- ;; Copyright (C) 2019-2021 eDgar
- ;; Author: Quang Linh LE <linktohack@gmail.com>
- ;; URL: http://www.notabug.com/broncodev/ox-latex-subfigure
- ;; Version: 0.0.2
- ;; Keywords: convenience ox latex subfigure org org-mode
- ;; Package-Requires: ((emacs "24"))
- ;; This file is not part of GNU Emacs.
- ;;; License:
- ;; This file is part of ox-latex-subfigure
- ;;
- ;; ox-latex-subfigure is free software: you can redistribute it and/or
- ;; modify it under the terms of the GNU General Public License as
- ;; published by the Free Software Foundation, either version 3 of the
- ;; License.
- ;;
- ;; ox-latex-subfigure is distributed in the hope that it will be
- ;; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- ;; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;; GNU General Public License for more details.
- ;;
- ;; You should have received a copy of the GNU General Public License
- ;; along with this program. If not, see
- ;; <http://www.gnu.org/licenses/>.
- ;;; Commentary:
- ;; ox-latex-subfigure.el permits to export subfigure to latex
- ;;; Code:
- (require 'ox-latex)
- (require 'org-loaddefs)
- (defun ox-latex-subfigure-org-export-table-to-subfigure (text backend info)
- "Convert table to subfigure in LaTeX export.
- TEXT is raw text, BACKEND is backend, INFO is info."
- (when (org-export-derived-backend-p backend 'latex)
- (if (not (next-property-change 0 text))
- text
- (let
- ((pt 0)
- cell
- table)
- (while
- (or
- (not table)
- (not pt))
- (setq
- pt (next-property-change pt text)
- cell (plist-get (text-properties-at pt text) :parent)
- table (org-export-get-parent-table cell)))
- (let*
- ((attr (org-export-read-attribute :attr_latex table))
- (env (plist-get attr :environment))
- (limit (string-to-number (or (plist-get attr :limit) "0"))))
- (if (not (string= "subfigure" env))
- text
- (with-temp-buffer
- (insert text)
- (goto-char 1)
- (ox-latex-subfigure-latex-table-to-subfigure limit)
- (buffer-string))))))))
- (defun ox-latex-subfigure-latex-table-to-subfigure (limit)
- "Convert well-formed table to subfigure.
- LIMIT is limit."
- (interactive "p")
- (let ((width ".9\\textwidth")
- (align "")
- (option "")
- (centering "")
- (caption "")
- fig
- cap
- opn
- wdt
- aln)
- (beginning-of-line)
- (while (not (looking-at "^\\\\end{table}"))
- (let ((row (thing-at-point 'line t)))
- (kill-whole-line)
- (cond
- ;; \begin{table}[option], \end{table}
- ((string-match
- "^\\\\begin{table}\\(\\[.*\\]\\)?" row)
- (setq
- option (or (match-string 1 row) "")))
- ;; \centering
- ((string-match "^\\\\centering" row)
- (setq centering "\\centering\n"))
- ;; \begin{subfigure}{width}{align}, \begin{subfigure}{align}
- ;; \end{subfigure}
- ((string-match
- "^\\\\begin{subfigure}\\({\\(.*?\\)}\\)?\\({\\(.*?\\)}\\)?" row)
- ;; This will happen when \begin{subfigure} is found
- (let (maybe-width
- maybe-align
- start-of-table
- row-start
- row-end
- rules)
- (setq maybe-width (match-string 2 row))
- (setq maybe-align (match-string 4 row))
- (unless maybe-align
- (setq maybe-align maybe-width)
- (setq maybe-width nil))
- (setq width (or maybe-width width))
- (setq align (or maybe-align align))
- (setq start-of-table (point))
- ;; Remove all possible rules or hlines
- (setq rules
- (mapconcat
- 'identity
- '("hline"
- "vline"
- "toprule"
- "midrule"
- "bottomrule")
- "\\|"))
- (while (re-search-forward (concat "\\\\\\(" rules "\\)\n?") nil t)
- (replace-match ""))
- (goto-char start-of-table)
- ;; Transform all multi line rows to single line
- ;; rows by replacing newlines with spaces
- (while (not (looking-at "\\\\end{subfigure}"))
- (setq row-start (point))
- ;; Search for a new row delimiter
- (when (re-search-forward "\\\\\\\\\n?" nil t)
- (goto-char row-start)
- (setq row-end (match-beginning 0))
- ;; Replace all newlines in the row with spaces
- (save-match-data
- (while (re-search-forward "\n" row-end t)
- (replace-match " ")))
- (setq row-start (match-end 0))
- (goto-char row-start)))
- ;; Go back the start of the table and continue with normal
- ;; row formatting
- (goto-char start-of-table)))
- ;; \caption{\label{tab:orgtable1}
- ;; xxx}
- ((string-match "^\\\\caption[\\\\[{]" row)
- (setq
- caption (concat
- row (thing-at-point 'line t)))
- (kill-whole-line))
- ;; table row
- ((string-match ".*\\\\\\\\$" row)
- (let ((striped-row (replace-regexp-in-string
- "\\\\\\\\\n$" "" row)))
- (setq
- fig (append
- fig (split-string striped-row " & ")))
- (setq
- row (thing-at-point
- 'line t))
- (kill-whole-line)
- (setq
- striped-row (replace-regexp-in-string
- "\\\\\\\\\n$" "" row))
- (setq
- cap (append
- cap (split-string
- striped-row " & ")))
- ;;
- (setq
- row (thing-at-point
- 'line t))
- (kill-whole-line)
- (setq
- striped-row (replace-regexp-in-string
- "\\\\\\\\\n$" "" row))
- (setq
- opn (append
- opn (split-string striped-row " & "))))))))
- (kill-whole-line)
- (insert (format "\\begin{figure}%s\n%s%s" option
- (if (member 'subfigure org-latex-caption-above) caption "")
- centering))
- (dotimes (i (length fig))
- (let ((f (nth i fig))
- (c (nth i cap))
- (o (if (and (nth i opn)
- (string-match "\\\\end{subfigure}" (nth i opn)))
- nil
- (nth i opn)))
- (std "includegraphics")
- (svg "includesvg"))
- (when (or (string-match std c)
- (string-match svg c))
- (setq f (prog1 c (setq c f))))
- (when
- (or
- (string-match (concat
- "\\(\\\\"
- std
- "\\(:?\\[.*?\\]\\)?{.*?}\\)")
- f)
- (string-match (concat
- "\\(\\\\"
- svg
- "\\(:?\\[.*?\\]\\)?{.*?}\\)")
- f))
- (setq
- f (replace-regexp-in-string
- "\\[.*?\\]"
- (concat
- "[" o "]")
- (match-string 1 f)
- t t))
- ;; Split width by commas for each column
- (if
- ;; If only one width is given, and there are
- ;; many columns, the conditional forces wdt to
- ;; remain with the previous value of width,
- ;; because width was previously vacated
- (> (length width) 0)
- (setq
- ;; Get the the width for the current column
- wdt (car (split-string width ","))
- ;; Remove current instance of width and update
- ;; https://stackoverflow.com/a/32580403
- ;; https://www.emacswiki.org/emacs/ReplaceInString
- width (mapconcat
- 'identity
- (cdr
- (split-string
- width
- ","))
- ",")))
- ;; Split align if is not given (ox-latex sets a
- ;; default) or has several characters
- (if
- ;; If only one align char is given, and there
- ;; are many columns, the conditional forces
- ;; aln to remain with the previous value of
- ;; align, because align was previously vacated
- (> (length align) 0)
- (setq
- ;; Get the the alignment for the current
- ;; column (a single character)
- aln (substring align 0 1)
- ;; Remove current instance of align and update
- ;; https://stackoverflow.com/a/32580403
- ;; https://www.emacswiki.org/emacs/ReplaceInString
- align (mapconcat
- 'identity
- (cdr
- ;; Breaking strings into characters
- ;; https://www.emacswiki.org/emacs/SplitString#toc3
- (mapcar
- 'char-to-string
- align))
- "")))
- (insert (format "\\begin{subfigure}[%s]{%s}\\centering
- %s
- \\caption{%s}
- \\end{subfigure}\n" aln wdt f c))
- (when (and (> limit 0)
- (< i (1- (length fig)))
- (= (mod (1+ i) limit) 0))
- (insert (format "\\end{figure}\n
- \\begin{figure}%s
- %s\\ContinuedFloat\n" option centering))))))
- (insert (format "%s\\end{figure}\n"
- (if (member 'subfigure org-latex-caption-above) "" caption)))))
- (add-hook 'org-export-filter-table-functions
- 'ox-latex-subfigure-org-export-table-to-subfigure)
- (provide 'ox-latex-subfigure)
- ;;; ox-latex-subfigure.el ends here
|