Markdown to PDF Converter

Few weeks ago, I published SLogLib (a cross-platform logging library) on GitHub. I wrote the user manual in a file as is the standard practice at GitHub. However, since most of users don’t have markdown viewers installed on their machines they would either need to access GitHub repository or would have to convert it to more popular format such as PDF or perhaps HTML. For many users going online is becoming standard practice to access documentation but I prefer offline manuals. Thus, I wanted to ship a PDF manual along with the code.

I searched high and low for a standalone tool to convert markdown to PDF but surprisingly there are not a lot of options out there. The first tool I came across was GitPrint. It is conceptually innovative and straightforward to use with GitHub. Just add /your_user_name/repository_name at the end of and it prints the in the repository to PDF. The PDF generated is of good quality but there are no styling options. Also, it failed to include images in the PDF so I had to kept looking. One of the frequently recommended tool is PanDoc, which is a swiss-army knife to convert files from one markup format into another. However, in my experience it doesn’t do a good job of converting markdown to PDF. Another popular tool online is a markdown-pdf package for Node.js. Since, I have no prior experience with Node.js I haven’t tried it yet.

Earlier this year, I bought a MacBook Pro and installed a markdown editor called MacDown. It is really nice tool with side-by-side rendering of markup and HTML. It can export markdown as PDF and produces very good quality PDF’s. It also supports lots of styling options as well as a CSS to customize PDF generation. In the end, I used it to generate PDF for SLogLib.

Even though I had a PDF for SLogLib, I wanted to find/build a cross-platform tool to convert markdown to PDF.

The basic idea to convert markdown to PDF is simple. First convert markdown to HTML and then print HTML to PDF. I used hoedown to convert markdown to PDF because of several reasons:

  1. First and foremost it is cross-platform and compiles as a standalone binary for all three main platforms: Windows, Linux, and OSX.
  2. MacDown uses it too and I was quite happy with its rendering.
  3. It supports not only standard markdown but also several non-standard extensions.

To converted HTML to PDF one of the most popular tool I came across was wkhtmltopdf. It is also cross-platform and complies into standalone binaries for all popular platforms. In fact, it is possible to download the pre-built library right from its website. Wkhtmltopdf uses a modified version of webkit shipped with Qt. It uses webkit to render the html and print to PDF. However, while testing I found that on a Windows 7 machines there is a serious problem with font kerning. It has been reported by a lot of users but I haven’t found a solution to fix it. Wkhtmltopdf would have been ideal as I could simply write a command line and/or GUI tool wrapping the functionality of hoedown and Wkhtmltopdf.

Screenshot of markdown to PDF generated from MacDown

Screenshot of PDF generated from MacDown.

Screenshot of markdown to PDF generated wkhtmltopdf

Screenshot of PDF generated from wkhtmltopdf.

I could not find any other standalone cross-platform tool to convert HTML to PDF. So, for now I decided to use dompdf which is written in PHP. Once I started used PHP I thought why not make it a web based tool. This would allow me to learn about SEO which I have been promising myself to learn one day :). The tools is hosted at At the moment it doesn’t appear in first five pages in Google search for “markdown to pdf” or “markdown 2 pdf”. I am playing with various SEO tools and techniques and hope to get it within first five pages.

My quest for a standalone tool is not yet complete. I will try to find a solution for wkhtmltopdf kerning issue or find another standalone cross-platform tool for converting from HTML to PDF. I will update with my findings on this blog.

Onion Cells under Microscope

In this post, I will show how to make a wet mount slide for looking onion cells under a microscope.

Making the slide
  1. Take a clean slide and place a drop of water in the centre
  2. Take a small piece of onion and carefully peel the translucent membrane from the rough underside
    of the slide. To peel the membrane, you can either use a sharp blade or a pair of tweezers. It is important to do this step carefully so as to not break too many cells. So, ideally always hold the peeled membrane at the edges.
  3. Now carefully, place the membrane in the drop of water placed earlier on the slide.
  4. You may want to put a small drop of tincture iodine over the onion membrane. This is to help create contrast between cell nuclei and other parts of cells.
  5. Finally, gently lower a cover slip over the membrane.

Below are the micrographs of the onion cells. The nuclei are the small dark circles and the thick black lines are the cell walls.

Onion cells magnified 40 times
Onion cells magnified 40 times.
Onion cells magnified 100 times
Onion cells magnified 100 times.

Dog Cardiac Muscle l.s. Amscope 50PC Prepared Slides

Dog cardiac muscle longitudinal section (l.s.) is the 9th slide in the Amscope 50PC prepared slides. A cardiac muscle is found only in heart. These muscles are involuntary i.e. they contract and expand automatically to keep heart pumping. I am not 100% sure but most likely the cark blue dots in the micrographs are the nuclei.

Micrographs [19 July 2015]
Amscope 50PC Prepared Slides

This post lists all the micrographs I have done from the Amscope 50PC prepared slides.

Dense Connective Tissue section Amscope 50PC Prepared Slides

Dense connective tissue (section) is the 8th slide in the Amscope 50PC prepared slides. Dense connective tissue have densely packed fibers made up of mainly collagen (while lines in the micrograph below). The fibers in these tissues are regularly arranged and they are very strong but inelastic. Due to their in-elasticity, they can break if a strong force is applied across the fibers. Dense connective tissues forms the ligaments (connects muscles to bones) and tendons (connects bones to bones) in our body.

Micrographs [19 July 2015]
Amscope 50PC Prepared Slides

