Blogging with pandoc, perl and javascript
2018-11-09
Derek Zhou
I've been blogging with Nikola since 2013. Nikola is a great to to generate static sites, such as blog, and it has many functionalities that are cool. However, sometimes you just want to roll your own for itching reasons:
- Nikola has many dependancies, many of its functionalies are of no use for me
- Its markdown support is limited; many markdown extensions are not supported
- Its front page is paginated by year, which is awkward when you want to search text
So I start coding and a couple of days later, I have a new system up that cover all functionalities I need, plus it looks better than the old one!
What I like from Nikola
First we have to learn from the past. Nikola based blog has several stonrg points I like to keep:
- All metadata are embedded at the beginning of the post, so to add a post we just write a new file
- Simple keyword tagging
- Teaser section. Only a user defined snippet is shown on the front page so the front page is not cluttered
- javascript free, fully static html per post for easy bookmarking and printing
What I want to add/change
Markdown tables
a table markup is very usful for blogging. For example:
-------------------------------------------------------------
Centered Default Right Left
Header Aligned Aligned Aligned
----------- ------- --------------- -------------------------
First row 12.0 Example of a row that
spans multiple lines.
Second row 5.0 Here's another one. Note
the blank line between
rows.
-------------------------------------------------------------
Table: Here's the caption. It, too, may span
multiple lines.
Which can be rendered as:
Centered Header | Default Aligned | Right Aligned | Left Aligned |
---|---|---|---|
First | row | 12.0 | Example of a row that spans multiple lines. |
Second | row | 5.0 | Here's another one. Note the blank line between rows. |
Syntax highlighted code sections
How about:
~~~ perl
while(my $post = readdir $dh) {
next unless (-f "$folder/$post");
next unless (substr($post, -3) eq '.md');
my $metas = get_meta("$folder/$post");
push @post_meta, $metas;
}
~~~
Which can be rendered as:
while(my $post = readdir $dh) {
next unless (-f "$folder/$post");
next unless (substr($post, -3) eq '.md');
my $metas = get_meta("$folder/$post");
push @post_meta, $metas;
}
One frontpage
One frontpage to rule them all, One frontpage to find them, One frontpage to bring them all and in the javascript bind them.
The frontpage should load asynchronisely and on demand, and provide user interaction capabilities such as filtering based on tags, etc.
The building blocks
Pandoc
Pandoc is a great tool for converting marked up texts. It supports an enriched markdown syntax and many options to generate htmls. And it is very fast. Here I use it to convert markdown to html snippet for further processing. Actually, all the heavy lifting is done in pandoc.
Perl
I use perl to write a couple of scripts to generate the JSON index and postprocess the pandoc generated html into final versions. The generation of the full htmls use the excellent Template toolkit framework.
Make
I use make to coordinate all backend build process:
- index generation
- per-post html and teaser generation
- file distribution
It can even build in parallel.
Bootstrap
Bootstrap provides nice styles already. My customized style sheet is fairly short.
Jquery
With Jquery I wrote a short javascript (~100 LOC) to load the JSON index and the teaser snippets with AJAX. Teasers are loaded and rendered in the background with tag based filtering.
Summary
The old saying is don't reinvent the wheel, but that is what I am doing here. There are many wonderful tools that I use so all I did is piecing them together with small amount of glue code. The end result is something tailored to my needs; and you are welcome to take it or build something for your need. It is not hard, really.