Doktor: extract docs from external files

Sometimes we have more markdown than Elixir in our elixir files. I thought it would be fun to have a tool that could extract the docs from specially prepared markdown files. I’ve came up with Doktor.

First, you write your docs, say, in dok/

<!-- @moduledoc Dummy -->
A dummy module for testing purposes.

<!-- @doc hey/1 -->
Says "hey" to a person.

<!-- @doc hey/2 -->
Says "hey" to a pair of persons.

Then, you use Doktor on your module:

defmodule Dummy do
  use Doktor, file: "doks/"

  @moduledok "Dummy"

  @dok "hey/1"
  def hey(name) do
    "Hey #{name}!"

  @dok "hey/2"
  def hey(name1, name2) do
    "Hey #{name1} & #{name2}"

You can now do this:

iex(26)> h Dummy
* Dummy

A dummy module for testing purposes.

iex(27)> h Dummy.hey
* def hey(name)

Says "hey" to a person.

* def hey(name1, name2)

Says "hey" to a pair of persons.

It works by overwriting the @ macro so that it treats the dok, typedok and moduledok calls in a different way. Fortunately this is the only “magic” I need. At compile time, the use Doktor, file: filename parses the sections from the filename and stores it in an agent, which is disposed of when the module is compiled. While the module is compiled, @dok and friends retrieve the function/module/etc. from the agent and add it to the AST of the module. It’s quite simple.

The beauty of that markdown file format is that it’s perfectly compatible with ordinary markdown, which means it highlights correctly and can be used to extract parts of markdown files. The format in the special comments is pretty self-explanatory. I don’t know if I’ll ever end up using this in practice, but it’s pretty cool.

This is restricted to one file per module for usability reasons, but it seems easy to generalize it so that it can retrieve docs from several files.

Link to github here:

This library hasn’t been published on Hex, and won’t be unless there is some demand for it :slight_smile: (we should avoid namespace pollution there)