--- /dev/null
+*.pyc
+_build
 
--- /dev/null
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+DOCBUILDDIR   := _build
+
+SRCDIR ?= .
+ALLSPHINXOPTS := -d $(DOCBUILDDIR)/doctrees $(SPHINXOPTS) $(SRCDIR)
+
+MAN_RST_FILES := $(shell find $(SRCDIR)/man* -name '*.rst')
+MAN_ROFF_FILES := $(patsubst $(SRCDIR)/man%.rst,$(DOCBUILDDIR)/man/man%,$(MAN_RST_FILES))
+MAN_GZIP_FILES := $(addsuffix .gz,$(MAN_ROFF_FILES))
+
+.PHONY: build-man
+build-man: $(MAN_GZIP_FILES)
+
+%.gz: %
+       rm -f $@ && gzip --stdout $^ > $@
+
+$(MAN_ROFF_FILES): $(DOCBUILDDIR)/.roff.stamp
+
+# By using $(DOCBUILDDIR)/.roff.stamp instead of $(MAN_ROFF_FILES), we
+# convey to make that a single invocation of this recipe builds all
+# of the roff files.  This prevents parallel make from starting an
+# instance of this recipe for each roff file.
+$(DOCBUILDDIR)/.roff.stamp $(MAN_ROFF_FILES): $(MAN_RST_FILES)
+       mkdir -p $(DOCBUILDDIR)
+       touch $(DOCBUILDDIR)/.roff.stamp
+       $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(DOCBUILDDIR)/man
+       for section in 1 5; do \
+           mkdir -p $(DOCBUILDDIR)/man/man$${section}; \
+           mv $(DOCBUILDDIR)/man/*.$${section} $(DOCBUILDDIR)/man/man$${section}; \
+       done
+
+clean:
+       rm -rf $(DOCBUILDDIR) $(SRCDIR)/conf.pyc
 
--- /dev/null
+# -*- coding: utf-8 -*-
+
+import os.path
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = 'notmuch'
+authors = 'Carl Worth and many others'
+copyright = '2009-2015, {0}'.format(authors)
+
+location = os.path.dirname(__file__)
+
+dirname = location
+while True:
+    version_file = os.path.join(dirname, 'version')
+    if os.path.exists(version_file):
+        with open(version_file,'r') as f:
+            version = f.read().strip()
+            break
+    if dirname == '/':
+        raise ValueError(
+            'no version file found in this directory or its ancestors')
+    dirname = os.path.dirname(dirname)
+
+# The full version, including alpha/beta/rc tags.
+release = version
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+
+man_pages = [
+    ('man1/notmuch-report.1', 'notmuch-report',
+     'generate reports from notmuch queries', [authors], 1),
+    ('man5/notmuch-report.json.5', 'notmuch-report.json',
+     'configure notmuch-report', [authors], 5),
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+texinfo_no_detailmenu = True
+
+texinfo_documents = [
+    ('man1/notmuch-report.1', 'notmuch-report',
+     'generate reports from notmuch queries', authors, 'notmuch-report',
+     'generate reports from notmuch queries', 'Miscellaneous'),
+    ('man5/notmuch-report.json.5', 'notmuch-report.json',
+     'configure notmuch-report', authors, 'notmuch-report.json',
+     'configure notmuch-report', 'Miscellaneous'),
+]
 
--- /dev/null
+Welcome to notmuch's dev-tool documentation!
+============================================
+
+Contents:
+
+.. toctree::
+   :titlesonly:
+
+   man1/notmuch-report.1
+   man5/notmuch-report.json.5
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
 
--- /dev/null
+==============
+notmuch-report
+==============
+
+SYNOPSIS
+========
+
+**notmuch-report** [options ...]
+
+DESCRIPTION
+===========
+
+Generate HTML or plain-text reports showing query results.
+
+OPTIONS
+=======
+
+  ``-h``, ``--help``
+
+    Show a help message, including a list of available options, and
+    exit.
+
+  ``--text``
+    Output plain text instead of HTML.
+
+  ``--config`` <PATH>
+    Load config from given file.  The format is described in
+    **notmuch-report.json(5)**.  If this option is not set,
+    **notmuch-report** loads the config from the Git repository at
+    ``NMBGIT``.  See :ref:`NMBGIT <NMBGIT>` for details.
+
+  ``--list-views``
+    List available views (by title) and exit.
+
+  ``--get-query`` <VIEW>
+    Print the configured query for view matching the given title.
+
+ENVIRONMENT
+===========
+
+.. _NMBGIT:
+
+  ``NMBGIT``
+    If ``--config PATH`` is not set, **notmuch-report** will attempt
+    to load a config file named ``notmuch-report.json`` from the
+    ``config`` branch of the ``NMBGIT`` repository (defaulting to
+    ``~/.nmbug``).
+
+SEE ALSO
+========
+
+**notmuch(1)**, **notmuch-report.json(5)**, **notmuch-search(1)**,
+ **notmuch-tag(1)**
+
 
--- /dev/null
+==============
+notmuch-report
+==============
+
+NAME
+====
+
+notmuch-report.json - configure output for **notmuch-report(1)**
+
+DESCRIPTION
+===========
+
+The config file is JSON_ with the following fields:
+
+meta
+  An object with page-wide information
+
+  title
+    Page title used in the default header.
+
+  blurb
+    Introduction paragraph used in the default header.
+
+  header
+    `Python format string`_ for the HTML header.  Optional.  It is
+    formatted with the following context:
+
+    date
+      The current UTC date.
+
+    datetime
+      The current UTC date-time.
+
+    title
+      The **meta.title** value.
+
+    blurb
+      The **meta.blurb** value.
+
+    encoding
+      The encoding used for the output file.
+
+    inter_message_padding
+      0.25em, for consistent CSS generation.
+
+    border_radius
+      0.5em, for consistent CSS generation.
+
+  footer
+    `Python format string`_ for the HTML footer.  It is formatted with
+    the same context used for **meta.header**.  Optional.
+
+  message-url
+    `Python format string`_ for message-linking URLs.  Optional.
+    Defaults to linking Gmane_.  It is formatted with the following
+    context:
+
+    message-id
+      The quoted_ message ID.
+
+    subject
+      The message subject.
+
+views
+  An array of view objects, where each object has the following
+  fields:
+
+  title
+    Header text for the view.
+
+  comment
+    Paragraph describing the view in more detail.  Optional.
+
+  id
+    Anchor string for the view.  Optional, defaulting to a slugged
+    form of the view title
+
+  query
+    An array of strings, which will be joined with 'and' to form the
+    view query.
+
+.. _Gmane: http://gmane.org/
+.. _JSON: http://json.org/
+.. _Python format string: https://docs.python.org/3/library/string.html#formatstrings
+.. _quoted: https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote
+
+EXAMPLE
+=======
+
+::
+
+  {
+    "meta": {
+      "title": "Notmuch Patches",
+      "blurb": "For more information see <a href=\"http://notmuchmail.org/nmbug\">nmbug</a>",
+      "header": "<html><head></head><body><h1>{title}</h1><p>{blurb}</p><h2>Views</h2>",
+      "footer": "<hr><p>Generated: {datetime}</p></html>",
+      "message-url": "http://mid.gmane.org/{message-id}"
+    },
+    "views": [
+      {
+        "title": "Bugs",
+        "comment": "Unresolved bugs.",
+        "query": [
+          "tag:notmuch::bug",
+          "not tag:notmuch::fixed",
+          "not tag:notmuch::wontfix"
+        ]
+      },
+      {
+        "title": "Review",
+        "comment": "These patches are under review, or waiting for feedback.",
+        "id": "under-review",
+        "query": [
+          "tag:notmuch::patch",
+          "not tag:notmuch::pushed",
+          "not tag:notmuch::obsolete",
+          "not tag:notmuch::stale",
+          "not tag:notmuch::wontfix",
+          "(tag:notmuch::moreinfo or tag:notmuch::needs-review)"
+        ]
+      }
+    ]
+  }
+
+SEE ALSO
+========
+
+**notmuch(1)**, **notmuch-report(1)**, **notmuch-search(1)**, **notmuch-tag(1)**
 
         return self._slug_regexp.sub('-', string)
 
 parser = argparse.ArgumentParser(description=__doc__)
-parser.add_argument('--text', help='output plain text format',
-                    action='store_true')
-parser.add_argument('--config', help='load config from given file',
-                    metavar='PATH')
-parser.add_argument('--list-views', help='list views',
-                    action='store_true')
-parser.add_argument('--get-query', help='get query for view',
-                    metavar='VIEW')
+parser.add_argument(
+    '--text', action='store_true', help='output plain text format')
+parser.add_argument(
+    '--config', metavar='PATH',
+    help='load config from given file.  '
+        'The format is described in notmuch-report.json(5).')
+parser.add_argument(
+    '--list-views', action='store_true', help='list views')
+parser.add_argument(
+    '--get-query', metavar='VIEW', help='get query for view')
+
 
 args = parser.parse_args()