Asciidoctor: Asciidoc to Markdown conversion (graceful downgrade)

Created on 1 Nov 2016  路  4Comments  路  Source: asciidoctor/asciidoctor

Flat-file CMSs (such as Grav, Pico, ...) and some text editors (such as Scriveners) use Markdown. It is not possible to push all of them to support Asciidoc but there might be some interim advantages if Asciidoc to Markdown becomes possible.

Most helpful comment

It's very unlikely a Markdown converter will become part of core, which I'll explain below. But I think you already have a strong path to get there by converting AsciiDoc to DocBook using Asciidoctor, then DocBook to Markdown using pandoc. While I'm not a fan of how pandoc makes AsciiDoc, I do think it handles Markdown (and all its nauances and flavors) very well. I don't see this as far from perfect, unless you think how pandoc makes Markdown is far from perfect. The DocBook captures all the semantic information from the AsciiDoc document.

Here's the command I've used to down-convert to Markdown (which does so in a single step):

asciidoctor -b docbook -a leveloffset=+1 -o - README.adoc | \
pandoc  --atx-headers --wrap=preserve -t markdown_strict -f docbook - > README.md

(You can also choose other markdown flavors such as markdown_github).

NOTE: The leveloffset is necessary to prevent pandoc from eating the document title and shifting all headings up one level).

The reason I don't see a Markdown converter being part of core is because there isn't just one Markdown. So it would mean having to create lots of different converters to make it generally useful, which would take resources and focus away from the project. But that doesn't mean such a converter cannot exist. I'd certainly support the effort if someone wanted to create a Markdown converter for Asciidoctor as a separate project.

All 4 comments

I occasionally need to convert asciidoc to markdown (see for example: https://stackoverflow.com/questions/47324785/how-can-i-add-a-table-with-multi-row-cells-to-a-readme-in-vsts)

Markdown is more popular than asciidoc for short pieces of writing. For example, these github comment or stackoverflow.

Currently the easiest mechanism is first converting to docbook and then using pandoc (see https://tinyapps.org/blog/nix/201701240700_convert_asciidoc_to_markdown.html) but its far from perfect. A markdown backend would eliminate the middle man.

It's very unlikely a Markdown converter will become part of core, which I'll explain below. But I think you already have a strong path to get there by converting AsciiDoc to DocBook using Asciidoctor, then DocBook to Markdown using pandoc. While I'm not a fan of how pandoc makes AsciiDoc, I do think it handles Markdown (and all its nauances and flavors) very well. I don't see this as far from perfect, unless you think how pandoc makes Markdown is far from perfect. The DocBook captures all the semantic information from the AsciiDoc document.

Here's the command I've used to down-convert to Markdown (which does so in a single step):

asciidoctor -b docbook -a leveloffset=+1 -o - README.adoc | \
pandoc  --atx-headers --wrap=preserve -t markdown_strict -f docbook - > README.md

(You can also choose other markdown flavors such as markdown_github).

NOTE: The leveloffset is necessary to prevent pandoc from eating the document title and shifting all headings up one level).

The reason I don't see a Markdown converter being part of core is because there isn't just one Markdown. So it would mean having to create lots of different converters to make it generally useful, which would take resources and focus away from the project. But that doesn't mean such a converter cannot exist. I'd certainly support the effort if someone wanted to create a Markdown converter for Asciidoctor as a separate project.

@mojavelinux thanks for this (oh, and all of asciidoctor, BTW) - FYI I'm using asciidoc as a basis for https://github.com/scotws/TaliForth2/tree/master/docs, and using your script, and it is still eating the title when converting to markdown_github. This is not a biggie - I just add the string by hand at the moment, but I thought you should know.

For those using python-markdown (that supports admonitions) I extended this a little:

-- DANGER: DIRTY LUA AHEAD
function isAdmonition(el)
    classes = {'tip', 'note', 'important', 'caution', 'warning'}

    if el.tag ~= "Div" then
        return false
    end

    for i, class in pairs(classes) do
        if el.classes[1] == class then
            return true
        end
    end

    return false
end

function Admonition(div)
    string = pandoc.List({pandoc.RawInline("markdown", "!!! ".. div.classes[1]), pandoc.LineBreak()})

    for i, el in pairs(div.content[1].content) do
        -- IF it is the start, offset
        if i == 1 then
            string:extend {pandoc.Space(), pandoc.Space(), pandoc.Space(), pandoc.Space()}
        end

        -- Add the token
        string:extend{el}

        -- If the token inserted was a line break, it needs another offset
        if el == pandoc.SoftBreak() then
            string:extend {pandoc.Space(), pandoc.Space(), pandoc.Space(), pandoc.Space()}
        end
    end

    return pandoc.Para(string)
end

function Pandoc(doc)
    local hblocks = {}

    for i,el in pairs(doc.blocks) do
        if isAdmonition(el) then
            table.insert(hblocks, Admonition(el))
        else
            table.insert(hblocks, el)
        end
    end

    return pandoc.Pandoc(hblocks, doc.meta)
end

Which made it something like:

asciidoctor -b docbook \
    --attribute leveloffset=+1 \
    --out-file - \
    file.adoc | \
pandoc \
    --wrap=preserve \
    --lua-filter ./path/to/markdown-admonition.lua \
    -t gfm \
    -f docbook \
    - > output.adoc md;

YMMV, but it was Friday so I felt like yak shaving.

Was this page helpful?
0 / 5 - 0 ratings