Sphinx documentation on GitHub
Quickly publish documentation alongside your code by following this easy recipe
The Data Desk often publishes documentation alongside its code on GitHub, a social networking site where developers share their work. GitHub’s main service — free for open-source projects — is for managing source code, but it also provides ticket tracking, wikis and a simple file-hosting service for publishing HTML pages.
It’s that last trick that’s great for documentation. The service is called GitHub Pages and it’s tailored to host sites generated by Jekyll, a framework for creating static sites with the Ruby programming language. But, if you make the right moves, you can get it to publish just about any HTML. Not only is it live online, but every change you make will be saved in the same version-control system as the code.
But what to put up there? You could handcraft your documentation, writing out every HTML tag in loving longhand. Or you could be lazy like the Data Desk and use software that does the hard work for you.
The Data Desk uses Sphinx, a framework for writing and organizing documentation written in the Python programming language. You provide the text and it provides a complete base template and automatically generates a table of contents, navigation bar and links between different pages. It even indexes your site and sets up a simple JavaScript-based search.
The text is expected in reStructuredText markup and the base template can be themed to look however you like. The Data Desk’s style is based on the design of The Times’ Sunday newspaper and can be seen here, here, here, here and here. You can also see Sphinx in use on documentation for Python’s core, pip, Django and Flask.
It’s a bit of trick to get Sphinx to play nice with GitHub Pages, but it can be done. Here’s how.
Step by step
GitHub is powered by Git, the version control system developed for managing the Linux source code. Most everything you do on Github is centered on Git-managed code repositories.
So that’s where we start. If you don’t have a GitHub account already, set one up. Then create a new code repository and follow the instructions to get it set up on your computer.
To start, your code is going to go in the “master” branch created when Git first initializes your repository. Normally, you create other branches when you want to fork away and make changes independent of what’s in the master branch.
With GitHub Pages, anything you commit to a branch titled gh-pages
will instead be published at http://your_username.github.com/your_repository_name/. So the first step to publishing anything is to create that branch.
$ git branch gh-pages
Now jump into the new branch.
$ git checkout gh-pages
Before we can start work, we need to clear out anything from the master branch and start fresh. To make that happen, you have to run a few obscure Git commands. Here they are.
$ git symbolic-ref HEAD refs/heads/gh-pages $ rm .git/index $ git clean -fdx
Once that’s over, install Sphinx from the PyPI package repository using pip
.
$ pip install sphinx
Once Sphinx is installed, instruct it to create a new documentation set.
$ sphinx-quickstart
After you issue the command, Sphinx will ask you a series of questions that configure your project. You can give the default answer in every case except one. The second question it will ask is:
Separate source and build directories (y/N) [n]:
You must answer yes. That means you should type Y
and then press enter
on your keyboard.
Next you have to modify Sphinx’s Makefile
so it will build your site in the root directory. Open up the Makefile
and change the eighth line to:
BUILDDIR = ./
Then go down to the 39th line and change the html
command to look like this:
html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR) @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
To verify it works, instruct Sphinx to build your site for the first time. You will need to issue this command every time you wish to update the files on your local system.
$ make html
Finally, you need to create an empty file in the root directory that lets GitHub know you aren’t using Jekyll to structure your site.
$ touch .nojekyll
Now all that’s left is to commit your HTML and push it up to GitHub.
$ git add . $ git commit -am "First commit" $ git push origin gh-pages
Wait a few minutes and visit http://your_username.github.com/your_repository_name/. There you should find a simple Sphinx site live on the Web. To update it, edit the files in the source directory, run make html
again and push to GitHub.
Tying it together
The routine above will work, but it is tiresome to run through it each time you start a new repository. You can automate the process by chaining all of the commands together and executing them as a batch. The Data Desk does this using Fabric, a tool for streamlining Python tasks. It was designed for deploying code to remote machines, but it’s just as useful for running commands on your local computer.
If you don’t have Fabric installed already, retrieve it from PyPI.
$ pip install fabric
Once it’s ready, create a new file called fabfile.py
at the root of your master branch and paste in the following code.
from fabric.api import * from fabric.contrib.console import confirm def create_sphinx_pages(): """ Create a new branch with Sphinx documentation ready to be published using GitHub's Pages system. Example usage: $ fab make_sphinx_branch Before you can publish your docs, you need to commit them to the repo. $ git add . $ git commit -am "First commit" Then publish the files by pushing them up to GitHub. $ git push origin gh-pages Then the docs will appear on GitHub at: http://<your_account_name>.github.com/<your_repo_name>/ """ # Create the new branch local("git branch gh-pages") # Move into it local("git checkout gh-pages") # Clear it out local("git symbolic-ref HEAD refs/heads/gh-pages") local("rm .git/index") local("git clean -fdx") # Install sphinx local("pip install sphinx") # Save the dependencies to the requirements file local("pip freeze > requirements.txt") # Warn the user of a quirk before configuring with Sphinx confirm(""". ___ ___ _ ___ ___ _ /\ | | |_ |\ | | | / \ |\ | /--\ | | |_ | \| | _|_ \_/ | \| Sphinx is about to start configuring your project. You can accept the default settings it offers, EXCEPT ONE. The second question it will ask is: 'Separate source and build directories (y/N) [n]:' YOU MUST ANSWER YES. THAT MEANS YOU TYPE 'Y' AND PRESS ENTER. DO YOU UNDERSTAND?""") # Start up a Sphinx project local("sphinx-quickstart") # Create the .nojekyll file GitHub requires local("touch .nojekyll") # Make the patches to Sphinx's Makefile we need local("echo '' >> Makefile") local("echo 'BUILDDIR = ./' >> Makefile") local("echo '' >> Makefile") local("echo 'html:' >> Makefile") local("echo '\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)' >> Makefile") local("echo '\t@echo' >> Makefile") local("echo '\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)\"' >> Makefile") # Make the branch for the first time local("make html")
Fabric does exactly the same thing we walked through above, but it does it with one simple command.
$ fab create_sphinx_pages
And all that’s left is the honor of publishing it for the first time.
$ git add . $ git commit -am "First commit" $ git push origin gh-pages
Much respect due
This post pulls together ideas worked out elsewhere by Luca Sbardella, Damien Lebrun, Michael Jones and Tom Preston-Werner, who all deserve our thanks.