bradley.ayers
bradley.ayers

Reputation: 38372

Automatically build Sphinx documentation when a source file changes

I'm using Sphinx to document one of my projects, and I like to preview my changes in my browser. I want to be able to save some changes to an .rst file, and be able to immediately refresh my browser and see the changes.

Essentially I want to automatically execute a make html whenever one of the .rst files is changed.

Upvotes: 22

Views: 8849

Answers (5)

varontron
varontron

Reputation: 1157

Rebuild a page and refresh a preview in VSCode

If using vscode, install Live Preview, with sphinx-build and restructuredText then, in a zsh terminal, from your doc root dir, in a single command you can:

  • rebuild (make html),
  • open a preview build/html/doc.html
  • re-open the document you were editing code -r source/doc.rst
make html && code -r build/html/doc.html && code -r source/doc.rst
  • make html will build the doc tree
  • code -r will reuse the current window in both cases

If each of doc.html, the live preview of doc.html, and doc.rst are all open already, sphinx will rebuild the tree and vscode will open the refreshed preview, and return you to editing doc.rst.

Take it one step further

and create a dynamic keybinding, which will do all of the above with a keyboard shortcut for any open .rst file. Add this to your keybindings.json:

   {
      "key": "cmd+shift+R",
      "command": "workbench.action.terminal.sendSequence",
      "args": {
        "text": "VSCODEOPENFILE=${file} && sphinx-build -M html ${VSCODEOPENFILE:h} ${${VSCODEOPENFILE:h}/source/build/} ${VSCODEOPENFILE} && code -r ${${VSCODEOPENFILE:h}/source/build/}${${VSCODEOPENFILE:t}/rst/html} && code -r ${VSCODEOPENFILE}\u000D"
      },
      "when": "textInputFocus && !editorReadonly"
    }
  • "key": "cmd+shift+R" is the keyboard shortcut. Run this when your rst file is in the active editor
  • "command": "workbench.action.terminal.sendSequence" tells vscode what to do (run the args as a command in the terminal)
  • the command in "args": { "text" :
    • VSCODEOPENFILE=${file} will set the env var the currently open file path
    • sphinx-build -M html ${VSCODEOPENFILE:h} ${${VSCODEOPENFILE:h}/source/build/} ${VSCODEOPENFILE} && code -r ${${VSCODEOPENFILE:h}/source/build/}${${VSCODEOPENFILE:t}/rst/html} will run sphinx rebuild on just the current file
      • -M html use the html builder
      • ${VSCODEOPENFILE:h} is the path to the source dir, e.g., workspace/docs/source
      • ${${VSCODEOPENFILE:h}/source/build/} substitutes build for source to get the path to the build dir, e.g., workspace/docs/build
      • code -r ${${VSCODEOPENFILE:h}/source/build/}${${VSCODEOPENFILE:t}/rst/html} will substitute both build for source and html for rst in the argument (i.e., source/doc.rst will become build/doc.html,) and reopen it in the existing window, forcing the live preview to refresh
      • code -r ${VSCODEOPENFILE} will return you to the original window (e.g., doc.rst,) for editing.
  • when setting will restrict the Command-Shift-R command to work when only when the editor is focused and not read-only.

NOTE this code is for mac os x and zsh, but will likely work elsewhere with a little tweaking

This resolved an issue for me with continuous autorebuilding by sphinx-autobuild due, I assume, to an shutil.copyfile in conf.py. Also I tried a few vscode sphinx and rst-preview extensions, and none of them worked, either.

Upvotes: 0

Andy Lee
Andy Lee

Reputation: 920

You can use sphinx-autobuild. It will also automatically initiate a page refresh in the browser.

It is easy to use, for example:

sphinx-autobuild docs docs/_build/html

or, if you have a separate build dir,

sphinx-autobuild <doc-source-dir> <doc-build-dir>

where <doc-source-dir> is the source directory of your documentation and <doc-build-dir> is the directory where you want the built html files.

Upvotes: 38

ferrouswheel
ferrouswheel

Reputation: 3786

Jacob Kaplan-Moss has a good solution:

pip install watchdog
watchmedo shell-command \
          --patterns="*.rst" \
          --ignore-pattern='_build/*' \
          --recursive \
          --command='make html'

Note, change the pattern to match your suffix. Jacob uses *.txt, but I needed to change it to *.rst.

Upvotes: 17

perrygeo
perrygeo

Reputation: 385

If you're on a *nix system, you can use inotify to monitor filesystem events and trigger actions.

For example, on ubuntu,

apt-get install inotify-tools

Then run a script like this to listen for events in a given dir

while true
  do
    inotifywait -r -e modify -e move -e create -e delete /tmp/docs | while read line
      do
        echo "file changed; time to run make html"
      done
  done

Upvotes: 4

P2bM
P2bM

Reputation: 1048

You can create a macro in you favorite editor that saves the file and opens it in your browser, any text editor can do (geany, gedit, emacs, vi, notepad++...)

Upvotes: 0

Related Questions