Using Documenter.jl for non-Julia package documentation

I recently tried using Documenter.jl to add documentation to a Julia package and I really liked how it worked. I was thinking about using Documenter.jl to write documentation for non-Julia packages and was wondering if anyone had any advice as to whether:

  1. This is possible
  2. This is a good idea
  3. This is the right/wrong tool for this purpose (I also noticed Franklin.jl and Weave.jl may be alternatives)

For example, can I just add a docs folder to my repo with make.jl and Project.toml files and go from there as if the repo was a Julia package? Or must this be nested within a Julia package to work correctly?

As an example, I have a tool written in Makefiles that I’d like to write cleaner documentation for. I also have C++ projects currently using Doxygen, is there a way to tie that in or have Documenter.jl pick up on docstrings in C++ code somehow?

Suggestions for alternative tools for this purpose are definitely welcome, too. Now that my team is all working remotely we’re feeling more motivated to improve our documentation.

1 Like

I’m not sure how hackable Documenter.jl is for this kind of stuff; Franklin on the other hand (since you mentioned it) is as hackable as you want but it would require some effort. On the top of my head the key thing would be to write your own scraper (in Julia) to retrieve docstrings & function signatures from your codebase (that should not be too hard) and then you can just plug the results in a page.

Here’s a very simple POC, let’s say you have this in file.cpp

/**
 * Takes two integers and sums them
 */
int sum(int a, int b) {
   int c = a+b;
   return c;
}

/**
 * Takes two integers and subtracts them
 */
int sub(int a, int b) {
   int c = a-b;
   return c;
}

A poor man’s parser is to look for a /** at the start of a line then capture until */

function poor_parser(s)
    lines = split(s, '\n')
    docstrings = String[]
    open = false
    curds = ""
    for line in lines
        startswith(line, "/**") && (open = true)
        if open
            curds *= line * "\n"
            if endswith(line, "*/")
                push!(docstrings, strip(curds))
                curds = ""
                open = false
            end
        end
    end
    return docstrings
end

You can paste that function in a utils.jl file of a Franklin folder adding at the bottom

function hfun_docstring(args)
    r = ""
    for ds in poor_parser(read(args[1], String))
      r *= "<pre><code>$ds</code></pre>"
    end
    return r
end

You can then call that on a page with {{docstring path/file.cpp}}

Here’s what it looks like: https://tlienart.github.io/cppds/
Here’s the source: https://github.com/tlienart/cppds

Of course this might not be the shortest path to what you want :joy: . Also in practice you’d want to capture the line after the docstring, do some further processing etc etc which may be more effort than you’d like.

PS: I didn’t explain everything in details because this may be far from what you’re looking for; should you be interested, feel free to reach out on Slack or open a GitHub issue.

4 Likes

Wow! I hadn’t even thought about parsing my existing Doxygen tags as docstrings, but now that I see your example I see that it’s actually a pretty reasonable thing to try out. Thank you for the detailed response and examples, this is really cool and I’m looking forward to hopefully giving it a try soon.

1 Like