Orgmode Plugin init.el
Table of Contents
This is the emacs configuration (init.el
) for the orgmode plugin to export posts and pages to HTML. I spent forever messing with the init.el
file for my emacs instance, but it turns out that the plugin has its own configuration so you have to make changes here or they won't matter.
Pygments
This is the list of languages that pygments will colorize when source-code blocks are exported. The org-babel documentation has a list of supported languages, but it doesn't list fish
, although that seems to work. It might be because I inserted fish-mode, or maybe it just has to be a supported pygments language.
The first argument is what you put as the type in the source block and the second is the pygments short-name ("org-source-name" . "pygments-name")
.
Fish
Add coloring for the fish-shell.
("fish" . "fish")
function color_test
echo "colorize me"
end
Gherkin
("gherkin" . "gherkin")
Scenario: Gherkin colorization
Feature: Pygments gherkin colorization
Given a gherkin feature file
When the org-mode file is exported to HTML
Then the feature fragment is colorized.
HTML
("html" . "html")
<h1>Colorize HTML</h1>
INI
Jinja
("jinja" . "html+jinja")
{% macro pseudocode() %}
<script src="https://cdn.jsdelivr.net/npm/pseudocode@latest/build/pseudocode.min.js"></script>
{% endmacro %}
Mako
("mako" . "html+mako")
<%def name="pseudocode()">
<script src="https://cdn.jsdelivr.net/npm/pseudocode@latest/build/pseudocode.min.js"></script>
</%def>
Lazy Image Loading
This adds Lazy Loading to the HTML image tags.
;; Export images with lazy link type
(defun org-custom-link-img-url-export (path desc format)
(cond
((eq format 'html)
(format "<img src=\"%s\" alt=\"%s\" loading=\"lazy\" />" path desc))))
(org-add-link-type "lazy-img-url" nil 'org-custom-link-img-url-export)
This is supposed to let the browser know that it doesn't have to load the image until it's within view of the user. Here's an example hosted on pCloud.
You use it by using lazy-img-url
instead of img-url
in an image link.
[[lazy-img-url:test-image.png][Alternate Image Name]]
Silencing the Python Warning
Emacs warns you that it's using 4 spaces for the python code, which is what we want anyway, so this should, hopefully, turn off all those warnings.
(setq python-indent-guess-indent-offset t)
(setq python-indent-guess-indent-offset-verbose nil)
The Tangle
;; Init file to use with the orgmode plugin.
;; this is generated from the post with the slug: orgmode-plugin-initel
;; Load org-mode
;; Requires org-mode v8.x
(require 'package)
(setq package-load-list '((htmlize t)))
(package-initialize)
(require 'org)
(require 'ox-html)
;;; Custom configuration for the export.
;;; Add any custom configuration that you would like to 'conf.el'.
(setq nikola-use-pygments t
org-export-with-toc nil
org-export-with-section-numbers nil
org-startup-folded 'showeverything)
;; Load additional configuration from conf.el
(let ((conf (expand-file-name "conf.el" (file-name-directory load-file-name))))
(if (file-exists-p conf)
(load-file conf)))
;;; Macros
;; Load Nikola macros
(setq nikola-macro-templates
(with-current-buffer
(find-file
(expand-file-name "macros.org" (file-name-directory load-file-name)))
(org-macro--collect-macros)))
;;; Code highlighting
(defun org-html-decode-plain-text (text)
"Convert HTML character to plain TEXT. i.e. do the inversion of
`org-html-encode-plain-text`. Possible conversions are set in
`org-html-protect-char-alist'."
(mapc
(lambda (pair)
(setq text (replace-regexp-in-string (cdr pair) (car pair) text t t)))
(reverse org-html-protect-char-alist))
text)
;; Use pygments highlighting for code
(defun pygmentize (lang code)
"Use Pygments to highlight the given code and return the output"
(with-temp-buffer
(insert code)
(let ((lang (or (cdr (assoc lang org-pygments-language-alist)) "text")))
(shell-command-on-region (point-min) (point-max)
(format "pygmentize -f html -l %s" lang)
(buffer-name) t))
(buffer-string)))
(defconst org-pygments-language-alist
'(("asymptote" . "asymptote")
("awk" . "awk")
("c" . "c")
("console" . "console")
("c++" . "cpp")
("cpp" . "cpp")
("clojure" . "clojure")
("css" . "css")
("d" . "d")
("emacs-lisp" . "scheme")
("F90" . "fortran")
<<fish-pygments>>
<<gherkin-pygments>>
("gnuplot" . "gnuplot")
("groovy" . "groovy")
("haskell" . "haskell")
<<html-pygments>>
<<ini-pygments>>
("java" . "java")
<<jinja-pygments>>
("js" . "js")
("julia" . "julia")
("latex" . "latex")
("lisp" . "lisp")
<<mako-pygments>>
("makefile" . "makefile")
("matlab" . "matlab")
("mscgen" . "mscgen")
("ocaml" . "ocaml")
("octave" . "octave")
("perl" . "perl")
("picolisp" . "scheme")
("python" . "python")
("r" . "r")
("ruby" . "ruby")
("sass" . "sass")
("scala" . "scala")
("scheme" . "scheme")
("sh" . "sh")
("shell-session" . "shell-session")
("sql" . "sql")
("sqlite" . "sqlite3")
("tcl" . "tcl"))
"Alist between org-babel languages and Pygments lexers.
lang is downcased before assoc, so use lowercase to describe language available.
See: http://orgmode.org/worg/org-contrib/babel/languages.html and
http://pygments.org/docs/lexers/ for adding new languages to the mapping.")
;; Override the html export function to use pygments
(defun org-html-src-block (src-block contents info)
"Transcode a SRC-BLOCK element from Org to HTML.
CONTENTS holds the contents of the item. INFO is a plist holding
contextual information."
(if (org-export-read-attribute :attr_html src-block :textarea)
(org-html--textarea-block src-block)
(let ((lang (org-element-property :language src-block))
(code (org-element-property :value src-block))
(code-html (org-html-format-code src-block info)))
(if nikola-use-pygments
(progn
(unless lang (setq lang ""))
(pygmentize (downcase lang) (org-html-decode-plain-text code)))
code-html))))
;; Export images with custom link type
(defun org-custom-link-img-url-export (path desc format)
(cond
((eq format 'html)
(format "<img src=\"%s\" alt=\"%s\"/>" path desc))))
(org-add-link-type "img-url" nil 'org-custom-link-img-url-export)
;; Export images with built-in file scheme
(defun org-file-link-img-url-export (path desc format)
(cond
((eq format 'html)
(format "<img src=\"/%s\" alt=\"%s\"/>" path desc))))
(org-add-link-type "file" nil 'org-file-link-img-url-export)
;; Support for magic links (link:// scheme)
(org-link-set-parameters
"link"
:export (lambda (path desc backend)
(cond
((eq 'html backend)
(format "<a href=\"link:%s\">%s</a>"
path (or desc path))))))
<<lazy-load-images>>
;; Export function used by Nikola.
(defun nikola-html-export (infile outfile)
"Export the body only of the input file and write it to
specified location."
(with-current-buffer (find-file infile)
(org-macro-replace-all nikola-macro-templates)
(org-html-export-as-html nil nil t t)
(write-file outfile nil)))
;; silence notice that emacs is using a default of 4 spaces
<<python-space-guess-silence>>
Links
- Chaganti P. Plugins for Nikola. 2020 [cited 2023 Jun 25]. orgmode. Available from: https://plugins.getnikola.com/v8/orgmode/
- Babel: Languages [Internet]. [cited 2023 Jun 25]. Available from: https://orgmode.org/worg/org-contrib/babel/languages/index.html
- Languages — Pygments [Internet]. [cited 2023 Jun 25]. Available from: https://pygments.org/languages/