ox-latex: Refactor `org-latex-src-block'
* lisp/ox-latex.el (org-latex-src-block): Extract the per-format logic from `org-latex-src-block' into new dedicated functions: + `org-latex-src-block--verbatim' + `org-latex-src-block--custom' + `org-latex-src-block--minted' + `org-latex-src-block--listings' This makes `org-latex-src-block' much less monolithic, taking it from 175 lines to 30, and I find also makes it easier to understand.
This commit is contained in:
parent
d5a52be0a5
commit
61d85bcdb3
337
lisp/ox-latex.el
337
lisp/ox-latex.el
|
@ -2997,164 +2997,195 @@ contextual information."
|
||||||
(float (plist-get attributes :float))
|
(float (plist-get attributes :float))
|
||||||
(listings (plist-get info :latex-listings)))
|
(listings (plist-get info :latex-listings)))
|
||||||
(cond
|
(cond
|
||||||
;; Case 1. No source fontification.
|
|
||||||
((or (not lang) (not listings))
|
((or (not lang) (not listings))
|
||||||
(let ((caption-str (org-latex--caption/label-string src-block info))
|
(org-latex-src-block--verbatim src-block info lang caption caption-above-p label
|
||||||
(verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
|
num-start retain-labels attributes float))
|
||||||
(org-export-format-code-default src-block info))))
|
|
||||||
(cond ((string= "multicolumn" float)
|
|
||||||
(format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
|
|
||||||
(plist-get info :latex-default-figure-position)
|
|
||||||
(if caption-above-p caption-str "")
|
|
||||||
verbatim
|
|
||||||
(if caption-above-p "" caption-str)))
|
|
||||||
(caption (concat
|
|
||||||
(if caption-above-p caption-str "")
|
|
||||||
verbatim
|
|
||||||
(if caption-above-p "" (concat "\n" caption-str))))
|
|
||||||
(t verbatim))))
|
|
||||||
;; Case 2. Custom environment.
|
|
||||||
(custom-env
|
(custom-env
|
||||||
(let ((caption-str (org-latex--caption/label-string src-block info))
|
(org-latex-src-block--custom src-block info lang caption caption-above-p label
|
||||||
(formatted-src (org-export-format-code-default src-block info)))
|
num-start retain-labels attributes float custom-env))
|
||||||
(if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env)
|
|
||||||
(format "\\begin{%s}\n%s\\end{%s}\n"
|
|
||||||
custom-env
|
|
||||||
(concat (and caption-above-p caption-str)
|
|
||||||
formatted-src
|
|
||||||
(and (not caption-above-p) caption-str))
|
|
||||||
custom-env)
|
|
||||||
(format-spec custom-env
|
|
||||||
`((?s . ,formatted-src)
|
|
||||||
(?c . ,caption)
|
|
||||||
(?f . ,float)
|
|
||||||
(?l . ,(org-latex--label src-block info))
|
|
||||||
(?o . ,(or (plist-get attributes :options) "")))))))
|
|
||||||
;; Case 3. Use minted package.
|
|
||||||
((eq listings 'minted)
|
((eq listings 'minted)
|
||||||
(let* ((caption-str (org-latex--caption/label-string src-block info))
|
(org-latex-src-block--minted src-block info lang caption caption-above-p label
|
||||||
(placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
|
num-start retain-labels attributes float))
|
||||||
(plist-get info :latex-default-figure-position)))
|
|
||||||
(float-env
|
|
||||||
(cond
|
|
||||||
((string= "multicolumn" float)
|
|
||||||
(format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
|
|
||||||
placement
|
|
||||||
(if caption-above-p caption-str "")
|
|
||||||
(if caption-above-p "" caption-str)))
|
|
||||||
(caption
|
|
||||||
(format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
|
|
||||||
placement
|
|
||||||
(if caption-above-p caption-str "")
|
|
||||||
(if caption-above-p "" caption-str)))
|
|
||||||
((string= "t" float)
|
|
||||||
(concat (format "\\begin{listing}[%s]\n"
|
|
||||||
placement)
|
|
||||||
"%s\n\\end{listing}"))
|
|
||||||
(t "%s")))
|
|
||||||
(options (plist-get info :latex-minted-options))
|
|
||||||
(body
|
|
||||||
(format
|
|
||||||
"\\begin{minted}[%s]{%s}\n%s\\end{minted}"
|
|
||||||
;; Options.
|
|
||||||
(concat
|
|
||||||
(org-latex--make-option-string
|
|
||||||
(if (or (not num-start) (assoc "linenos" options))
|
|
||||||
options
|
|
||||||
(append
|
|
||||||
`(("linenos")
|
|
||||||
("firstnumber" ,(number-to-string (1+ num-start))))
|
|
||||||
options)))
|
|
||||||
(let ((local-options (plist-get attributes :options)))
|
|
||||||
(and local-options (concat "," local-options))))
|
|
||||||
;; Language.
|
|
||||||
(or (cadr (assq (intern lang)
|
|
||||||
(plist-get info :latex-minted-langs)))
|
|
||||||
(downcase lang))
|
|
||||||
;; Source code.
|
|
||||||
(let* ((code-info (org-export-unravel-code src-block))
|
|
||||||
(max-width
|
|
||||||
(apply 'max
|
|
||||||
(mapcar 'length
|
|
||||||
(org-split-string (car code-info)
|
|
||||||
"\n")))))
|
|
||||||
(org-export-format-code
|
|
||||||
(car code-info)
|
|
||||||
(lambda (loc _num ref)
|
|
||||||
(concat
|
|
||||||
loc
|
|
||||||
(when ref
|
|
||||||
;; Ensure references are flushed to the right,
|
|
||||||
;; separated with 6 spaces from the widest line
|
|
||||||
;; of code.
|
|
||||||
(concat (make-string (+ (- max-width (length loc)) 6)
|
|
||||||
?\s)
|
|
||||||
(format "(%s)" ref)))))
|
|
||||||
nil (and retain-labels (cdr code-info)))))))
|
|
||||||
;; Return value.
|
|
||||||
(format float-env body)))
|
|
||||||
;; Case 4. Use listings package.
|
|
||||||
(t
|
(t
|
||||||
(let ((lst-lang
|
(org-latex-src-block--listings src-block info lang caption caption-above-p label
|
||||||
(or (cadr (assq (intern lang)
|
num-start retain-labels attributes float))))))
|
||||||
(plist-get info :latex-listings-langs)))
|
|
||||||
lang))
|
|
||||||
(caption-str
|
|
||||||
(when caption
|
|
||||||
(let ((main (org-export-get-caption src-block))
|
|
||||||
(secondary (org-export-get-caption src-block t)))
|
|
||||||
(if (not secondary)
|
|
||||||
(format "{%s}" (org-export-data main info))
|
|
||||||
(format "{[%s]%s}"
|
|
||||||
(org-export-data secondary info)
|
|
||||||
(org-export-data main info))))))
|
|
||||||
(lst-opt (plist-get info :latex-listings-options)))
|
|
||||||
(concat
|
|
||||||
;; Options.
|
|
||||||
(format
|
|
||||||
"\\lstset{%s}\n"
|
|
||||||
(concat
|
|
||||||
(org-latex--make-option-string
|
|
||||||
(append
|
|
||||||
lst-opt
|
|
||||||
(cond
|
|
||||||
((and (not float) (plist-member attributes :float)) nil)
|
|
||||||
((string= "multicolumn" float) '(("float" "*")))
|
|
||||||
((and float (not (assoc "float" lst-opt)))
|
|
||||||
`(("float" ,(plist-get info :latex-default-figure-position)))))
|
|
||||||
`(("language" ,lst-lang))
|
|
||||||
(if label
|
|
||||||
`(("label" ,(org-latex--label src-block info)))
|
|
||||||
'(("label" " ")))
|
|
||||||
(if caption-str `(("caption" ,caption-str)) '(("caption" " ")))
|
|
||||||
`(("captionpos" ,(if caption-above-p "t" "b")))
|
|
||||||
(cond ((assoc "numbers" lst-opt) nil)
|
|
||||||
((not num-start) '(("numbers" "none")))
|
|
||||||
(t `(("firstnumber" ,(number-to-string (1+ num-start)))
|
|
||||||
("numbers" "left"))))))
|
|
||||||
(let ((local-options (plist-get attributes :options)))
|
|
||||||
(and local-options (concat "," local-options)))))
|
|
||||||
;; Source code.
|
|
||||||
(format
|
|
||||||
"\\begin{lstlisting}\n%s\\end{lstlisting}"
|
|
||||||
(let* ((code-info (org-export-unravel-code src-block))
|
|
||||||
(max-width
|
|
||||||
(apply 'max
|
|
||||||
(mapcar 'length
|
|
||||||
(org-split-string (car code-info) "\n")))))
|
|
||||||
(org-export-format-code
|
|
||||||
(car code-info)
|
|
||||||
(lambda (loc _num ref)
|
|
||||||
(concat
|
|
||||||
loc
|
|
||||||
(when ref
|
|
||||||
;; Ensure references are flushed to the right,
|
|
||||||
;; separated with 6 spaces from the widest line of
|
|
||||||
;; code
|
|
||||||
(concat (make-string (+ (- max-width (length loc)) 6) ?\s)
|
|
||||||
(format "(%s)" ref)))))
|
|
||||||
nil (and retain-labels (cdr code-info))))))))))))
|
|
||||||
|
|
||||||
|
(defun org-latex-src-block--verbatim
|
||||||
|
(src-block info _lang caption caption-above-p _label
|
||||||
|
_num-start _retain-labels _attributes float)
|
||||||
|
"Transcode a SRC-BLOCK element from Org to LaTeX, using verbatim.
|
||||||
|
LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
|
||||||
|
and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
|
||||||
|
(let ((caption-str (org-latex--caption/label-string src-block info))
|
||||||
|
(verbatim (format "\\begin{verbatim}\n%s\\end{verbatim}"
|
||||||
|
(org-export-format-code-default src-block info))))
|
||||||
|
(cond ((string= "multicolumn" float)
|
||||||
|
(format "\\begin{figure*}[%s]\n%s%s\n%s\\end{figure*}"
|
||||||
|
(plist-get info :latex-default-figure-position)
|
||||||
|
(if caption-above-p caption-str "")
|
||||||
|
verbatim
|
||||||
|
(if caption-above-p "" caption-str)))
|
||||||
|
(caption (concat
|
||||||
|
(if caption-above-p caption-str "")
|
||||||
|
verbatim
|
||||||
|
(if caption-above-p "" (concat "\n" caption-str))))
|
||||||
|
(t verbatim))))
|
||||||
|
|
||||||
|
(defun org-latex-src-block--custom
|
||||||
|
(src-block info _lang caption caption-above-p _label
|
||||||
|
_num-start _retain-labels attributes float custom-env)
|
||||||
|
"Transcode a SRC-BLOCK element from Org to LaTeX, using a custom environment.
|
||||||
|
LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
|
||||||
|
and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
|
||||||
|
(let ((caption-str (org-latex--caption/label-string src-block info))
|
||||||
|
(formatted-src (org-export-format-code-default src-block info)))
|
||||||
|
(if (string-match-p "\\`[a-zA-Z0-9]+\\'" custom-env)
|
||||||
|
(format "\\begin{%s}\n%s\\end{%s}\n"
|
||||||
|
custom-env
|
||||||
|
(concat (and caption-above-p caption-str)
|
||||||
|
formatted-src
|
||||||
|
(and (not caption-above-p) caption-str))
|
||||||
|
custom-env)
|
||||||
|
(format-spec custom-env
|
||||||
|
`((?s . ,formatted-src)
|
||||||
|
(?c . ,caption)
|
||||||
|
(?f . ,float)
|
||||||
|
(?l . ,(org-latex--label src-block info))
|
||||||
|
(?o . ,(or (plist-get attributes :options) "")))))))
|
||||||
|
|
||||||
|
(defun org-latex-src-block--minted
|
||||||
|
(src-block info lang caption caption-above-p _label
|
||||||
|
num-start retain-labels attributes float)
|
||||||
|
"Transcode a SRC-BLOCK element from Org to LaTeX, using minted.
|
||||||
|
LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
|
||||||
|
and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
|
||||||
|
(let* ((caption-str (org-latex--caption/label-string src-block info))
|
||||||
|
(placement (or (org-unbracket-string "[" "]" (plist-get attributes :placement))
|
||||||
|
(plist-get info :latex-default-figure-position)))
|
||||||
|
(float-env
|
||||||
|
(cond
|
||||||
|
((string= "multicolumn" float)
|
||||||
|
(format "\\begin{listing*}[%s]\n%s%%s\n%s\\end{listing*}"
|
||||||
|
placement
|
||||||
|
(if caption-above-p caption-str "")
|
||||||
|
(if caption-above-p "" caption-str)))
|
||||||
|
(caption
|
||||||
|
(format "\\begin{listing}[%s]\n%s%%s\n%s\\end{listing}"
|
||||||
|
placement
|
||||||
|
(if caption-above-p caption-str "")
|
||||||
|
(if caption-above-p "" caption-str)))
|
||||||
|
((string= "t" float)
|
||||||
|
(concat (format "\\begin{listing}[%s]\n"
|
||||||
|
placement)
|
||||||
|
"%s\n\\end{listing}"))
|
||||||
|
(t "%s")))
|
||||||
|
(options (plist-get info :latex-minted-options))
|
||||||
|
(body
|
||||||
|
(format
|
||||||
|
"\\begin{minted}[%s]{%s}\n%s\\end{minted}"
|
||||||
|
;; Options.
|
||||||
|
(concat
|
||||||
|
(org-latex--make-option-string
|
||||||
|
(if (or (not num-start) (assoc "linenos" options))
|
||||||
|
options
|
||||||
|
(append
|
||||||
|
`(("linenos")
|
||||||
|
("firstnumber" ,(number-to-string (1+ num-start))))
|
||||||
|
options)))
|
||||||
|
(let ((local-options (plist-get attributes :options)))
|
||||||
|
(and local-options (concat "," local-options))))
|
||||||
|
;; Language.
|
||||||
|
(or (cadr (assq (intern lang)
|
||||||
|
(plist-get info :latex-minted-langs)))
|
||||||
|
(downcase lang))
|
||||||
|
;; Source code.
|
||||||
|
(let* ((code-info (org-export-unravel-code src-block))
|
||||||
|
(max-width
|
||||||
|
(apply 'max
|
||||||
|
(mapcar 'length
|
||||||
|
(org-split-string (car code-info)
|
||||||
|
"\n")))))
|
||||||
|
(org-export-format-code
|
||||||
|
(car code-info)
|
||||||
|
(lambda (loc _num ref)
|
||||||
|
(concat
|
||||||
|
loc
|
||||||
|
(when ref
|
||||||
|
;; Ensure references are flushed to the right,
|
||||||
|
;; separated with 6 spaces from the widest line
|
||||||
|
;; of code.
|
||||||
|
(concat (make-string (+ (- max-width (length loc)) 6)
|
||||||
|
?\s)
|
||||||
|
(format "(%s)" ref)))))
|
||||||
|
nil (and retain-labels (cdr code-info)))))))
|
||||||
|
;; Return value.
|
||||||
|
(format float-env body)))
|
||||||
|
|
||||||
|
(defun org-latex-src-block--listings
|
||||||
|
(src-block info lang caption caption-above-p label
|
||||||
|
num-start retain-labels attributes float)
|
||||||
|
"Transcode a SRC-BLOCK element from Org to LaTeX, using listings.
|
||||||
|
LANG, CAPTION, CAPTION-ABOVE-P, LABEL, NUM-START, RETAIN-LABELS, ATTRIBUTES
|
||||||
|
and FLOAT are extracted from SRC-BLOCK and INFO in `org-latex-src-block'."
|
||||||
|
(let ((lst-lang
|
||||||
|
(or (cadr (assq (intern lang)
|
||||||
|
(plist-get info :latex-listings-langs)))
|
||||||
|
lang))
|
||||||
|
(caption-str
|
||||||
|
(when caption
|
||||||
|
(let ((main (org-export-get-caption src-block))
|
||||||
|
(secondary (org-export-get-caption src-block t)))
|
||||||
|
(if (not secondary)
|
||||||
|
(format "{%s}" (org-export-data main info))
|
||||||
|
(format "{[%s]%s}"
|
||||||
|
(org-export-data secondary info)
|
||||||
|
(org-export-data main info))))))
|
||||||
|
(lst-opt (plist-get info :latex-listings-options)))
|
||||||
|
(concat
|
||||||
|
;; Options.
|
||||||
|
(format
|
||||||
|
"\\lstset{%s}\n"
|
||||||
|
(concat
|
||||||
|
(org-latex--make-option-string
|
||||||
|
(append
|
||||||
|
lst-opt
|
||||||
|
(cond
|
||||||
|
((and (not float) (plist-member attributes :float)) nil)
|
||||||
|
((string= "multicolumn" float) '(("float" "*")))
|
||||||
|
((and float (not (assoc "float" lst-opt)))
|
||||||
|
`(("float" ,(plist-get info :latex-default-figure-position)))))
|
||||||
|
`(("language" ,lst-lang))
|
||||||
|
(if label
|
||||||
|
`(("label" ,(org-latex--label src-block info)))
|
||||||
|
'(("label" " ")))
|
||||||
|
(if caption-str `(("caption" ,caption-str)) '(("caption" " ")))
|
||||||
|
`(("captionpos" ,(if caption-above-p "t" "b")))
|
||||||
|
(cond ((assoc "numbers" lst-opt) nil)
|
||||||
|
((not num-start) '(("numbers" "none")))
|
||||||
|
(t `(("firstnumber" ,(number-to-string (1+ num-start)))
|
||||||
|
("numbers" "left"))))))
|
||||||
|
(let ((local-options (plist-get attributes :options)))
|
||||||
|
(and local-options (concat "," local-options)))))
|
||||||
|
;; Source code.
|
||||||
|
(format
|
||||||
|
"\\begin{lstlisting}\n%s\\end{lstlisting}"
|
||||||
|
(let* ((code-info (org-export-unravel-code src-block))
|
||||||
|
(max-width
|
||||||
|
(apply 'max
|
||||||
|
(mapcar 'length
|
||||||
|
(org-split-string (car code-info) "\n")))))
|
||||||
|
(org-export-format-code
|
||||||
|
(car code-info)
|
||||||
|
(lambda (loc _num ref)
|
||||||
|
(concat
|
||||||
|
loc
|
||||||
|
(when ref
|
||||||
|
;; Ensure references are flushed to the right,
|
||||||
|
;; separated with 6 spaces from the widest line of
|
||||||
|
;; code
|
||||||
|
(concat (make-string (+ (- max-width (length loc)) 6) ?\s)
|
||||||
|
(format "(%s)" ref)))))
|
||||||
|
nil (and retain-labels (cdr code-info))))))))
|
||||||
|
|
||||||
;;;; Statistics Cookie
|
;;;; Statistics Cookie
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue