Allow the configuration directory to be set differently from the source directory.

Also don't import docutils on importing sphinx.
This commit is contained in:
Georg Brandl 2008-05-02 10:32:08 +00:00
parent 5a6e3b61d1
commit e2158213e8
9 changed files with 101 additions and 72 deletions

View File

@ -11,10 +11,10 @@ Document names
Since the reST source files can have different extensions (some people like
``.txt``, some like ``.rst`` -- the extension can be configured with
:confval:`source_suffix`) and different OSes have different path separators,
Sphinx abstracts them: all "document names" are relative to the
:term:`documentation root`, the extension is stripped, and path separators are
converted to slashes. All values, parameters and suchlike referring to
"documents" expect such a document name.
Sphinx abstracts them: all "document names" are relative to the :term:`source
directory`, the extension is stripped, and path separators are converted to
slashes. All values, parameters and suchlike referring to "documents" expect
such a document name.
The TOC tree
@ -71,11 +71,12 @@ tables of contents. The ``toctree`` directive is the central element.
The second line above will link to the ``strings`` document, but will use the
title "All about strings" instead of the title of the ``strings`` document.
In the end, all documents under the :term:`documentation root` must occur in
some ``toctree`` directive; Sphinx will emit a warning if it finds a file
that is not included, because that means that this file will not be reachable
through standard navigation. Use :confval:`unused_documents` to explicitly
exclude documents from this check.
In the end, all documents in the :term:`source directory` (or subdirectories)
must occur in some ``toctree`` directive; Sphinx will emit a warning if it
finds a file that is not included, because that means that this file will not
be reachable through standard navigation. Use :confval:`unused_documents` to
explicitly exclude documents from this check, and :confval:`exclude_dirs` to
exclude whole directories.
The "master document" (selected by :confval:`master_doc`) is the "root" of
the TOC tree hierarchy. It can be used as the documentation's main page, or

View File

@ -6,30 +6,32 @@ The build configuration file
.. module:: conf
:synopsis: Build configuration file.
The :term:`documentation root` must contain a file named :file:`conf.py`. This
file (containing Python code) is called the "build configuration file" and
The :term:`configuration directory` must contain a file named :file:`conf.py`.
This file (containing Python code) is called the "build configuration file" and
contains all configuration needed to customize Sphinx input and output behavior.
The configuration file if executed as Python code at build time (using
:func:`execfile`, and with the current directory set to the documentation root),
and therefore can execute arbitrarily complex code. Sphinx then reads simple
names from the file's namespace as its configuration.
:func:`execfile`, and with the current directory set to its containing
directory), and therefore can execute arbitrarily complex code. Sphinx then
reads simple names from the file's namespace as its configuration.
Some conventions are important to keep in mind here: Relative paths are always
used relative to the documentation root, and document names must always be given
without file name extension.
Important points to note:
The term "fully-qualified name" refers to a string that names an importable
Python object inside a module; for example, the FQN ``"sphinx.builder.Builder"``
means the ``Builder`` class in the ``sphinx.builder`` module.
* If not otherwise documented, values must be strings, and their default is the
empty string.
The contents of the namespace are pickled (so that Sphinx can find out when
configuration changes), so it may not contain unpickleable values -- delete them
from the namespace with ``del`` if appropriate. Modules are removed
automatically, so you don't need to ``del`` your imports after use.
* The term "fully-qualified name" refers to a string that names an importable
Python object inside a module; for example, the FQN
``"sphinx.builder.Builder"`` means the ``Builder`` class in the
``sphinx.builder`` module.
The configuration values can be separated in several groups. If not otherwise
documented, values must be strings, and their default is the empty string.
* Remember that document names use ``/`` as the path separator and don't contain
the file name extension.
* The contents of the config namespace are pickled (so that Sphinx can find out
when configuration changes), so it may not contain unpickleable values --
delete them from the namespace with ``del`` if appropriate. Modules are
removed automatically, so you don't need to ``del`` your imports after use.
General configuration
@ -41,9 +43,9 @@ General configuration
extensions coming with Sphinx (named ``sphinx.addons.*``) or custom ones.
Note that you can extend :data:`sys.path` within the conf file if your
extensions live in another directory -- but make sure you use absolute
paths. If your extension path is relative to the documentation root, use
:func:`os.path.abspath` like so::
extensions live in another directory -- but make sure you use absolute paths.
If your extension path is relative to the :term:`configuration directory`,
use :func:`os.path.abspath` like so::
import sys, os
@ -51,8 +53,8 @@ General configuration
extensions = ['extname']
That way, you can load an extension called ``extname`` from the documentation
root's subdirectory ``sphinxext``.
That way, you can load an extension called ``extname`` from the subdirectory
``sphinxext``.
The configuration file itself can be an extension; for that, you only need to
provide a :func:`setup` function in it.
@ -128,7 +130,8 @@ General configuration
.. confval:: templates_path
A list of paths that contain extra templates (or templates that overwrite
builtin templates).
builtin templates). Relative paths are taken as relative to the
configuration directory.
.. confval:: template_bridge
@ -186,8 +189,9 @@ that use Sphinx' HTMLWriter class.
.. confval:: html_static_path
A list of paths that contain custom static files (such as style sheets or
script files). They are copied to the output directory after the builtin
static files, so a file named :file:`default.css` will overwrite the builtin
script files). Relative paths are taken as relative to the configuration
directory. They are copied to the output directory after the builtin static
files, so a file named :file:`default.css` will overwrite the builtin
:file:`default.css`.
.. confval:: html_last_updated_fmt
@ -303,8 +307,8 @@ These options influence LaTeX output.
.. confval:: latex_logo
If given, this must be the name of an image file (relative to the
documentation root) that is the logo of the docs. It is placed at the top of
the title page. Default: ``None``.
configuration directory) that is the logo of the docs. It is placed at the
top of the title page. Default: ``None``.
.. confval:: latex_appendices

