6

Colored syntax highlighting of code blocks in .org files works well when executed through the main init.el file. However, when setting up Emacs and Org-mode to publish projects asynchronously, colored synatax highlighting is not present and only bold and underlined formatting is used.

I have the following minimal example:

init.el

(add-to-list 'load-path "~/.emacs.d/modes/org-mode-8.2.10/lisp")
(add-to-list 'load-path "~/.emacs.d/modes/htmlize-1.6.1/")
(require 'org) 
(require 'htmlize)

(setq org-src-fontify-natively t)    

(setq org-publish-project-alist
      '(
        ("prj"
         :base-directory "~/tmp/org-export-test/"
         :base-extension "org"
         :publishing-directory "~/tmp/org-export-pub/"
         :recursive t
         :publishing-function org-html-publish-to-html
         )))

;; async export options
(setq org-export-async-debug t)
(setq org-export-async-init-file
      (expand-file-name "export-async-init-file.el"
            (file-name-directory user-init-file)))

(global-set-key (kbd "C-c C-8")
                (lambda () (interactive) (org-publish "prj")))
;;      (lambda () (interactive) (org-publish "prj" :ASYNC t)))

export-async-init-file.el

(add-to-list 'load-path "~/.emacs.d/modes/org-mode-8.2.10/lisp")
(add-to-list 'load-path "~/.emacs.d/modes/htmlize-1.6.1/")
(require 'org) 
(require 'htmlize)

(setq org-src-fontify-natively t)

(setq org-export-async-debug t)

Org file in the project folder

Hello world example code:

#+BEGIN_SRC python
def hello_world(name):
    print(name)
#+END_SRC

The above should be colored and highlighted.

In the above settings I get

enter image description here

When switching on the asynchronous export however (switching the comment on the last two lines of init.el), I get

enter image description here

How can I set up the above configuration to get color highlighting in asynchronous export as well?

(Note: While I would like to make colored syntax highlighting work in Org-mode 8.2.10, I have also tried the above example with the latest Org-mode 9.0.5 and have found the same behavior.)

2 Answers 2

11

With ox-html? See the docstring of org-html-htmlize-output-type.

Output type to be used by htmlize when formatting code snippets. Choices are css to export the CSS selectors only,inline-css to export the CSS attribute values inline in the HTML or nil to export plain text. We use as default inline-css, in order to make the resulting HTML self-containing.

However, this will fail when using Emacs in batch mode for export, because then no rich font definitions are in place. It will also not be good if people with different Emacs setup contribute HTML files to a website, because the fonts will represent the individual setups. In these cases, it is much better to let Org/Htmlize assign classes only, and to use a style file to define the look of these classes. To get a start for your css file, start Emacs session and make sure that all the faces you are interested in are defined, for example by loading files in all modes you want. Then, use the command M-x org-html-htmlize-generate-css to extract class definitions.

Here's an example.

#+bind: org-html-htmlize-output-type css
#+BEGIN_SRC emacs-lisp :var css-file="code.css" :results raw
  (unless noninteractive
    (org-html-htmlize-generate-css)
    (with-current-buffer "*html*"
      (write-file css-file))
    (format "#+html_head_extra: <link rel=\"stylesheet\" type=\"text/css\" href=\"%s\"/>"
        css-file))
#+END_SRC

#+RESULTS:
#+html_head_extra: <link rel="stylesheet" type="text/css" href="code.css"/>

Hello world example code:

#+BEGIN_SRC python
def hello_world(name):
    print(name)
#+END_SRC

The above should be colored and highlighted.

The file above is made to be self-contained and should work from emacs -q. #+bind is used for setting variables on a file basis, typically variables that cannot be changed via #+options. To use #+bind, org-export-allow-bind-keywords should be non-nil. Here,#+bind can be thought of as (setq-local org-html-htmlize-output-type 'css) in the org export buffer.

The src-block is a fancy way to (0) generate code.css via org-html-htmlize-generate-css and (1) generate the ox-html instruction to include this stylesheet, namely #+html_head_extra: <link rel="stylesheet" type="text/css" href="code.css"/>.

4
  • Thanks, setting org-html-htmlize-output-type to css and defining highlighting styles externally - as generated by org-html-htmlize-generate-css - did the trick. I initially tried setting org-export-htmlize-output-type, I don't know where I had that from, but it doesn't seem to work with this. I must admit that I don't quite understand your example, but the reference you gave I believe fully answers my question. Thanks again! Commented Mar 16, 2017 at 9:39
  • What part do you not understand out of curiosity?
    – rasmus
    Commented Mar 16, 2017 at 11:54
  • Here's what I think I understand: I think with the example you've given, you set the htmlize output type to css, generate the highlighting stylesheet and have it included in the header of the generated html document. And you do this all in one org-file? I don't understand how you do this (#+bind:?, :var css-file="code.css" :results raw, #+RESULTS:?). What would I need to do to have this work with the minimal example above? Just using your org file instead of the one I gave doesn't seem to work. Commented Mar 16, 2017 at 12:24
  • @FelixZ.Hoffmann I updated the answer.
    – rasmus
    Commented Mar 22, 2017 at 9:08
3

This builds on rasmus answer and shows how to get org files converted to html in a build system. Tested on Emacs 25.

In your ~/.emacs

(require 'org)
(setq org-src-fontify-natively t)

this will display code blocks syntactically with colors. This only helps with editing.

Given batch-org-to-html.el:

(require 'org)
(require 'ox-html)

(defun batch-org-to-html--load-file (org-file)
  (setq make-backup-files nil)   ;; no need to create backup~ on generated files
  (find-file org-file))

(defun batch-org-to-html--get-css-file ()
  (save-excursion
    (save-restriction
      (let (css-file)
        (when (re-search-forward
               (concat
                "^#\\+HTML_HEAD_EXTRA:" "\\s-"
                "<link" "\\s-" "rel=\"stylesheet\"" "\\s-" "type=\"text/css\"" "\\s-"
                "href=\"\\([^\"]+\\.css\\)\"/>")
               nil t)
          (setq css-file (match-string 1)))
        css-file))))

(defun batch-org-to-html (org-file)
  "Convert ORG-FILE with a .org extension to FILE.html
Use batch-org-to-html from the command line in batch mode."
  (batch-org-to-html--load-file org-file)
  (when (batch-org-to-html--get-css-file)
    (setq org-html-htmlize-output-type 'css))
  (org-html-export-to-html))

(defun batch-org-gen-css-and-exit (org-file)
  "Generate *.css for org-file. Give file.org, will produce
file.css. To generate the CSS file, the window layers of Emacs
must be loaded. The windowing portions of Emacs are required to
get the font faces. After generating the CSS, this quits
Emacs."
  (batch-org-to-html--load-file org-file)
  (let ((css-file (batch-org-to-html--get-css-file)))
    (if (not css-file)
        (error "%s is missing the *.css file specification." css-file))
    (org-html-htmlize-generate-css)
    (with-current-buffer "*html*"
      (write-file css-file)))
  (kill-emacs))

you can then integrate html generation into a build system using:

# This needs to be done once
emacs -q -l batch-org-to-html.el '--eval=(batch-org-gen-css-and-exit "test.org")'

# Run this as you update your org file
emacs -q --batch -l batch-org-to-html.el '--eval=(batch-org-to-html "test.org")'

Where the test.org contains:

#+STARTUP: showall
#+TITLE: Test

# ----------
# | Styles |
# ----------
#   1. The first HTML_HEAD_EXTRA link is used to produce styles-from-org.css
#   2. The second HTML_HEAD_EXTRA link is additional handwritten styling
#
#+HTML_HEAD_EXTRA: <link rel="stylesheet" type="text/css" href="styles-from-org.css"/>
#+HTML_HEAD_EXTRA: <link rel="stylesheet" type="text/css" href="styles.css"/>

# --------------------
# | org-mode options |
# --------------------
# 1. Toggle TeX-like syntax for sub- and superscripts. "^{}" will be interpreted but the
#    simple 'a_b' will be left as is.
# 2. Only two levels of toc (toc:2).
#
#+OPTIONS: ^:{}
#+OPTIONS: toc:2

* Head1

Head1 body.

1. Item one
   - bullet 1
   - bullet 2
2. Item two

** Head2

Head2 body. Example link, http://www.google.com


*** Head3

Example with colors:

#+BEGIN_SRC c++
  if (a > 10) {
      b = 20;
  }
#+END_SRC

and extra handwritten style.css contains:

body {
  font-size: 11pt;
  text-align: left;
  line-height:1.2em;
}

h1 {font-size: 14pt;}

.title {
  padding-bottom: 7px;
  margin-bottom: 20px;
  border-bottom: 1px solid #222;
}

h2 {
  font-size: 12pt;
  padding-bottom: 4px;
  margin-top: 5px;
  margin-bottom: 5px;
  border-bottom: 1px solid #DDD;
}

h3 {font-size: 11pt; color: #0000ff;}
h4 {font-size: 9pt; color: #a34d32;}

a {text-decoration: none; color: #537d7b}
a:visited {text-decoration: none; color: #98855b}
a:hover {text-decoration: underline; color: #a34d32}

Your Answer

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

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