3

I'd like to get line numbers displayed for all the source blocks in Exported file ( html/pdf)

For a particular souce block, I got to add the switch -n to the source block
e.g.:

#+BEGIN_SRC C++ -n
  #include<iostream>
  using namespace std;
  int main() {
      cout<<"Hello World";
      return 0;
  }
#+END_SRC

Is it possible to add this switch globally in properties drawer or any better way?
So that I don’t have to add switches like these on all the source blocks..

2 Answers 2

2

The elisp code below provides some basic functionality for setting source block switches on a per-file basis with org-version 9.0.5.

You can set switches for all source blocks within a subtree with the switches property. If switches is set before the first heading it is valid for the whole file.

For an example the org-file

#+PROPERTY: switches: +n
* first level
  #+BEGIN_SRC emacs-lisp
(message "block in first level")
  #+END_SRC
** second level
   #+BEGIN_SRC emacs-lisp
(message "block in second level")
(message "second line")   
   #+END_SRC
* second heading in the first level
  #+BEGIN_SRC emacs-lisp
(message "first line")
(message "second line")
  #+END_SRC

exports the following rendered html-output. exported orgmode file

This is only a very basic implementation. A better implementation would require changes on the orgmode source code itself. Since this feature is very reasonable I've filed an enhancement request at the orgmode mailing list.

(require 'cl-lib)
(require 'org)
(require 'ox)
(require 'org-element)

(defvar org-src-switch-alist nil
  "Alist mapping an org source code switches to its argument parser (which can be nil) and its interpreter.")
(setq org-src-switches-alist
  '(("-n" org-src-parse-number (lambda (num) (list :number-lines (cons 'new (or num 0)))))
    ("+n" org-src-parse-number (lambda (num) (list :number-lines (cons 'continued (or num 0)))))
    ("-r" nil (:retain-labels nil))
    ("-i" nil (:preserve-indent t))
    ("-l" org-src-parse-quoted-string (lambda (str) (assert (stringp str)) (list :label-fmt str)))
    ("-k" nil (:use-labels t))))

(defun org-src-parse-number ()
  "Parse number at point and return it as the only element of a list.
If parsing fails the return value is (nil)."
  (list 
   (when (looking-at "[0-9]")
     (read (current-buffer)))))

(defun org-src-parse-quoted-string ()
  "Parse quoted string at point and return it as the only element of a list.
If parsing fails the return value is (nil)."
  (list
   (when (looking-at "\"")
     (read (current-buffer)))))

(defun org-src-switch-parse (str)
  "Parse org mode source block switches in string STR."
  (let ((sw-re (regexp-opt (mapcar 'car org-src-switches-alist)))
        ret)
    (with-temp-buffer
      (insert str)
      (goto-char (point-min))
      (while (progn
               (skip-syntax-forward  " ")
               (looking-at sw-re))
        (goto-char (match-end 0))
        (let* ((sw (assoc-string (match-string 0) org-src-switches-alist))
               (parser (cadr sw))
               (interpreter (nth 2 sw))
               args)
          (skip-syntax-forward " ")
          (when parser
            (setq args (funcall parser)))
          (setq ret
                (append
                 ret
                 (if (functionp interpreter)
                     (apply interpreter args)
                   interpreter))))))
    ret))

(defun org-src-switch-propagate (keyword-element)
  (let ((value
         (and (string-equal (org-element-property :key keyword-element) "PROPERTY")
              (org-element-property :value keyword-element))))
    (when (and value (string-match "switches:" (downcase value)))
      (setq value (org-src-switch-parse (substring value (match-end 0))))
      (let ((parent (org-element-property :parent keyword-element)))
    (when (and
           (eq (org-element-type parent) 'section)
           (eq (org-element-type (org-element-property :parent parent)) 'org-data))
      (setq parent (org-element-property :parent parent)))
    (org-element-map
        parent
        '(src-block example-block)
      `(lambda (bl)
         (cl-loop for pair on ',value by 'cddr
              do (org-element-put-property bl (car pair) (cadr pair)))))))))

(defun org-element-parse-buffer-ad (info)
  "Filter the INFO returned by `org-element-parse-buffer' for global switches
and apply them to source code blocks."
  (org-element-map info 'keyword #'org-src-switch-propagate)
  info)

(advice-add #'org-element-parse-buffer :filter-return #'org-element-parse-buffer-ad)
1
  • Hi @Tobias, thanks for the concise solution ..im using version 8.2.10 and in this version this solution isnt working ill try to upgrade and check this..
    – junnu
    Jul 6, 2017 at 4:02
0

I'm not sure how to do header args without :name arg format (e.g. just the -n in your example), but perhaps the following will help:

A specific language:

(setq org-babel-default-header-args:sh
  '((:prologue . "exec 2>&1") (:epilogue . ":"))

All languages:

 (setq org-babel-default-header-args
       (cons '(:noweb . "yes")
             (assq-delete-all :noweb org-babel-default-header-args)))

Source: http://orgmode.org/manual/System_002dwide-header-arguments.html

1
  • 1
    The original poster @junnu names -n in the header line correctly as switch. It is not a header argument. I doubt that your proposal helps with switches. I had a look into the source of org-element-src-block-parser and also in the exporter. The switches are quite hard-coded. Perhaps one would have a chance to override the :switches property in the element parser generated info via some advice somewhere. But, I don't have the time to try that.
    – Tobias
    Jul 5, 2017 at 11:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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