View File

@ -14,17 +14,22 @@ Glossary
See :ref:`builders` for an overview over Sphinx' built-in builders.
configuration directory
The directory containing :file:`conf.py`. By default, this is the same as
the :term:`source directory`, but can be set differently with the **-c**
command-line option.
description unit
The basic building block of Sphinx documentation. Every "description
directive" (e.g. :dir:`function` or :dir:`describe`) creates such a unit;
and most units can be cross-referenced to.
documentation root
The directory which contains the documentation's :file:`conf.py` file and
is therefore seen as one Sphinx project.
environment
A structure where information about all documents under the root is saved,
and used for cross-referencing. The environment is pickled after the
parsing stage, so that successive runs only need to read and parse new and
changed documents.
source directory
The directory which, including its subdirectories, contains all source
files for one Sphinx project.

View File

@ -31,16 +31,20 @@ or some (not broken) SVN trunk snapshot.
.. _Pygments: http://pygments.org
Setting up a documentation root
-------------------------------
Setting up the documentation sources
------------------------------------
The root directory of a documentation collection is called the
:dfn:`documentation root`. There's nothing special about it; it just needs to
contain the Sphinx configuration file, :file:`conf.py`.
The root directory of a documentation collection is called the :dfn:`source
directory`. Normally, this directory also contains the Sphinx configuration
file :file:`conf.py`, but that file can also live in another directory, the
:dfn:`configuration directory`.
.. versionadded:: 0.2.1
Support for a different configuration directory.
Sphinx comes with a script called :program:`sphinx-quickstart` that sets up a
documentation root and creates a default :file:`conf.py` from a few questions
it asks you. Just run ::
source directory and creates a default :file:`conf.py` from a few questions it
asks you. Just run ::
$ sphinx-quickstart
@ -55,7 +59,7 @@ like this::
$ sphinx-build -b latex sourcedir builddir
where *sourcedir* is the :term:`documentation root`, and *builddir* is the
where *sourcedir* is the :term:`source directory`, and *builddir* is the
directory in which you want to place the built documentation (it must be an
existing directory). The :option:`-b` option selects a builder; in this example
Sphinx will build LaTeX files.
@ -79,6 +83,15 @@ The :program:`sphinx-build` script has several more options:
the build directory; with this option you can select a different cache
directory (the doctrees can be shared between all builders).
**-c** *path*
Don't look for the :file:`conf.py` in the source directory, but use the given
configuration directory instead. Note that various other files and paths
given by configuration values are expected to be relative to the
configuration directory, so they will have to be present at this location
too.
.. versionadded:: 0.2.1
**-D** *setting=value*
Override a configuration value set in the :file:`conf.py` file. (The value
must be a string value.)

View File

@ -169,16 +169,15 @@ Glossary
.. glossary::
documentation root
The directory which contains the documentation's :file:`conf.py` file and
is therefore seen as one Sphinx project.
environment
A structure where information about all documents under the root is saved,
and used for cross-referencing. The environment is pickled after the
parsing stage, so that successive runs only need to read and parse new and
changed documents.
source directory
The directory which, including its subdirectories, contains all source
files for one Sphinx project.
Grammar production displays

View File

