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
|
* sphinx.builder, sphinx.environment: Gracefully handle some exception
|
||||||
cases.
|
cases.
|
||||||
|
|
||||||
|
* sphinx.config: The config file itself can be an extension (if it
|
||||||
|
provides a setup() function).
|
||||||
|
|
||||||
|
|
||||||
Release 0.1.61950 (Mar 26, 2008)
|
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
|
# All configuration values have a default value; values that are commented out
|
||||||
# serve to show the default value.
|
# serve to show the default value.
|
||||||
|
|
||||||
import sys, os
|
import sys, os, re
|
||||||
|
|
||||||
# If your extensions are in another directory, add it here.
|
# 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
|
# General configuration
|
||||||
# ---------------------
|
# ---------------------
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||||
# coming with Sphinx (named 'sphinx.addons.*') or your custom ones.
|
# 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.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
@ -125,3 +125,37 @@ latex_documents = [('contents', 'sphinx.tex', 'Sphinx Documentation',
|
|||||||
#latex_appendices = []
|
#latex_appendices = []
|
||||||
|
|
||||||
automodule_skip_lines = 4
|
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
|
That way, you can load an extension called ``extname`` from the documentation
|
||||||
root's subdirectory ``sphinxext``.
|
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
|
.. confval:: templates_path
|
||||||
|
|
||||||
A list of paths that contain extra templates (or templates that overwrite
|
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,
|
are so-called "hook points" at strategic places throughout the build process,
|
||||||
where an extension can register a hook and run specialized code.
|
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::
|
.. toctree::
|
||||||
|
|
||||||
ext/appapi
|
ext/appapi
|
||||||
|
@ -79,6 +79,9 @@ class Sphinx(object):
|
|||||||
# load all extension modules
|
# load all extension modules
|
||||||
for extension in getattr(self.config, 'extensions', ()):
|
for extension in getattr(self.config, 'extensions', ()):
|
||||||
self.setup_extension(extension)
|
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
|
# this must happen after loading extension modules, since they
|
||||||
# can add custom config values
|
# can add custom config values
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import types
|
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
|
|
||||||
@ -77,10 +76,6 @@ class Config(object):
|
|||||||
execfile(config['__file__'], config)
|
execfile(config['__file__'], config)
|
||||||
finally:
|
finally:
|
||||||
os.chdir(olddir)
|
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)
|
self.__dict__.update(config)
|
||||||
|
|
||||||
def init_defaults(self):
|
def init_defaults(self):
|
||||||
@ -91,5 +86,11 @@ class Config(object):
|
|||||||
def __getitem__(self, name):
|
def __getitem__(self, name):
|
||||||
return getattr(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):
|
def __contains__(self, name):
|
||||||
return hasattr(self, name)
|
return hasattr(self, name)
|
||||||
|
@ -13,6 +13,7 @@ import re
|
|||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import heapq
|
import heapq
|
||||||
|
import types
|
||||||
import difflib
|
import difflib
|
||||||
import itertools
|
import itertools
|
||||||
import cPickle as pickle
|
import cPickle as pickle
|
||||||
@ -179,6 +180,12 @@ class BuildEnvironment:
|
|||||||
warnfunc = self._warnfunc
|
warnfunc = self._warnfunc
|
||||||
self.set_warnfunc(None)
|
self.set_warnfunc(None)
|
||||||
picklefile = open(filename, 'wb')
|
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:
|
try:
|
||||||
pickle.dump(self, picklefile, pickle.HIGHEST_PROTOCOL)
|
pickle.dump(self, picklefile, pickle.HIGHEST_PROTOCOL)
|
||||||
finally:
|
finally:
|
||||||
|
Loading…
Reference in New Issue
Block a user