Markdown rendering in ArgParse.jl

Julia lets you include some Markdown syntax in docstrings, and renders it with nice colors in the terminal, e.g. in interactive help:

Is it possible to achieve the same with ArgParse.jl?

If you type Markdown into the help text, it just renders as plain text (try julia main.jl --help with the file below).

`main.jl`
using ArgParse
using Markdown

function parse_commandline()
    s = ArgParseSettings()

    @add_arg_table! s begin
        "--opt1"
            help = "an option with an argument `and some markdown`"
        "--opt2", "-o"
            help = "another option with an argument"
            arg_type = Int
            default = 0
        "--flag1"
            help = "an option without argument, i.e. a flag"
            action = :store_true
        "arg1"
            help = "a positional argument"
            required = true
    end

    return parse_args(s)
end

function main()
    parsed_args = parse_commandline()
    println("Parsed args:")
    for (arg,val) in parsed_args
        println("  $arg  =>  $val")
    end
end

main()

And if you change the help strings to a md"markdown string" (after using Markdown) you get:

> julia main.jl --help
ERROR: LoadError: ArgParseSettingsError("help must be an AbstractString")

I looked into it, and it seems that patching the source is required. An example PR is: support markdown in help strings by stevengj · Pull Request #134 · carlobaldassi/ArgParse.jl · GitHub

1 Like

Partial solution

Studying Steven’s patch, it is possible to render many Markdown strings in ArgParse.jl without patching the source if you use repr() to convert the Markdown to text with ANSI escape codes. Here is a minimal example:

# demo.jl

using ArgParse
using Markdown

function to_ansi(markdown::Markdown.MD)
    ansi_escaped = repr("text/plain", markdown; context=:color => true)
    # Remove 2-space indent inserted by repr
    Base.unindent(ansi_escaped, 2)
end

function main(args)
    s = ArgParseSettings(
        description=to_ansi(md"""
        Example of using **Markdown** syntax within `Argparse.jl`.

        Multiple paragraphs parse correctly as long as you set `preformatted_description` to `true`.
        """) * '\n',
        preformatted_description=true
    )

    @add_arg_table! s begin
        "arg1"
        begin
            help = to_ansi(md"You can also use Markdown in the `help` text")
        end
    end

    parse_args(s)
end

main(ARGS)

Then julia ./demo.jl --help gets you:

image

However, this will fail or produce weird indentation in certain edge cases, such as when the Markdown includes subheadings or when you combine it with options like help_width. See the pull request linked above for more discussion.