Before the creation of this current my blog “engine” was NanoBlogger. It is a very cool project which aims to construct a blog engine using only generic UNIX commands (cat, grep, sed, …).
After using it a while, I remarked that NanoBlogger generates its own text-based database to track modifications of articles. It also generates many files during the generation and creation process. This trough me away. Why not using the perfect tool to track dependencies and generate files ? GNU Make.
After some experiments, I choose Gnu Awk to parse content and tags, Markdown for translating a wiki-like syntax to html. And the last dependency is an ftp program and a shell script used to sync your local site to the web.
I use a template to generate xhtml structure. This template must contain tags in
the form of
:TAG_NAME:
.
First we must have a symetric pre-suffix readable pattern :
is a good choice.
Secondly we need a unique tag name pattern, a one who no man must write. The
double collumns is not used in a pattern like that: :BLABLABLA:
.
See the template for this site.
To easily match a tag pattern, we use the pre-suffix as RS
(Record
Separator).
Now if we want to match :TAG:
, we just have to write :
/^:TAG:$/ { Do what you want here... }
To perform advanced construct in the awk script, we need to know the content
file (paste the content at the
:CONTENT:
tag and the output
file name to perform tree navigation.
To read the content file, we read the file in the
:CONTENT:
tag block.
/^:CONTENT:$/ { while ((getline content <input) > 0) print content >output; already_printed = "true"; }
To construct a navigation tree, your files must be organized in th same path. For this site, I have the “about”, “project”, … directories.
/^:HEADER:$/ { print "<a href=\"/davidcl/index.html\">davidcl</a> > " >output; num_directories = split (output, path, "/"); for (i=1; i<num_directories; i++) { print "<a href=\"/davidcl/" path[i] "\">" path[i] "</a>" >output; print " > " >output; } name = path[num_directories]; sub (/.html/, "", name); print name >output; already_printed = "true"; }
The Makefile first define tools and root directories which will be parsed. If you want you can add per-directory rule and these rules will be included.
# Tools path MARKDOWN = /usr/bin/markdown AWK = /usr/bin/gawk SH = /bin/sh RM = /bin/rm -f CAT = /bin/cat TOUCH = /bin/touch # Setting default searching directories directories = projects articles about # including per-directory specific rules (if any). # Use to add sub-directories to the $(directories) variables -include $(addsuffix /Makefile, $(directories)) # Adding others path to the directories variable after inclusion directories += . styles
After this configuration definition we search for all .text (Markdown content) files, all .htm (xhtml content) files and all others files (images, css).
Then rules are defined. First, global commands :
Secondly, generic commands :
%.htm: %.text $(MARKDOWN) $< > $@ %.html: %.htm templates/default.template template.awk $(AWK) -f template.awk -v input="$<" -v output="$@" templates/default.template %.atom: %.htm templates/atom-entry.template template.awk $(AWK) -f template.awk -v input="$<" -v output="$@" templates/atom-entry.template
See the makefile for this site.
My website can be used as an example, simply delete the content and write your own.
Fork me on github !!!