This post lists all the micrographs I have done from the Amscope 50PC prepared slides.

Dandelion Fuzz w.m. – Amscope 50PC Prepared Slides

Dandelion Fuzz whole mount (w.m.) is the 7th slide in the Amscope 50PC prepared slides. Dandelion is a yellow colored flower native to Eurasia and North America [Wikipedia]. What appears to be a single dandelion flower is actually made up of a large number of small flowers called florets! After removing the yellow petals from all florets, we are left with dandelion fuzz also known as seed head. The micrographs below show a single seed from the seed head.

Micrographs [19 July 2015]
Amscope 50PC Prepared Slides

This post lists all the micrographs I have done from the Amscope 50PC prepared slides.

A man gets an immense satisfaction from the knowledge of having done good work

You increase your self-respect when you feel you’ve done everything you ought to have done, and if there is nothing else to enjoy, there remains that chief of pleasures, the feeling of being pleased with oneself. A man gets an immense amount of satisfaction from the knowledge of having done good work and of having made the best use of his day, and when I am in this state I find that I thoroughly enjoy my rest and even the mildest forms of recreation.

Journal of Eugene Delacroix

Cross-platform high-resolution timer

Often there is a need to estimate the time it takes for a piece of code to run. This is useful not only for debugging but also for reporting the execution time of lengthy tasks to the user.

On Windows, QueryPerformanceFrequency() and QueryPerformanceCounter() can be used to determine the execution time of a code. QueryPerformanceFrequency() returns the frequency of the current performance counter in counts per second and QueryPerformanceCounter() returns a high resolution (<1µs) time stamp. Together they can be used to determine time it takes to run a piece of code is:

LARGE_INTEGER _frequency;


// Code which takes a long time to run.


double _intervalInSeconds = (_stop.QuadPart - _start.QuadPart) / _frequency.QuadPart;

On Linux, clock_gettime can be used to get a time interval with a resolution of nano-seconds. clock_gettime() requires two arguments: clockid_t and timespec structure. To build a timer, CLOCK_MONOTONIC is a good choice for clockid_t as the time is guaranteed to be monotonically increasing. timespec structure have two field: tv_sec (time in seconds) and tv_nsec (time in nanoseconds). Code to determine the time it takes to run a piece of code is:

struct timespec _start;
clock_gettime(CLOCK_MONOTONIC, &_start);

// Code which takes long time to run.

struct timespec _stop;
clock_gettime(CLOCK_MONOTONIC, &_stop);

double _intervalInseconds = (_stop.tv_sec + _stop.tv_nsec*1e-9) - (_start.tv_sec + _start.tv_nsec*1e-9);

I have written a simple class which can be user on both windows and Linux. It has the following interface:

class Timer

    enum TimeUnit
        TimeInSeconds = 1,
        TimeInMilliSeconds = 1000,
        TimeInMicroSeconds = 1000000



    // On Windows, returns true if high performance timer is available.
    // On Linux, always returns true.
    bool IsTimerAvailable();

    // Start the timer.
    void Start();

    // Stop the timer and return the time elapsed since the timer was started.
    double Stop(TimeUnit timeUnit = TimeInMilliSeconds);

    // Get the time elapsed since Start() was called.
    double TimeElapsedSinceStart(TimeUnit timeUnit = TimeInMilliSeconds);

    // Get the total time elapsed between Start() and Stop().
    double TotalTimeElasped(TimeUnit timeUnit = TimeInMilliSeconds);

You can download the code from the following links:

Cucurbita Stem l.s. – Amscope 50PC Prepared Slides

Cucurbita stem lateral section (l.s.) is the 6th slide in the Amscope 50PC prepared slides. Cucurbita (Latin for gourd) is popularly known as squash, pumpkin, or gourd depending on species, variety, and local parlance.

Micrographs [24 May 2015]
Amscope 50PC Prepared Slides

This post lists all the micrographs I have done from the Amscope 50PC prepared slides.

SLogLib: An easy to use, fully customizable and extensible, cross-platform logging library

A long time ago when I was doing PhD I was implementing a very complex geometric algorithm for computing intersection of two triangular meshes. There were bugs in code which would trigger only in certain edge cases. Since it was a GUI program using std::cout was not an option. Initially I tried writing messages to a file but soon realized it was too tedious as code was spanned across several files and I had to manually insert file names, function names, line numbers for every logging message.

A quick search on Internet revealed many logging libraries. I tried couple of them (unfortunately I can’t remember their names now) but none of them allowed customization of the output. The libraries I came across could output to variety of devices, supported multi-threading and many other fancy features but it was not possible to change the way messages was reported to the user. This was very important to me because I wanted to format my messages in a particular way so that I can easily check how my code was crashing on edge cases.

So, I wrote the first version of SLogLib sometime in 2005. It was build on a single principle that user should be in complete control of how messages are written to devices. In order to do that, SLogLib wraps all information required for logging into a structure called Message and passes it to a Formatter. The Formatter converts the Message structure to a std::string which will be outputted to the device. The Formatter must be written by the user. However, to make it easier to start using SLogLib and illustrate how to write a Formatter few Formatters are included with SLogLib.

Over past decade SLogLib has been very useful to me for a variety of projects and I hope that other can find it useful as well. SLogLib is hosted on Github under MIT license. You can clone of fork it from here:

Paramecium under Microscope in Pond Water

Paramecium in a sample of water taken from swan lake in Singapore Botanical Gardens.