org mode导出latex, 如何自定义元素(比如代码块)使用的环境?

我想用mintinline导出==~~, 用langbox导出代码块. 有没有示例可以做到这一点呢?

有帮助的内容: 这个非常好的教程, 13.17最后的例子, 以及ox-latex.el. 大概有这几步:

  • 定义元素函数
  • 添加后端
  • 定义命令使用添加的后端 代码对除了我以外的所有人都没什么用, 因为仅仅是把minted改成langbox. 仅供参考:
(defun marktex-src-block (src-block _contents info)
  "Transcode a SRC-BLOCK element from Org to LaTeX.
CONTENTS holds the contents of the item.  INFO is a plist holding
contextual information."
  (when (org-string-nw-p (org-element-property :value src-block))
    (let* ((lang (org-element-property :language src-block))
	   (caption (org-element-property :caption src-block))
	   (caption-above-p (org-latex--caption-above-p src-block info))
	   (label (org-element-property :name src-block))
	   (custom-env (and lang
			    (cadr (assq (intern lang)
					org-latex-custom-lang-environments))))
	   (num-start (org-export-get-loc src-block info))
	   (retain-labels (org-element-property :retain-labels src-block))
	   (attributes (org-export-read-attribute :attr_latex src-block))
	   (float (plist-get attributes :float))
	   (listings (plist-get info :latex-listings)))
      (cond
       ;; Case 1.  No source fontification.
       ((or (not lang) (not listings))
	(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))))
       ;; Case 2.  Custom environment.
       (custom-env
	(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) "")))))))
       ;; Case 3.  Use minted package.
       ((eq listings 'minted)
	(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{langbox}[%s]\n%s\\end{langbox}"
		 ;; 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
	(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))))))))))))

(org-export-define-derived-backend 'marktex 'latex :translate-alist '((src-block . marktex-src-block)))


(defun marktex-latex-export ()
  (interactive)
  (let ((outfile (org-export-output-file-name ".tex")))
    (org-export-to-file 'marktex outfile )))