Collected Markdown Makefile Wisdom
November 20, 2008
I’ve collected a few examples of Makefile rules that use various implementations of Markdown to generate XHTML from plain text files.
First, Hans Fugal offers the following Markdown Makefile Idiom:
all: $(patsubst %.txt,%.html,$(wildcard *.txt))
%.html: %.txt header.html footer.html
cat header.html > $@
markdown $< >> $@
cat footer.html >> $@
This one is pretty standard. The patsubst
macro is used to generate
the list of .html
targets from the filenames of all .txt
files in
the directory. It processes all of the .txt
files using Markdown
and applies a header and footer.
P. Damian Cugley wrote up some notes on using Markdown and Make to maintain a bunch of documents. He provides the following Make rules:
MARKDOWN = markdown
txtFiles = index.txt
all: $(txtFiles:.txt=.html)
clean:
rm -f $(txtFiles:.txt=.html)
.SUFFIXES: .txt .html
.txt.html:
$(MARKDOWN) < $< > $@
This version is much like the previous one except that it doesn’t
perform any globbing–one has to list the txtFiles
manually.
However, the best part of this example is the more advanced version
that follows (see the link). It uses a clever sed script to wrap a
header and footer around the output, using the first h1
element on
the page as the title.
The Pandoc source code includes the Markdown source for the website and a Makefile for building it. It is complicated by the fact that it also automatically runs some demos, but abstracting away from that it basically does the following:
ALL := index.html README.html INSTALL.html examples.html
PANDOC_PATH ?= $(dir $(shell which pandoc))
MAKEPAGE = $(PANDOC_PATH)/pandoc -s -S -H css -A footer.html
%.html : %.txt css
$(MAKEPAGE) $< > $@
Here, Pandoc’s -s
flag results in a standalone XHTML document with
an appropriate header and footer. The -H
flag includes the contents
of a file before the document body while -A
works similarly at the
end of the document.
A project called Obi has a documentation Makefile which processes
pages with Markdown but calls xsltproc
using the stylesheet
template.xslt which takes the text of the first h1
tag to use as
the title.
XSLT = xsltproc
PERL = perl
MARKDOWN = markdown
INDENT = xmllint --format
STYLESHEET = template.xslt
HTML_FILES = blocks.html events.html index.html manual.html plan.html
all: $(HTML_FILES)
%.html: %.txt
echo "<markdown>" > $@.markdown && \
$(MARKDOWN) $< >> $@.markdown && \
echo "</markdown>" >> $@.markdown && \
$(XSLT) $(STYLESHEET) $@.markdown | $(INDENT) - > $@ && \
$(RM) $@.markdown
.PHONY: clean
clean:
$(RM) *.markdown $(HTML_FILES)
Finally, the rngzip Makefile contains the following:
DOCS := README INSTALL USAGE CAVEATS COPYING
DOCS_HTML := $(addprefix doc/,$(addsuffix .html,$(DOCS)))
MARKDOWN = libs/markdown/Markdown.pl
doc/%.html: % doc/head doc/foot
(cat doc/head; perl $(MARKDOWN) <$*; cat doc/foot) \
| recode -d u8..h4 >$@
This example groups the header, body, and footer and pipes everything
to recode
to convert the entities from UTF–8 to HTML4. This
construct might be useful for other types of processing as well
(e.g., tidy
).