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.
How to insert the content of a org-mode's code block inside <pre><code> tags when exporting to HTML?
2 Answers
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)
rlt)
(cond
((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 "-")))
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))
slug))
(defun org2html-replace-pre (html)
"Replace pre blocks with sourcecode shortcode blocks.
shamelessly copied from org2blog/wp-replace-pre()"
(save-excursion
(let (pos code lang info params header code-start code-end html-attrs pre-class)
(with-temp-buffer
(insert html)
(goto-char (point-min))
(save-match-data
(while (re-search-forward "<pre\\(.*?\\)>" nil t 1)
;; When the codeblock is a src_block
(unless
(save-match-data
(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-"
lang
"\">\n"
code
"</code></pre>\n"))
)))
;; Get the new html!
(setq html (buffer-substring-no-properties (point-min) (point-max))))
))
html)
(defun org2html--render-subtree ()
"Render current subtree"
(let ((org-directory default-directory)
html-file
tags
title
post-slug
html-text)
;; 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))
(save-excursion
(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)
(save-excursion
(org-mark-element)
(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
(save-excursion
(setq html-text
(cond
((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)))
(t
(if (fboundp 'org-export-as)
(org-export-as 'html t nil t)))
)))
html-text))
(defun org2html-export-subtree ()
"Export current first level subtree into HTML"
(interactive)
(let ((org-directory default-directory)
html-file
tags
title
post-slug
html-text)
;; just goto the root element
(condition-case nil
(outline-up-heading 8)
(error
(message "at the beginning ...")))
;; should be nil
(org2html--render-subtree)
))
(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
'(progn
(add-to-list 'org-export-filter-src-block-functions
'org2html-wrap-blocks-in-code)
))
-
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?– shackraCommented Mar 6, 2015 at 0:13
-
I updated original code, there is no dependency now. all you need is copy/paste.– chen binCommented 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!– shackraCommented 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 isorg2html-replace-pre
) toorg-export-filter-src-block-functions
! and should I keep or delete the(setq org-html-htmlize-output-type nil)
statement?– shackraCommented Mar 6, 2015 at 20:06 -
1
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)
(replace-regexp-in-string
"\\(</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
'rasmus/org-html-wrap-blocks-in-code)
(setq org-html-htmlize-output-type nil)
-
Why did I get
htmlize-buffer-1: Symbol's function definition is void: nil
?– shackraCommented Mar 5, 2015 at 17:33 -
1Maybe you haven't installed
htmlize.el
, which generates the fontification in the defaultox-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 whenhtmlize.el
is not installed, please report it as a bug on the mailing list.– rasmusCommented 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.– shackraCommented Mar 5, 2015 at 21:53
-
1The magic pixies inside the cables! They do this kind of stuff. It is known!– rasmusCommented Mar 5, 2015 at 23:35
-
the source code blocks include the programming language of the code, How do I access that information?– shackraCommented Mar 6, 2015 at 6:35
org-html-src-block
.