mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Allow the config to act as an extension.
This commit is contained in:
parent
b016896c1c
commit
ea2f87fc03
3
CHANGES
3
CHANGES
@ -13,6 +13,9 @@ Changes in trunk
|
||||
* sphinx.builder, sphinx.environment: Gracefully handle some exception
|
||||
cases.
|
||||
|
||||
* sphinx.config: The config file itself can be an extension (if it
|
||||
provides a setup() function).
|
||||
|
||||
|
||||
Release 0.1.61950 (Mar 26, 2008)
|
||||
================================
|
||||
|
40
doc/conf.py
40
doc/conf.py
@ -11,17 +11,17 @@
|
||||
# All configuration values have a default value; values that are commented out
|
||||
# serve to show the default value.
|
||||
|
||||
import sys, os
|
||||
import sys, os, re
|
||||
|
||||
# If your extensions are in another directory, add it here.
|
||||
sys.path.append(os.path.dirname(__file__))
|
||||
#sys.path.append(os.path.dirname(__file__))
|
||||
|
||||
# General configuration
|
||||
# ---------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.addons.*') or your custom ones.
|
||||
extensions = ['ext', 'sphinx.ext.autodoc', 'sphinx.ext.doctest']
|
||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@ -125,3 +125,37 @@ latex_documents = [('contents', 'sphinx.tex', 'Sphinx Documentation',
|
||||
#latex_appendices = []
|
||||
|
||||
automodule_skip_lines = 4
|
||||
|
||||
|
||||
# Extension interface
|
||||
# -------------------
|
||||
|
||||
from sphinx import addnodes
|
||||
|
||||
dir_sig_re = re.compile(r'\.\. ([^:]+)::(.*)$')
|
||||
|
||||
def parse_directive(env, sig, signode):
|
||||
if not sig.startswith('.'):
|
||||
dec_sig = '.. %s::' % sig
|
||||
signode += addnodes.desc_name(dec_sig, dec_sig)
|
||||
return sig
|
||||
m = dir_sig_re.match(sig)
|
||||
if not m:
|
||||
signode += addnodes.desc_name(sig, sig)
|
||||
return sig
|
||||
name, args = m.groups()
|
||||
dec_name = '.. %s::' % name
|
||||
signode += addnodes.desc_name(dec_name, dec_name)
|
||||
signode += addnodes.desc_classname(args, args)
|
||||
return name
|
||||
|
||||
|
||||
def parse_role(env, sig, signode):
|
||||
signode += addnodes.desc_name(':%s:' % sig, ':%s:' % sig)
|
||||
return sig
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_description_unit('directive', 'dir', 'pair: %s; directive', parse_directive)
|
||||
app.add_description_unit('role', 'role', 'pair: %s; role', parse_role)
|
||||
app.add_description_unit('confval', 'confval', 'pair: %s; configuration value')
|
||||
|
@ -50,6 +50,9 @@ General configuration
|
||||
That way, you can load an extension called ``extname`` from the documentation
|
||||
root's subdirectory ``sphinxext``.
|
||||
|
||||
The configuration file itself can be an extension; for that, you only need to
|
||||
provide a :func:`setup` function in it.
|
||||
|
||||
.. confval:: templates_path
|
||||
|
||||
A list of paths that contain extra templates (or templates that overwrite
|
||||
|
40
doc/ext.py
40
doc/ext.py
@ -1,40 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
ext.py -- Sphinx extension for the Sphinx documentation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
:copyright: 2008 by Georg Brandl.
|
||||
:license: BSD.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from sphinx import addnodes
|
||||
|
||||
dir_sig_re = re.compile(r'\.\. ([^:]+)::(.*)$')
|
||||
|
||||
def parse_directive(env, sig, signode):
|
||||
if not sig.startswith('.'):
|
||||
dec_sig = '.. %s::' % sig
|
||||
signode += addnodes.desc_name(dec_sig, dec_sig)
|
||||
return sig
|
||||
m = dir_sig_re.match(sig)
|
||||
if not m:
|
||||
signode += addnodes.desc_name(sig, sig)
|
||||
return sig
|
||||
name, args = m.groups()
|
||||
dec_name = '.. %s::' % name
|
||||
signode += addnodes.desc_name(dec_name, dec_name)
|
||||
signode += addnodes.desc_classname(args, args)
|
||||
return name
|
||||
|
||||
|
||||
def parse_role(env, sig, signode):
|
||||
signode += addnodes.desc_name(':%s:' % sig, ':%s:' % sig)
|
||||
return sig
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_description_unit('directive', 'dir', 'pair: %s; directive', parse_directive)
|
||||
app.add_description_unit('role', 'role', 'pair: %s; role', parse_role)
|
||||
app.add_description_unit('confval', 'confval', 'pair: %s; configuration value')
|
@ -15,6 +15,9 @@ reStructuredText roles and directives, extending the markup. And finally, there
|
||||
are so-called "hook points" at strategic places throughout the build process,
|
||||
where an extension can register a hook and run specialized code.
|
||||
|
||||
The configuration file itself can be an extension, see the :confval:`extensions`
|
||||
configuration value docs.
|
||||
|
||||
.. toctree::
|
||||
|
||||
ext/appapi
|
||||
|
@ -79,6 +79,9 @@ class Sphinx(object):
|
||||
# load all extension modules
|
||||
for extension in getattr(self.config, 'extensions', ()):
|
||||
self.setup_extension(extension)
|
||||
# the config file itself can be an extension
|
||||
if hasattr(self.config, 'setup'):
|
||||
self.config.setup(self)
|
||||
|
||||
# this must happen after loading extension modules, since they
|
||||
# can add custom config values
|
||||
|
@ -10,7 +10,6 @@
|
||||
"""
|
||||
|
||||
import os
|
||||
import types
|
||||
from os import path
|
||||
|
||||
|
||||
@ -77,10 +76,6 @@ class Config(object):
|
||||
execfile(config['__file__'], config)
|
||||
finally:
|
||||
os.chdir(olddir)
|
||||
# remove potentially pickling-problematic values
|
||||
for key, val in config.items():
|
||||
if key.startswith('_') or isinstance(val, types.ModuleType):
|
||||
del config[key]
|
||||
self.__dict__.update(config)
|
||||
|
||||
def init_defaults(self):
|
||||
@ -91,5 +86,11 @@ class Config(object):
|
||||
def __getitem__(self, name):
|
||||
return getattr(self, name)
|
||||
|
||||
def __setitem__(self, name, value):
|
||||
setattr(self, name, value)
|
||||
|
||||
def __delitem__(self, name):
|
||||
delattr(self, name)
|
||||
|
||||
def __contains__(self, name):
|
||||
return hasattr(self, name)
|
||||
|
@ -13,6 +13,7 @@ import re
|
||||
import os
|
||||
import time
|
||||
import heapq
|
||||
import types
|
||||
import difflib
|
||||
import itertools
|
||||
import cPickle as pickle
|
||||
@ -179,6 +180,12 @@ class BuildEnvironment:
|
||||
warnfunc = self._warnfunc
|
||||
self.set_warnfunc(None)
|
||||
picklefile = open(filename, 'wb')
|
||||
# remove potentially pickling-problematic values from config
|
||||
for key, val in vars(self.config).items():
|
||||
if key.startswith('_') or \
|
||||
isinstance(val, types.ModuleType) or \
|
||||
isinstance(val, types.FunctionType):
|
||||
del self.config[key]
|
||||
try:
|
||||
pickle.dump(self, picklefile, pickle.HIGHEST_PROTOCOL)
|
||||
finally:
|
||||
|
Loading…
Reference in New Issue
Block a user