New year, new petprojects. One of them is moving existing documentation in an easier to manage, easier to use format. I looked around what is being used right now internally, and seen many tools from doxygen to sandcastle. One of the tools that caught my attention was sphinx. Being a Python tool, it enables to run on both on Windows and Linux, and looking little more around I found support for VSCode editing – I'm in.
So, what is sphinx? Sphinx is a tool that makes it easy to create intelligent and beautiful documentation, written by Georg Brandl and licensed under the BSD license. It was originally created for the Python documentation, and it has excellent facilities for the documentation of software projects in a range of languages.
So I gave it a try and I ended up setting up something similar to github pages – I send a PR to a particular internal repo, and when it gets merged, it kicks off a build which automatically uploads it as the new content.
Locally I did set up the following in my tasks.json:
{
"version": "0.1.0",
"command": "python",
"isShellCommand": true,
"args": [ "sphinx-build", "-b", "html", "-d", "build/doctrees", ".\\src\\sphinx\\source", ".\\doc"],
"showOutput": "always"
}
Next thing was to set up my conf.py, I picked a few plugins I was thinking I'd use:
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
# 'sphinx.ext.autosectionlabel', — this depends on a newer sphinx that I have
# http://www.sphinx-doc.org/en/1.5.1/ext/autosectionlabel.html
'sphinx.ext.autosummary',
# http://www.sphinx-doc.org/en/1.5.1/ext/autosummary.html
'sphinx.ext.todo'
# http://www.sphinx-doc.org/en/1.5.1/ext/todo.html
]
I started playing than around with the RST syntax, and very quickly figured out that there is good support for python (not a surprise) in code coloring, but even if I did set .. code:: csharp it wasn't recognizing it.
So time to write my first sphinx plugin, in _ext/csharplexer.py:
def setup(app):
import pygments
from pygments.lexers import CSharpLexer
app.add_lexer('csharp', CSharpLexer())
than I can add 'csharplexer' as an extension.
Next, I started looking making the rendering little nicer – I'll likely have longer listings as part of the code, and I wanted to have a syntax for toggles working. So time for the next extension – toggle. Taking the following source:
.. container:: toggle
.. container:: header
**Example to show how to add unitycontainer**
.. code-block:: csharp
:linenos:
Assert(true); // OK
var i = 1;
Console.WriteLine("Hello World!");
I could just add _static/custom.css:
.toggle .header {
display: block;
clear: both;
cursor: pointer;
}
.toggle .header:after {
content: " ▼";
}
.toggle .header.open:after {
content: " ▲";
}
and _templates/page.html:
{% extends "!page.html" %}
{% set css_files = css_files + ["_static/custom.css"] %}
{% block footer %}
<script type="text/javascript">
$(document).ready(function() {
$(".toggle > *").hide();
$(".toggle .header").show();
$(".toggle .header").click(function() {
$(this).parent().children().not(".header").toggle(400);
$(this).parent().children(".header").toggleClass("open");
})
});
</script>
{% endblock %}
Which resulted in something I liked 🙂
Will be continued – next time I'll try to get viewcode working.