@ -16,10 +16,7 @@ import traceback
from os import path
from cStringIO import StringIO
from docutils.utils import SystemMessage
from sphinx.util import format_exception_cut_frames, save_traceback
from sphinx.application import Sphinx
from sphinx.util.console import darkred, nocolor
__revision__ = '$Revision$'
@ -37,8 +34,10 @@ Options: -b <builder> -- builder to use; default is html
-a -- write all files; default is to only write new and changed files
-E -- don't use a saved environment, always read all files
-d <path> -- path for the cached environment and doctree files
(default outdir/.doctrees)
-D <setting=value> -- override a setting in sourcedir/conf.py
(default: outdir/.doctrees)
-c <path> -- path where configuration file (conf.py) is located
(default: same as sourcedir)
-D <setting=value> -- override a setting in configuration
-N -- do not do colored output
-q -- no output on stdout, just warnings on stderr
-P -- run Pdb on exception
@ -49,17 +48,23 @@ Modi:
def main(argv=sys.argv):
# delay-import these to be able to get sphinx.__version__ from setup.py
# even without docutils installed
from sphinx.application import Sphinx
from docutils.utils import SystemMessage
if not sys.stdout.isatty() or sys.platform == 'win32':
# Windows' poor cmd box doesn't understand ANSI sequences
nocolor()
try:
opts, args = getopt.getopt(argv[1:], 'ab:d:D:NEqP')
srcdir = path.abspath(args[0])
opts, args = getopt.getopt(argv[1:], 'ab:d:c:D:NEqP')
srcdir = confdir = path.abspath(args[0])
if not path.isdir(srcdir):
print >>sys.stderr, 'Error: Cannot find source directory.'
return 1
if not path.isfile(path.join(srcdir, 'conf.py')):
if not path.isfile(path.join(srcdir, 'conf.py')) and \
'-c' not in (opt[0] for opt in opts):
print >>sys.stderr, 'Error: Source directory doesn\'t contain conf.py file.'
return 1
outdir = path.abspath(args[1])
@ -94,6 +99,12 @@ def main(argv=sys.argv):
all_files = True
elif opt == '-d':
doctreedir = val
elif opt == '-c':
confdir = path.abspath(val)
if not path.isfile(path.join(confdir, 'conf.py')):
print >>sys.stderr, \
'Error: Configuration directory doesn\'t contain conf.py file.'
return 1
elif opt == '-D':
key, val = val.split('=')
try:
@ -110,7 +121,7 @@ def main(argv=sys.argv):
use_pdb = True
try:
app = Sphinx(srcdir, outdir, doctreedir, buildername,
app = Sphinx(srcdir, confdir, outdir, doctreedir, buildername,
confoverrides, status, sys.stderr, freshenv)
if not app.builder:
return 1

View File

@ -60,7 +60,7 @@ class BuiltinTemplates(TemplateBridge):
def init(self, builder):
self.templates = {}
base_templates_path = path.join(path.dirname(__file__), 'templates')
ext_templates_path = [path.join(builder.srcdir, dir)
ext_templates_path = [path.join(builder.confdir, dir)
for dir in builder.config.templates_path]
self.templates_path = [base_templates_path] + ext_templates_path
loader = SphinxFileSystemLoader(base_templates_path, ext_templates_path)

View File

@ -54,7 +54,7 @@ events = {
class Sphinx(object):
def __init__(self, srcdir, outdir, doctreedir, buildername,
def __init__(self, srcdir, confdir, outdir, doctreedir, buildername,
confoverrides, status, warning=sys.stderr, freshenv=False):
self.next_listener_id = 0
self._listeners = {}
@ -62,6 +62,7 @@ class Sphinx(object):
self.builder = None
self.srcdir = srcdir
self.confdir = confdir
self.outdir = outdir
self.doctreedir = doctreedir
@ -72,7 +73,7 @@ class Sphinx(object):
self._events = events.copy()
# read config
self.config = Config(srcdir, 'conf.py')
self.config = Config(confdir, 'conf.py')
if confoverrides:
for key, val in confoverrides.items():
setattr(self.config, key, val)

View File

@ -50,6 +50,7 @@ class Builder(object):
def __init__(self, app, env=None, freshenv=False):
self.srcdir = app.srcdir
self.confdir = app.confdir
self.outdir = app.outdir
self.doctreedir = app.doctreedir
if not path.isdir(self.doctreedir):
@ -487,19 +488,13 @@ class StandaloneHTMLBuilder(Builder):
self.info(' '+src, nonl=1)
shutil.copyfile(path.join(self.srcdir, src),
path.join(self.outdir, '_images', dest))
# the logo is handled differently
if self.config.html_logo:
logobase = path.basename(self.config.html_logo)
self.info(' '+logobase, nonl=1)
shutil.copyfile(path.join(self.srcdir, self.config.html_logo),
path.join(self.outdir, '_static', logobase))
self.info()
# copy static files
self.info(bold('copying static files...'))
ensuredir(path.join(self.outdir, '_static'))
staticdirnames = [path.join(path.dirname(__file__), 'static')] + \
[path.join(self.srcdir, spath)
[path.join(self.confdir, spath)
for spath in self.config.html_static_path]
for staticdirname in staticdirnames:
for filename in os.listdir(staticdirname):
@ -819,7 +814,7 @@ class LaTeXBuilder(Builder):
if self.config.latex_logo:
logobase = path.basename(self.config.latex_logo)
self.info(' '+logobase, nonl=1)
shutil.copyfile(path.join(self.srcdir, self.config.latex_logo),
shutil.copyfile(path.join(self.confdir, self.config.latex_logo),
path.join(self.outdir, logobase))
self.info(bold('copying TeX support files...'))