logo一言堂

Blogging with pandoc, perl and javascript

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:

Here's the caption. It, too, may span multiple lines.
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.