Dmitrii Kashin's website

Website creation with Emacs Muse

Русский / English

Whan is Emacs Muse?

Emacs Muse - is a publisher developing by the GNU project. The main principle of work is: you write an article with some simple markdown, and then command "publish it!", it looks for recently modified articles in the current project and according to styles creates documents in another, appropriate for publication format.

Thus with the help of publisher it's possible to get a beautiful website if you have nothing against static ones.

How to use it?

Like a majority of GNU project programs, Emacs Muse is provided with great documentation in Info format., which is always available in Emacs via C-h i hot keys. If your distribution provides Muse without documentation, like for example in my case with Debian, you can download it on the official site and install it by the command run with the superuser privileges:

# ginstall-info /usr/share/info/dir

Before the beginning of site creation I'd recommended to read the documentation chapters about projects and styles. Learning markdown rules may be delayed, and you can use QuickStart.muse file (in Debian you can find it here: /usr/share/doc/muse-el/examples/QuickStart.muse)


Well, you've got QuickStart.muse file containing an article. You'd like to form a html-page from it. In order to do it you only need to type hot keys C-c C-t and order to apply an html style. As a result you'll get an .html-file with the article.

But of course the design is rather simple now. To create your own design you need to define a new style, derivative from html. In the example below I define a new style only differed from the base one with footer and header, which will be the skeleton of our new site.

(muse-derive-style "" "html"
		   :header "~/prog/muse/"
		   :footer "~/prog/muse/")

It's quite easily to write the skeleton. Firstly we need to choose a site design. If you're a good make-up (html coder), you can do it yourself. In my turn I used free templates from Andreas Viklund's site on the advice of Alexey Ott1

In order to cut the template into header and footer it's very convenient to use html-mode. You must know that when Muse form an article according to style, it goes through it's content looking for additional tags. The most important one seems to be the tag <lisp> which makes possible to evaluate an arbitrary S-expression and substitute the result of evaluation in the code. Examples of that construct use can be seen in my files header.tmpl and footer.tmpl.


For greater convenience you can group files and publish them all at once allowing Muse to track changes in them. These groups are called projects.

Documentation about projects is short and clear. Shortly speaking, the list of projects looks like this:


PROJECT-NAME defines the name of project, SOURCES is the list of directories where .muse-files are stored, and OUTPUTS are lists declaring what and where publish. If you're going to use multiple subdirectories then it's convenient to use muse-project-alist-dirs and muse-project-alist-styles functions, which traverse the tree of directories and form parameters counted above. Here how it can be done:

(setq muse-project-alist
      `(("" (,@(muse-project-alist-dirs "~/prog/muse/") :default "index")
	 ,@(muse-project-alist-styles "~/prog/muse/"


The stuff written above only shows a direction for the movement, but in order to finish you need to make a lot of efforts. Especially in plan of lisp-insertions. I confess I'm not very experienced with elisp, but I've been playing with it for some time and have written a few useful functions which will help you to save your time.

muse-file-relative-path - returns path from current file to target.
muse-current-file-relative-path - returns path from the root of current project to current file.

I use two languages for my site. In the root of project I've got two directories: en and ru. I determine the language of current file by the name of the first dir of its relative path.

muse-detect-language - determine the name of current file
muse-another-language-relative-path - returns a relative path to the same file but in another language.
muse-gen-locale-date - makes language substitutions in a date string. Months are declared in symbol months-translation:

(setq months-translation
      '(("ru" . (("January" . "января")
		 ("February" . "февраля")
		 ("November" . "ноября")
		 ("December" . "декабря")))))

To provide the multiple language support I've typed muse-generate-menu, which forms the menu with the variable

(setq '(("ru" . ( ("index.html" . "Главная")
			       ("articles/index.html" . "Статьи")
                               ("about.html" . "Обо мне")))
                     ("en" . ( ("index.html" . "Main")
			       ("articles/index.html" . "Articles")
			       ("about.html" . "About Me")))))

All these functions you can get from my file muse-config.el.


1. It'd be unfair not to note the man inspired me to this article - Alexey Ott, and his quite not bad article about his site creation. But in this article I'm describing my own experience of using Emacs Muse, and thus not to violate the licence CC BY-NC-ND 3.0, which his article's published with.

Last change: 7 Октябрь 2014