In this walkthrough tutorial, you'll learn how to convert OpenAPI 3.0 definitions to MarkDown with Widdershins CLI.
The reasons to parse an OpenAPI document and convert it to MarkDown could be diverse. In my case, I wanted to render beautiful documentation that is fully integrated with Sphinx, my favorite static site generator for documentation projects.
So if you have already written an OpenAPI document and you would like to get an idea of how you can turn it into MarkDown, this article might be of interest to you.
Prerequisites
- Have a valid OpenAPI document.
- Have NodeJS installed on your computer.
- Have basic command-line knowledge.
What's Widdershins?
Widdershins is the open-source command-line tool we'll use to convert the OpenAPI document to MarkDown. By default, Widdershins outputs MarkDown compatible with renderers such as Slate, ReSlate, and Shins.
Thanks to its customizable template system, we can customize the output to make it compatible with other static site generators such as Jekyll, Docusaurus, or Sphinx.
Installing Widdershins
Widdershins can be installed with NPM. In the command prompt, run the following command npm install -g widdershins
.
After the installation has been completed, you can verify Widdershins installation by running widdershins --version
in the command prompt.
Parsing OpenAPI to MarkDown
Once Widdershins is installed, run the following command in the console prompt. Replace openapi.yaml
with the path to your OpenAPI file in YAML or JSON.
widdershins openapi.yaml -o openapi.md
The command stores the resulting MarkDown file as openapi.md
.
Customizing the output with flags
Widdershins comes with other built-in options to configure the output. For example, the option omitHeader
removes the YAML front-matter in the generated Markdown file.
👉 Check out the complete list of available options in the official docs.
In this example, I'm running the command from the previous step with the new option omitHeader
:
widdershins openapi.yaml -o openapi.md --omitHeader
Using custom-defined templates
Suppose you want to change the output's format, but you can't achieve the level of customization you are looking for by just tweaking Widdershins CLI's options. In this case, what I do is override the template Widdershins uses with a custom-defined template. Here's how:
- Create a new directory named
.widdershins
. Inside, create a second folder namedtemplates
.
mkdir -p .widdershins/templates
cd .widdershins/templates
- Copy the contents from the file main.dot in the folder you just created.
curl https://raw.githubusercontent.com/Mermade/widdershins/master/templates/openapi3/main.dot > main.dot
- Edit
main.dot
with your favorite code editor. The template engine Widdershins uses is doT.js. This enables you to access any variable from the OpenAPI description, even vendor extensions or nested fields.
From my experience, getting started with the template engine could be tricky. Here's a cheatsheet with the delimiters I've been using more to render and iterate through variables:
Evaluate
{{ var enums = []; }} // Executes the JavaScript code between the curly braces.
{{=a}} // Renders the contents of the variable a
{{=a.b}} // Renders the contents of the nested variable a.b
Conditional
{{? a }} hello {{?}} // If a is true, prints "hello".
{{? !a }} hello {{?}} // If a is false, prints "hello".
{{? a || b }} hello {{?}} // If a or b is true, prints "hello".
{{? a && b }} hello {{?}} // If a and b is true, prints "hello".
Iteration
{{~ alist:a}} {{= a }} {{~}} // Iterates throught alist and prints every element.
- Run the Widdershins CLI. In this case, add the option
-u
with the path to.widdershins/templates
:
widdershins openapi.yaml -o openapi.md -u ./widdershins/templates
Conclusion
I hope this was a helpful introduction to transform your OpenAPI to MarkDown.
Next, you could code a script to automatically generate MarkDown docs every time the original OpenAPI file receives an update. In my case, I'm also postprocessing the MarkDown file and dividing it into multiple files to have smoother navigation between the contents.
Please let me know if you succeed at @dgarcia360 and share the article if it helped you out!