When exporting to HTML, org-mode renders a code block in a very ugly way, I don't like that. I want to use HighlightJs to highlight my exported code blocks. But, how do I tell org-mode to simply insert the content of the code block and wrap it around <pre><code> tags when exporting to HTML? adding the language name to <code> as a class would be great.

  • 1
    There doesn't seem to be a configuration for that. Looks like you'll have to advise org-html-src-block.
    – wvxvw
    Mar 5, 2015 at 7:38

2 Answers 2


see https://github.com/redguardtoo/org2nikola/blob/master/org2nikola.el

I simplify it a little bit. Now you just run org2html-export-subtree anywhere at the first level node, the content of the node will be output into a html file whose name is normalized from the node's title.

or you just C-c C-e which is handled by org2html-wrap-blocks-in-code

The original code is borrowed from org2blog, it supports org7 and org8. It's pretty stable.

Here is the complete code. It's exactly designed for highlight.js! I've been using it for many months. See http://blog.binchen.org for samples.

(defun org2html-trim-string (string)
  (replace-regexp-in-string "\\`[ \t\n]*" "" (replace-regexp-in-string "[ \t\n]*\\'" "" string)))

(defun org2html--char-to-string (ch)
  (let ((chspc 32)
        (chsq 39)
        (ch0 48)
        (ch9 57)
        (cha 97)
        (chz 122)
        (chA 65)
        (chZ 90)
        (chdot 46)
        (chminus 45)
        (chunderscore 95)
     ((or (and (<= ch0 ch) (<= ch ch9))
          (and (<= cha ch) (<= ch chz))
          (and (<= chA ch) (<= ch chZ))
          (= chunderscore ch)
          (= chminus ch)
      (setq rlt (char-to-string ch)))
     ((or (= chspc ch) (= chsq ch) (= chdot ch))
      (setq rlt "-")))

(defun org2html-get-slug (str)
  (let (slug )
    (setq slug (mapconcat 'org2html--char-to-string str ""))
    ;; clean slug a little bit
    (setq slug (replace-regexp-in-string "\-\-+" "-" slug))
    (setq slug (replace-regexp-in-string "^\-+" "" slug))
    (setq slug (replace-regexp-in-string "\-+$" "" slug))
    (setq slug (org2html-trim-string slug))
    (setq slug (downcase slug))

(defun org2html-replace-pre (html)
  "Replace pre blocks with sourcecode shortcode blocks.
shamelessly copied from org2blog/wp-replace-pre()"
    (let (pos code lang info params header code-start code-end html-attrs pre-class)
        (insert html)
        (goto-char (point-min))
          (while (re-search-forward "<pre\\(.*?\\)>" nil t 1)

            ;; When the codeblock is a src_block
                  (setq pre-class (match-string-no-properties 1))
                  (string-match "example" pre-class))
              ;; Replace the <pre...> text
              (setq lang (replace-regexp-in-string ".*src-\\([a-zA-Z0-9]+\\).*" "\\1" pre-class)  )

              (replace-match "")
              (setq code-start (point))

              ;; Go to end of code and remove </pre>
              (re-search-forward "</pre.*?>" nil t 1)
              (replace-match "")
              (setq code-end (point))
              (setq code (buffer-substring-no-properties code-start code-end))

              ;; Delete the code
              (delete-region code-start code-end)
              ;; Stripping out all the code highlighting done by htmlize
              (setq code (replace-regexp-in-string "<.*?>" "" code))

              ;; default is highlight.js, it's the best!
              (insert (concat "\n<pre><code class=\"lang-"


        ;; Get the new html!
        (setq html (buffer-substring-no-properties (point-min) (point-max))))

(defun org2html--render-subtree ()
  "Render current subtree"
  (let ((org-directory default-directory)

    ;; set title
    (setq title (nth 4 (org-heading-components)))

    ;; set POST_SLUG if its does not exist
    (setq post-slug (org2html-get-slug title))
    ;; html file
    (setq html-file (concat (file-name-as-directory default-directory) post-slug ".html"))
    (setq html-text (org2html-export-into-html-text))

      (setq html-text (org2html-replace-pre html-text)))

    (with-temp-file html-file
      (insert html-text))
    (message "%s created" html-file)

(defun org2html-export-into-html-text ()
  (let (html-text b e)

      (forward-line) ;; donot export title
      (setq b (region-beginning))
      (setq e (region-end))

    ;; org-export-as will detect active region and narrow to the region
      (setq html-text
             ((version-list-< (version-to-list (org-version)) '(8 0 0))
              (if (fboundp 'org-export-region-as-html)
                  (org-export-region-as-html b e t 'string)))
              (if (fboundp 'org-export-as)
                  (org-export-as 'html t nil t)))

(defun org2html-export-subtree ()
  "Export current first level subtree into HTML"
  (let ((org-directory default-directory)

    ;; just goto the root element
    (condition-case nil
        (outline-up-heading 8)
       (message "at the beginning ...")))

    ;; should be nil

(defun org2html-wrap-blocks-in-code (src backend info)
  (if (org-export-derived-backend-p backend 'html)
      (org2html-replace-pre src)))

(eval-after-load 'ox
     (add-to-list 'org-export-filter-src-block-functions
  • My only concern was the external functions, and the possible external function inside those external functions, how much work will cost to adapt this code snippet for my needs?
    – shackra
    Mar 6, 2015 at 0:13
  • I updated original code, there is no dependency now. all you need is copy/paste.
    – chen bin
    Mar 6, 2015 at 11:29
  • copying and pasting this elisp code makes me feel like a Script kiddie, ha! I really need to domain Emacs lisp!. Thank you!
    – shackra
    Mar 6, 2015 at 19:56
  • Also, I was using this (add-to-list 'org-export-filter-src-block-functions 'shackra:org-html-wrap-blocks-in-code) as in the @rasmus' answer. I wonder if is possible to connect the correct function on your code snippet (I wonder if it is org2html-replace-pre) to org-export-filter-src-block-functions! and should I keep or delete the (setq org-html-htmlize-output-type nil) statement?
    – shackra
    Mar 6, 2015 at 20:06
  • 1
    I updated code.
    – chen bin
    Mar 8, 2015 at 2:19

Maybe something like this:

(defun rasmus/org-html-wrap-blocks-in-code (src backend info)
  "Wrap a source block in <pre><code class=\"lang\">.</code></pre>"
  (when (org-export-derived-backend-p backend 'html)
     "\\(</pre>\\)" "</code>\n\\1"
     (replace-regexp-in-string "<pre class=\"src src-\\([^\"]*?\\)\">"
                               "<pre>\n<code class=\"\\1\">\n" src))))

(add-to-list 'org-export-filter-src-block-functions

(setq org-html-htmlize-output-type nil)
  • Why did I get htmlize-buffer-1: Symbol's function definition is void: nil?
    – shackra
    Mar 5, 2015 at 17:33
  • 1
    Maybe you haven't installed htmlize.el, which generates the fontification in the default ox-html.el setup. If so don't say (setq org-html-htmlize-output-type nil). If it is the case that (setq org-html-htmlize-output-type nil) breaks the exporter when htmlize.el is not installed, please report it as a bug on the mailing list.
    – rasmus
    Mar 5, 2015 at 18:34
  • I exported my blog with org-page, and no error was triggered, it actually works! So, I don't know what went wrong the first time.
    – shackra
    Mar 5, 2015 at 21:53
  • 1
    The magic pixies inside the cables! They do this kind of stuff. It is known!
    – rasmus
    Mar 5, 2015 at 23:35
  • the source code blocks include the programming language of the code, How do I access that information?
    – shackra
    Mar 6, 2015 at 6:35

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.