Convert Markdown to AsciiDoc The Right Way! Use kramdoc

If you need to migrate Markdown content to AsciiDoc, there's a tool designed specifically to do it — it's called kramdoc. In this post, I'm going to show you how to use it and relate my experience with it.

Last week, I blogged about how to migrate from Markdown to more feature-rich formats, including AsciiDoc and reStructuredText, using Pandoc. Shortly after I tweeted about it, AsciiDoc project lead Dan Allen replied to my tweet:

I'd not heard of kramdoc up until he tweeted about it. Well, actually, the name did, if vaguely, ring a bell, but not very strongly.

I knew that Pandoc wasn't a perfect tool, but at that stage I was yet to see something better. Given that, I blogged about what I knew at the time. But, what are you to do when the Asciidoctor (and Antora) project lead says that he developed a tool for your specific use case?

Try it out of course! And so I did.

Naturally, after I try things out, and as you've come to expect, I'm likely to blog about the experience; whether good, bad, or indifferent.

What is kramdoc?

So, what is kramdoc? kramdoc is a kramdown extension for converting Markdown documents to AsciiDoc. The fuller description is:

Kramdown AsciiDoc (gem: kramdown-asciidoc, command: kramdoc) is a kramdown extension for converting Markdown documents to AsciiDoc. Notably, the converter generates modern AsciiDoc syntax suitable for use with Asciidoctor.

If you've not heard of kramdown before, here's how the project's home page describes it:

kramdown (sic, not Kramdown or KramDown, just kramdown) is a free MIT-licensed Ruby library for parsing and converting a superset of Markdown. It is completely written in Ruby, supports standard Markdown (with some minor modifications) and various extensions that have been made popular by the PHP Markdown Extra package and Maruku.

How to Install kramdoc

But before we dive right on in, let's make sure that you've got it installed, assuming you're going to follow along with me, that is. To do so — and you'll need to have Ruby installed — run the following command:

gem install kramdown-asciidoc

If all goes well, then you'll see output similar to the following:

Successfully installed kramdown-asciidoc-1.0.1
Parsing documentation for kramdown-asciidoc-1.0.1
Done installing documentation for kramdown-asciidoc after 0 seconds
1 gem installed

You'll likely have to restart your terminal emulator after it's installed, and you may have to add the gem bin directory to your path. But when you've done both, you'll have a new command in your path, called kramdoc.

Migrating Markdown to AsciiDoc

Now that we have it installed, we can use it. If you run kramdoc -h, you'll see the following output:

Usage: kramdoc [OPTION]... FILE...

Converts Markdown to AsciiDoc.

    -o, --output=FILE                Set the output filename or stream
        --format=GFM|kramdown|markdown
                                     Set the flavor of Markdown to parse (default: GFM)
    -a, --attribute=KEY[=VALUE]      Set an attribute in the AsciiDoc document header (accepts: key, key!, or key=value)
        --wrap=preserve|none|ventilate
                                     Set how lines are wrapped in the AsciiDoc document (default: preserve)
        --imagesdir=DIR              Set the imagesdir attribute in the AsciiDoc document header (also remove the value from the start of image paths)
        --heading-offset=NUMBER      Shift the heading level by the specified number
        --[no-]html-to-native        Set whether to passthrough HTML or convert it to AsciiDoc syntax where possible (default: true)
        --auto-ids                   Set whether to auto-generate IDs for all section titles
        --auto-id-prefix=STRING      Set the prefix to use for auto-generated section title IDs
        --auto-id-separator=CHAR     Set the separator char to use for auto-generated section title IDs
        --lazy-ids                   Set whether to drop IDs that match value of auto-generated ID
        --[no-]auto-links            Set whether to automatically convert bare URLs into links (default: true)
    -h, --help                       Display this help text and exit
    -v, --version                    Display version information and exit

In the output above, you can see that kramdoc provides options for customising how Markdown content is converted to AsciiDoc. These include:

  • Which Markdown format you are converting from
  • Whether to auto-generate ids for section titles
  • The ability to set document attributes
  • The value of the imagesdir attribute
  • The file to generate with the converted Markdown content

After scanning through them, and doing some experimenting, I found that I only needed three of them; these are:

  • format: While not essential, I used it as the Markdown I was migrating was based around being rendered on GitHub.
  • wrap: To know how to handle text wrapping (or not).
  • output: Because kramdoc will always need to know where to write the generated file.

wrap is essential for me because I'm a "true believer" in one-sentence-per-line, or as it's otherwise known: ventilated prose. If you're not familiar with the term, it means that each sentence goes on a separate line. Sentences aren't arbitrarily wrapped at a set number of characters, such as 72 in reStructuredText/Sphinx-Doc, nor are they split at the end of a sub-clause.

I strongly encourage you to read Dan's post on why ventilated prose is an excellent way to write!

Migrating a Single Markdown File to AsciiDoc

Given that I only need three options, here's an example of the command that I'd run to convert a Markdown file to AsciiDoc (formatted for readability):

kramdoc --format=GFM \
    --output=getting-started.adoc \
    --wrap=ventilate \
    getting-started.md

I've been migrating a number of files using kramdoc and have yet to encounter problems with it. Secondly, the quality of the AsciiDoc produced is excellent! There's no corruption. Titles, links, code blocks — everything — is migrated correctly.

Migrate Multiple Markdown Files to AsciiDoc

The previous example was fine for migrating one file. However, if you have a large Markdown content repository, you're not going to run the command once for each file; you're going to need to batch that migration.

Here's how to do so, using find:

find ./ -name "*.md" -type f -exec sh -c \
    'kramdoc --format=GFM --wrap=ventilate --output={}.adoc {}' \;

Alternatively, you could use a combination of find and xargs, as in the example below:

find ./ -name "*.md" -type f | xargs -I @@ \
    bash -c 'kramdoc --format=GFM --wrap=ventilate --output=@@.adoc @@';

There are other approaches, but these are the one that I defer to most often.

Conclusion

If you've decided that it's time to migrate to AsciiDoc — as it's a far more feature-rich file format for technical documentation than Markdown — and you're looking for a small, dedicated tool to migrate your content, look no further than kramdoc.

It's quick to install, quick to run, and produces excellent quality results. To find out more about it, check out the GitHub repository.

If you have found an issue with it, check to see if an issue's already been lodged. If not, create one and see it through to conclusion.

All that said, I’d love to hear what you think in the comments below. Have you been on the lookout for a way to migrate from Markdown? Are you sticking with Markdown? Please share your opinion below.

P.S. If you need assistance on any of your PHP projects, I am available for hire for freelance work.


Matthew Setter. Ethical Hacker, Online Privacy Advocate, and a Software Engineer.

Matthew Setter

Software Engineer, Ethical Hacker, & Online Privacy Advocate.

Matthew Setter is a software engineer, ethical hacker, privacy advocate, & technical writer, who loves travelling. He is based in Nuremberg, Germany. When he's not doing all things tech, he's spending time with his family, and friends.