0

I can't tell in what update exactly did this happen but since not so long ago Org adds a label{orgsrcblock#} to custom listings environments. Unfortunately, I can't find a way to tell listings to ignore this line, and it gets printed together with the source code. Here's an example:

#+BEGIN_SRC emacs-lisp :exports none
  (setq org-latex-pdf-process
          '("latexmk -pdflatex='pdflatex -shell-escape -interaction nonstopmode' -pdf -f %f")
          org-latex-listings t
          org-src-fontify-natively t
          org-latex-custom-lang-environments '((maxima "maxima"))
          org-babel-latex-htlatex "htlatex")
  (defmacro by-backend (&rest body)
      `(cl-case (when (boundp 'backend) (org-export-backend-name backend))
         ,@body))
#+END_SRC

#+BEGIN_LATEX
\definecolor{codebg}{rgb}{0.96,0.99,0.8}
\lstnewenvironment{maxima}{%
  \lstset{%
    backgroundcolor=\color{codebg},
    aboveskip=20pt,
    captionpos=b,
    showstringspaces=false,
    frame=single,
    framerule=0pt,
    basicstyle=\ttfamily\scriptsize,
    columns=fixed}}{}
}
#+END_LATEX

then somewhere later:

*Solution:*
#+NAME: prob3
#+HEADER: :exports both
#+BEGIN_SRC maxima :results output raw
  n: 4;
  tex(sum(binomial(n, i) * 3^i * (-2)^(n - i), i, 0, n));
#+END_SRC

results in LaTeX code:

\textbf{Solution:}
\begin{maxima}
n: 4;
tex(sum(binomial(n, i) * 3^i * (-2)^(n - i), i, 0, n));
\label{orgsrcblock1}

\end{maxima}

and is displayed as:

enter image description here


The relevant part of Org code which generates this is:

org-latex-src-block in ox-latex.el

;; Case 2.  Custom environment.
   (custom-env
(let ((caption-str (org-latex--caption/label-string src-block info)))
  (format "\\begin{%s}\n%s\\end{%s}\n"
      custom-env
      (concat (and caption-above-p caption-str)
          (org-export-format-code-default src-block info)
          (and (not caption-above-p) caption-str))
      custom-env)))
  • Try (setq org-latex-prefer-user-labels t). Does that fix it? – mankoff May 14 '15 at 19:55
  • @mankoff this only works if I add some label, (i.e. it will choose my label over the one generated automatically), but won't prevent Org from inserting the \label{my-label}. A bit more complicated than that, Org will try in order: :custom_id, :target and :name properties of the code block, but I need to have :name set. – wvxvw May 14 '15 at 20:15
1

This appears to be a problem with how listings package treats LaTeX code inside listings. Below is a patch, for those who may encounter this problem, but I doubt Org developers will be willing to incorporate this, so use at your own risk.

From 063a5ea97a9d7810a344b3e6fafcb6ebb1588d6c Mon Sep 17 00:00:00 2001
From: wvxvw <wvxvw@localhost>
Date: Thu, 14 May 2015 17:00:25 +0300
Subject: [PATCH] Wrap labels when in custom listings environment.

---
 lisp/ox-latex.el | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 192739a..bd57e13 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1058,6 +1058,17 @@ INFO is a plist holding contextual information."
       (let ((type (org-element-type element)))
    (memq (if (eq type 'link) 'image type) above)))))

+(defvar org-listings-escape-inside nil
+  "Whenever `org-latex-custom-lang-environments' is set setting
+this variable will result in \"\\label{}\" being wrapped into 
+specified delimiters.  For example, if set to '(\"(@*\" . \"*@)\")
+will produces \"(@*\\label{}*@)\".  This must correspond with
+\\lstnewenvironment{new-language}{%
+  \\lstset{%
+    escapeinside={(*@}{@*)},
+    ...}}
+")
+
 (defun org-latex--label (datum info &optional force full)
   "Return an appropriate label for DATUM.
 DATUM is an element or a `target' type object.  INFO is the
@@ -1068,7 +1079,8 @@ keyword or no CUSTOM_ID property, unless FORCE is non-nil.  In
 this case always return a unique label.

 Eventually, if FULL is non-nil, wrap label within \"\\label{}\"."
-  (let* ((type (org-element-type datum))
+  (let* ((lang (org-element-property :language datum))
+    (type (org-element-type datum))
     (user-label
      (org-element-property
       (case type
@@ -1093,9 +1105,16 @@ Eventually, if FULL is non-nil, wrap label within \"\\label{}\"."
                 "fig:")))
             (org-export-get-reference datum info))))))
     (cond ((not full) label)
-     (label (format "\\label{%s}%s"
-            label
-            (if (eq type 'target) "" "\n")))
+     (label
+      (cl-destructuring-bind (left . right)
+          (if (and lang org-listings-escape-inside
+           (cadr (assq (intern lang)
+                   org-latex-custom-lang-environments)))
+          org-listings-escape-inside
+        '("" . ""))
+        (format "%s\\label{%s}%s%s"
+            left label
+            (if (eq type 'target) "" "\n") right)))
      (t ""))))

 (defun org-latex--caption/label-string (element info)
-- 
2.1.0

The source of the problem was that listings package treats LaTeX code inside its environment as verbatim. But it is also possible to make it look for interpretable LaTeX code. In order to do this, you need to wrap that code in special delimiters. So, for example, your environment definition could look like this:

\lstnewenvironment{maxima}{%
  \lstset{%
    backgroundcolor=\color{codebg},
    escapeinside={(*@}{@*)},
    aboveskip=20pt,
    captionpos=b,
    label=,
    caption=,
    showstringspaces=false,
    frame=single,
    framerule=0pt,
    basicstyle=\ttfamily\scriptsize,
    columns=fixed}}{}
}

Note the escapeinside={(*@}{@*)}, line. Then you would also set:

(setq org-latex-custom-lang-environments '((maxima "maxima"))
      org-listings-escape-inside '("(*@" . "@*)"))

And, provided you applied the patch, Org will generate the code similar to:

\begin{maxima}
n: 4;
tex(sum(binomial(n, i) * 3^i * (-2)^(n - i), i, 0, n));
(*@\label{orgsrcblock1}
@*)
\end{maxima}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.