.Caption
image:https://picsum.photos/640/360[Alt, height=360]
Asciidoc vs Markdown
A few days ago browsing the internet I came across Asciidoc, a markup language similar to markdown, used primarily in the publishing industry. In fact it was created specifically to replace DocBook, a format used for techincal documentation and book publishing. Atlas, the tool used by O’Reilly, uses asciidoc as its main markup language. But despite its origins asciidoc can be used exaclty like markdown: it is supported by major static site generators like Hugo and Github and Gitlab support rendering asciidoc documents.
Interested, I decided to try to add asciidoc support to Kart, my static site generator. During the process I come across pleasent surprises from the power of the asciidoc language, but I also encountered a lot hiccups and head scratches. In the process I also found parts of Kart codebase which weren’t optimal, so I ended up improving them in order to add support for asciidoc. Cool!
Asciidoc advantages
Let’s cut straight to the point: Asciidoc out of the box is more powerful than Markdown. There a lot of things that in markdown are impossible to achieve without writing raw html (which is not optimal considering we are using a markup language not to use html!), that in Asciidoc are very simple.
-
Images: images are notoriously hard to use in markdown. Or rather, they are very easy to use if you don’t want to add a caption or, which is a more compelling case for me, resize the image. In this situation your only solution is to use html embedded in markdown. But with asciidoc you can simply write the following line to include an image, and you can modify every html parameter.
Figure 1. Caption -
Videos: after images, there are obviously videos. Videos are not embeddable in markdown (again, you can use raw html instead). People have found a workaround, but it nothing like being able to play a video directly in you website. However in asciidoc is as simple as
video::LXb3EKWsInQ[youtube, width=800, height=480]
Extendend Markdown syntax
If we were to consider only the basic markdown syntax, the previous list would be much much longer. There are a lot of things that are not covered by the basic syntax, like code blocks and tables, which are available in asciidoc. However people in the markdown community have noticed that, and have created a list of extensions to the markdown language, the markdown extended syntax. However there is no guarantee that your markdown parser supports it, as it is not part of any well defined specs. Some parts of this extended syntax are well supported (like tables and code blocks with are almost universal), others are not. And even if they are supported, some tools interpret the same thing in a slightly different way. This contributes to an overall lack of consistency of the markdown syntax, which is often very frustrating, as it seems that you are dealing with a different language everytime you look in a different tool. For example:
-
Custom attributes: sometimes you may want to add a custom css attribute to a specific part of your text. For example in this exact page I needed to add a class attribute to this unordered list. Fortunately in asciidoc this is simple, just add a line above the object you want to add an attrubute to like this:
[.custom-list-class] * List item 1 * List item 2
If I were to implement this is markdown, it would have been an entirely different experience. Right now there is a proposal to add this feature to the commonmark spec, but nothing is certain at this moment. There are a few tools that support this feature but, which is really the worst thing, they use a diffent syntax. Arghhhh! (as an example python-markdown, a popular python markdown parser, follows an older proposal)
-
Admonitions: I am putting here admonitions, even if they are not part anywhere of the markdown syntax, because they are supported by most of documentation tools.
And here is a small list of other things which are not supported in famous tools:
-
Description lists: not supported in docusaurus, Github and Gitlab
-
Task lists: not supported in docusaurus and python-markdown
-
Superscript and subscript: not supported by almost everything
Asciidoc disadvantages
There are a few things I don’t like about the asciidoc syntax. In markdown they are included in the extended syntax, not the base one, but still I think that markdown here has done a better job (and I don’t know if it’s a coincidence or not, these are the most common extensions across all markdown renderers):
-
Tables: this is really funny for me, as it is originally one of the main selling points of asciidoc. I understand that the syntax of markdown table is really verbose (to solve this there are even tools that automate this), but after that it seems to me more readable that asciidoc:
[cols="1,1"] |=== |Cell in column 1, header row |Cell in column 2, header row |Cell in column 1, row 2, a |Cell in column 2, row 2, b |Cell in column 1, row 3, c |Cell in column 2, row 3, d |===
Cell in column 1, header row Cell in column 2, header row Cell in column 1, row 2, a
Cell in column 2, row 2, b
Cell in column 1, row 3, c
Cell in column 2, row 3, d
Probably it is because of the fact that columns and row are not aligned as they should be, but I found this syntax rader ugly and very UNreadable.
-
Strikethrough: even though asciidoc is really powerful, it really has a horrible handling of strikethrough text. In markdown you simply put a text between double tildes, but in asciidoc you have to write
[.strikethrough]#text#
which is orrible, and secondly it doesn’t output a native html <del> or <s> block, which is styled automatically, but the output is a <span> with a custom attribute. This really I do not understand.
-
Footnotes: footnotes are a mixt bag. With asciidoc you write the footnote inline, so if you want to add a very quick footnote I think asciidoc is quite appealing; however if you want to write something longer you can’t do that in asciidoc, unless you use some workarounds like externalizing a footnote, which is something quite complicated
Markdown:
Here's a simple footnote,[^1] and here's a longer one.[^bignote] [^1]: This is the first footnote. [^bignote]: Here's one with multiple paragraphs. Indent paragraphs to include them in the footnote.
Asciidoc:
Here's a simple footnote footnote:[This is the first footnote], and a larger one is not possible
A part of these small things, I really haven’t really anyting against asciidoc as a language. However we haven’t talked about the elephant in the room. Right now there is a lack of tools for asciidoc. There is only one supported and really up-to-date parser and renderer, asciidoctor. The development of the language is completely done by them, and I start to fear that the only reason why the asciidoc language is more consistent is not because of design but because there is only one tool, and thus there is no incompatibility.
Moreover asciidoctor is written in ruby, which is an interpreted language, so it’s not so fast and, maybe most importantly, can’t be embedded in other programs. So if you want to support the asciidoc language you have to call asciidoctor externally. This is generally not a good idea. First of all as the performance is not good (I saw somewhere an blog post of a person trying to move his hugo blog from markdown to asciidoc, and saw an order of magnitued decrease in performance!). Secondly, you have very little control over the generated content. When I tried to integrate asciidoc into my static site generator I wanted to control programmatically how links were generated. However I really couldn’t to id as I didn’t have control over an interal ast representation, so I could only work with the final html, which is definetely more complicated. This is the major reason why major tools, like hugo, have only partial support for asciidoc.
Specification vs Tooling
As we have seen in the previous section, the major drawback of asciidoc is not really the language, but the lack of tooling around it. However this is not specific to this topic, but a more general rule. Almost every day something its released in the tech industry that promises to be much better that what is available, and even with all of its promises no one starts using it. It’s because even though this new project is better, the slight advantage of using it is completely outweigh by the hassle of changing everything else in order to support it. Think about Rust, a language I am learning which many people believe is next big things in compiled languages. It is in the same realm of C and many thing it is a superior language, however in many situations, for example game development, there is very little Rust. That's because even though there is a very passionate community that is building games tools with Rust, it has to compete with many decades of game development which have built a pletora of framework and tools for C. This is a reason why language that are 10 years old are considered still very young.
This story really reminds me of a very famous meme about computer standards. This doesn’t really apply to Asciidoc, as it was developed even before Markdown! (Markdown was first developed in 2004, Asciidoc in 2002). But still the idea remains that creating a supposedly better specification doesn’t always improve things, sometimes it is better to simply improve the tools around what already exists.
Conclusion
This was a fun experience. I learned a lot about asciidoc, and in the trying to add support for it in my static site generator I ended up improving other parts of the codebase. Asciidoc is certainly a pretty cool markup language, however I am not sure if I am going to start using it in my website for every page. But I will surely continue playing with it a little more in the following months!