[Python-checkins] r61331 - in doctools/trunk/sphinx: _jinja.py application.py builder.py config.py directives.py environment.py quickstart.py roles.py static/sphinxdoc.css
georg.brandl
python-checkins at python.org
Sun Mar 9 19:18:42 CET 2008
Author: georg.brandl
Date: Sun Mar 9 19:18:41 2008
New Revision: 61331
Modified:
doctools/trunk/sphinx/ (props changed)
doctools/trunk/sphinx/_jinja.py
doctools/trunk/sphinx/application.py
doctools/trunk/sphinx/builder.py
doctools/trunk/sphinx/config.py
doctools/trunk/sphinx/directives.py
doctools/trunk/sphinx/environment.py
doctools/trunk/sphinx/quickstart.py
doctools/trunk/sphinx/roles.py
doctools/trunk/sphinx/static/sphinxdoc.css
Log:
* Allow registering arbitrary cross-referencing directives/roles.
* Allow labels anywhere, and allow giving an explicit caption in :ref: links.
* Some fixes to the sphinxdoc style.
* Add an option to show author information in the output.
* Search user-defined templates in the order they occur in the config
(thanks Nick).
Modified: doctools/trunk/sphinx/_jinja.py
==============================================================================
--- doctools/trunk/sphinx/_jinja.py (original)
+++ doctools/trunk/sphinx/_jinja.py Sun Mar 9 19:18:41 2008
@@ -25,12 +25,19 @@
paths, or from an absolute path.
"""
- def __init__(self, paths):
- self.searchpaths = map(path.abspath, paths)
+ def __init__(self, basepath, extpaths):
+ self.basepath = path.abspath(basepath)
+ self.extpaths = map(path.abspath, extpaths)
+ self.searchpaths = self.extpaths + [self.basepath]
def get_source(self, environment, name, parent):
name = name.replace('/', path.sep)
- if path.isabs(name):
+ if name.startswith('!'):
+ name = name[1:]
+ if not path.exists(path.join(self.basepath, name)):
+ raise TemplateNotFound(name)
+ filename = path.join(self.basepath, name)
+ elif path.isabs(name):
if not path.exists(name):
raise TemplateNotFound(name)
filename = name
Modified: doctools/trunk/sphinx/application.py
==============================================================================
--- doctools/trunk/sphinx/application.py (original)
+++ doctools/trunk/sphinx/application.py Sun Mar 9 19:18:41 2008
@@ -18,8 +18,10 @@
from docutils.parsers.rst import directives, roles
import sphinx
+from sphinx.roles import xfileref_role
from sphinx.config import Config
from sphinx.builder import builtin_builders
+from sphinx.directives import desc_directive, additional_xref_types
from sphinx.util.console import bold
@@ -185,3 +187,9 @@
def add_role(self, name, role):
roles.register_canonical_role(name, role)
+
+ def add_description_unit(self, directivename, rolename, indexdesc='',
+ parse_node=None):
+ additional_xref_types[directivename] = (rolename, indexdesc, parse_node)
+ directives.register_directive(directivename, desc_directive)
+ roles.register_canonical_role(rolename, xfileref_role)
Modified: doctools/trunk/sphinx/builder.py
==============================================================================
--- doctools/trunk/sphinx/builder.py (original)
+++ doctools/trunk/sphinx/builder.py Sun Mar 9 19:18:41 2008
@@ -79,10 +79,9 @@
# load templates
self.templates = {}
- templates_path = [path.join(path.dirname(__file__), 'templates')]
- templates_path.extend(self.config.templates_path)
- templates_path.reverse()
- self.jinja_env = Environment(loader=SphinxFileSystemLoader(templates_path),
+ base_templates_path = path.join(path.dirname(__file__), 'templates')
+ loader = SphinxFileSystemLoader(base_templates_path, self.config.templates_path)
+ self.jinja_env = Environment(loader=loader,
# disable traceback, more likely that something
# in the application is broken than in the templates
friendly_traceback=False)
@@ -438,13 +437,11 @@
# additional pages from conf.py
for pagename, template in self.config.html_additional_pages.items():
- template = path.join(self.srcdir, template)
self.handle_page(pagename, {}, template)
# the index page
indextemplate = self.config.html_index
if indextemplate:
- indextemplate = path.join(self.srcdir, indextemplate)
self.handle_page('index', {'indextemplate': indextemplate}, 'index.html')
# copy static files
@@ -515,7 +512,7 @@
ctx['hasdoc'] = lambda name: name in self.env.all_docs
sidebarfile = self.config.html_sidebars.get(pagename)
if sidebarfile:
- ctx['customsidebar'] = path.join(self.srcdir, sidebarfile)
+ ctx['customsidebar'] = sidebarfile
ctx.update(addctx)
output = self.get_template(templatename).render(ctx)
Modified: doctools/trunk/sphinx/config.py
==============================================================================
--- doctools/trunk/sphinx/config.py (original)
+++ doctools/trunk/sphinx/config.py Sun Mar 9 19:18:41 2008
@@ -20,7 +20,7 @@
# the values are: (default, needs fresh doctrees if changed)
# If you add a value here, don't forget to include it in the
- # quickstart.py file template as well!
+ # quickstart.py file template as well as in the docs!
config_values = dict(
# general substitutions
@@ -41,6 +41,7 @@
unused_docs = ([], True),
add_function_parentheses = (True, True),
add_module_names = (True, True),
+ show_authors = (False, True),
pygments_style = ('sphinx', False),
# HTML options
Modified: doctools/trunk/sphinx/directives.py
==============================================================================
--- doctools/trunk/sphinx/directives.py (original)
+++ doctools/trunk/sphinx/directives.py Sun Mar 9 19:18:41 2008
@@ -310,21 +310,30 @@
targetname, targetname)
env.note_reftarget('option', optname, targetname)
continue
- elif desctype == 'envvar':
+ elif desctype == 'describe':
signode.clear()
signode += addnodes.desc_name(sig, sig)
+ continue
+ else:
+ # another registered generic x-ref directive
+ rolename, indextext, parse_node = additional_xref_types[desctype]
+ if parse_node:
+ parse_node(sig, signode)
+ else:
+ signode.clear()
+ signode += addnodes.desc_name(sig, sig)
if not noindex:
- targetname = 'envvar-' + sig
+ targetname = '%s-%s' % (rolename, sig)
signode['ids'].append(targetname)
state.document.note_explicit_target(signode)
- env.note_index_entry('pair', 'environment variable; %s' % sig,
- targetname, targetname)
- env.note_reftarget('envvar', sig, targetname)
+ if indextext:
+ env.note_index_entry('pair', '%s; %s' % (indextext, sig),
+ targetname, targetname)
+ env.note_reftarget(rolename, sig, targetname)
+ # don't use object indexing below
continue
- else:
- # for "describe": use generic fallback
- raise ValueError
except ValueError, err:
+ # signature parsing failed
signode.clear()
signode += addnodes.desc_name(sig, sig)
continue # we don't want an index entry here
@@ -384,15 +393,22 @@
'cvar',
# the odd one
'opcode',
- # the generic ones
- 'cmdoption', # for command line options
- 'envvar', # for environment variables
+ # for command line options
+ 'cmdoption',
+ # the generic one
'describe',
+ 'envvar',
]
for _name in desctypes:
directives.register_directive(_name, desc_directive)
+# Generic cross-reference types; they can be registered in the application
+additional_xref_types = {
+ # directive name: (role name, index text)
+ 'envvar': ('envvar', 'environment variable', None),
+}
+
# ------ versionadded/versionchanged -----------------------------------------------
@@ -526,8 +542,23 @@
def author_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
- # The author directives aren't included in the built document
- return []
+ # Show authors only if the show_authors option is on
+ env = state.document.settings.env
+ if not env.config.show_authors:
+ return []
+ para = nodes.paragraph()
+ emph = nodes.emphasis()
+ para += emph
+ if name == 'sectionauthor':
+ text = 'Section author: '
+ elif name == 'moduleauthor':
+ text = 'Module author: '
+ else:
+ text = 'Author: '
+ emph += nodes.Text(text, text)
+ inodes, messages = state.inline_text(arguments[0], lineno)
+ emph.extend(inodes)
+ return [para] + messages
author_directive.arguments = (1, 0, 1)
directives.register_directive('sectionauthor', author_directive)
Modified: doctools/trunk/sphinx/environment.py
==============================================================================
--- doctools/trunk/sphinx/environment.py (original)
+++ doctools/trunk/sphinx/environment.py Sun Mar 9 19:18:41 2008
@@ -44,6 +44,7 @@
from sphinx import addnodes
from sphinx.util import get_matching_docs, SEP
+from sphinx.directives import additional_xref_types
default_settings = {
'embed_stylesheet': False,
@@ -56,7 +57,7 @@
# This is increased every time a new environment attribute is added
# to properly invalidate pickle files.
-ENV_VERSION = 16
+ENV_VERSION = 17
def walk_depth(node, depth, maxdepth):
@@ -226,6 +227,7 @@
self.filemodules = {} # docname -> [modules]
self.modules = {} # modname -> docname, synopsis, platform, deprecated
self.labels = {} # labelname -> docname, labelid, sectionname
+ self.anonlabels = {} # labelname -> docname, labelid
self.reftargets = {} # (type, name) -> docname, labelid
# where type is term, token, option, envvar
@@ -471,13 +473,19 @@
continue
labelid = document.nameids[name]
node = document.ids[labelid]
- if not isinstance(node, nodes.section):
- # e.g. desc-signatures
+ if name.isdigit() or node.has_key('refuri') or \
+ node.tagname.startswith('desc_'):
+ # ignore footnote labels, labels automatically generated from a
+ # link and description units
continue
- sectname = node[0].astext() # node[0] == title node
if name in self.labels:
self.warn(docname, 'duplicate label %s, ' % name +
'other instance in %s' % self.doc2path(self.labels[name][0]))
+ self.anonlabels[name] = docname, labelid
+ if not isinstance(node, nodes.section):
+ # anonymous-only labels
+ continue
+ sectname = node[0].astext() # node[0] == title node
self.labels[name] = docname, labelid, sectname
def note_toctree(self, docname, toctreenode):
@@ -654,23 +662,37 @@
typ = node['reftype']
target = node['reftarget']
+ reftarget_roles = set(('token', 'term', 'option'))
+ # add all custom xref types too
+ reftarget_roles.update(i[0] for i in additional_xref_types.values())
+
try:
if typ == 'ref':
- # reference to the named label; the final node will contain the
- # section name after the label
- docname, labelid, sectname = self.labels.get(target, ('','',''))
- if not docname:
- newnode = doctree.reporter.system_message(
- 2, 'undefined label: %s' % target)
- #self.warn(fromdocname, 'undefined label: %s' % target)
+ if node['refcaption']:
+ # reference to anonymous label; the reference uses the supplied
+ # link caption
+ docname, labelid = self.anonlabels.get(target, ('',''))
+ sectname = node.astext()
+ if not docname:
+ newnode = doctree.reporter.system_message(
+ 2, 'undefined label: %s' % target)
else:
+ # reference to the named label; the final node will contain the
+ # section name after the label
+ docname, labelid, sectname = self.labels.get(target, ('','',''))
+ if not docname:
+ newnode = doctree.reporter.system_message(
+ 2, 'undefined label: %s -- if you don\'t ' % target +
+ 'give a link caption the label must precede a section '
+ 'header.')
+ if docname:
newnode = nodes.reference('', '')
innernode = nodes.emphasis(sectname, sectname)
if docname == fromdocname:
newnode['refid'] = labelid
else:
- # set more info in contnode in case the following call
- # raises NoUri, the builder will have to resolve these
+ # set more info in contnode in case the get_relative_uri call
+ # raises NoUri, the builder will then have to resolve these
contnode = addnodes.pending_xref('')
contnode['refdocname'] = docname
contnode['refsectname'] = sectname
@@ -693,7 +715,7 @@
newnode['refuri'] = builder.get_relative_uri(
fromdocname, docname) + '#' + labelid
newnode.append(contnode)
- elif typ in ('token', 'term', 'envvar', 'option'):
+ elif typ in reftarget_roles:
docname, labelid = self.reftargets.get((typ, target), ('', ''))
if not docname:
if typ == 'term':
Modified: doctools/trunk/sphinx/quickstart.py
==============================================================================
--- doctools/trunk/sphinx/quickstart.py (original)
+++ doctools/trunk/sphinx/quickstart.py Sun Mar 9 19:18:41 2008
@@ -78,6 +78,10 @@
# unit titles (such as .. function::).
#add_module_names = True
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
@@ -103,14 +107,14 @@
# typographically correct entities.
#html_use_smartypants = True
-# Content template for the index page, filename relative to this file.
+# Content template for the index page.
#html_index = ''
-# Custom sidebar templates, maps page names to filenames relative to this file.
+# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
-# filenames relative to this file.
+# template names.
#html_additional_pages = {}
# If true, the reST sources are included in the HTML build as _sources/<name>.
Modified: doctools/trunk/sphinx/roles.py
==============================================================================
--- doctools/trunk/sphinx/roles.py (original)
+++ doctools/trunk/sphinx/roles.py Sun Mar 9 19:18:41 2008
@@ -17,6 +17,7 @@
from sphinx import addnodes
ws_re = re.compile(r'\s+')
+caption_ref_re = re.compile(r'^([^<]+?)\s*<(.+)>$')
generic_docroles = {
'command' : nodes.strong,
@@ -127,6 +128,21 @@
pnode['refspecific'] = True
if typ == 'term':
pnode['reftarget'] = ws_re.sub(' ', text).lower()
+ elif typ == 'ref':
+ brace = text.find('<')
+ if brace != -1:
+ pnode['refcaption'] = True
+ m = caption_ref_re.match(text)
+ if not m:
+ # fallback
+ pnode['reftarget'] = text[brace+1:]
+ text = text[:brace]
+ else:
+ pnode['reftarget'] = m.group(2)
+ text = m.group(1)
+ else:
+ pnode['refcaption'] = False
+ pnode['reftarget'] = ws_re.sub('', text)
elif typ == 'option':
if text[0] in '-/':
pnode['reftarget'] = text[1:]
Modified: doctools/trunk/sphinx/static/sphinxdoc.css
==============================================================================
--- doctools/trunk/sphinx/static/sphinxdoc.css (original)
+++ doctools/trunk/sphinx/static/sphinxdoc.css Sun Mar 9 19:18:41 2008
@@ -64,11 +64,24 @@
tt.descclassname {
background-color: transparent;
+ border: 0;
}
-tt.xref, a tt {
+tt.xref {
background-color: transparent;
font-weight: bold;
+ border: 0;
+}
+
+a tt {
+ background-color: transparent;
+ font-weight: bold;
+ border: 0;
+ color: #CA7900;
+}
+
+a tt:hover {
+ color: #2491CF;
}
dl {
@@ -99,19 +112,10 @@
background-color: #fbe54e;
}
-/*
-dt {
- margin-top: 0.8em;
-}
-
-dd p.first {
- margin-top: 0;
-}
-
-dd p.last {
- margin-bottom: 0;
+dl.glossary dt {
+ font-weight: bold;
+ font-size: 1.1em;
}
-*/
pre {
line-height: 120%;
@@ -122,10 +126,6 @@
text-decoration: underline;
}
-div.syntax {
- background-color: transparent;
-}
-
div.document {
background-color: white;
text-align: left;
@@ -226,6 +226,10 @@
border-right: 1px solid #ccc;
}
+div.body a {
+ text-decoration: underline;
+}
+
div.sidebar {
margin: 0;
padding: 0.5em 15px 15px 0;
@@ -447,3 +451,50 @@
background-color: #ccc;
color: white!important;
}
+
+table.indextable td {
+ text-align: left;
+ vertical-align: top;
+}
+
+table.indextable dl, table.indextable dd {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+table.indextable tr.pcap {
+ height: 10px;
+}
+
+table.indextable tr.cap {
+ margin-top: 10px;
+ background-color: #f2f2f2;
+}
+
+img.toggler {
+ margin-right: 3px;
+ margin-top: 3px;
+ cursor: pointer;
+}
+
+form.pfform {
+ margin: 10px 0 20px 0;
+}
+
+table.contentstable {
+ width: 90%;
+}
+
+table.contentstable p.biglink {
+ line-height: 150%;
+}
+
+a.biglink {
+ font-size: 1.3em;
+}
+
+span.linkdescr {
+ font-style: italic;
+ padding-top: 5px;
+ font-size: 90%;
+}
More information about the Python-checkins
mailing list