[Python-checkins] r62705 - in doctools/trunk: CHANGES doc/concepts.rst sphinx/directives.py sphinx/static/sphinxdoc.css sphinx/util/__init__.py
georg.brandl
python-checkins at python.org
Sun May 4 18:57:16 CEST 2008
Author: georg.brandl
Date: Sun May 4 18:57:15 2008
New Revision: 62705
Log:
Add globbing-style toctree entries.
Modified:
doctools/trunk/CHANGES
doctools/trunk/doc/concepts.rst
doctools/trunk/sphinx/directives.py
doctools/trunk/sphinx/static/sphinxdoc.css
doctools/trunk/sphinx/util/__init__.py
Modified: doctools/trunk/CHANGES
==============================================================================
--- doctools/trunk/CHANGES (original)
+++ doctools/trunk/CHANGES Sun May 4 18:57:15 2008
@@ -4,9 +4,11 @@
New features added
------------------
+* The ``toctree`` directive now supports a ``glob`` option that allows
+ glob-style entries in the content.
+
* If the `pygments_style` config value contains a dot it's treated as the
import path of a custom Pygments style class.
-* autodoc detects descriptors properly now
* A new config value, `exclude_dirs`, can be used to exclude whole
directories from the search for source files.
@@ -36,6 +38,8 @@
and index file. Remove two remaining instances of hard-coded
"documentation".
+* sphinx.ext.autodoc: descriptors are detected properly now.
+
* Lots of little fixes to the LaTeX output and style.
* Fix OpenSearch template and make template URL absolute. The
Modified: doctools/trunk/doc/concepts.rst
==============================================================================
--- doctools/trunk/doc/concepts.rst (original)
+++ doctools/trunk/doc/concepts.rst Sun May 4 18:57:15 2008
@@ -70,18 +70,36 @@
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.
+
+ You can use "globbing" in toctree directives, by giving the ``glob`` flag
+ option. All entries are then matched against the list of available
+ documents, and matches are inserted into the list alphabetically. Example::
+
+ .. toctree::
+ :glob:
+
+ intro*
+ recipe/*
+ *
+
+ This includes first all documents whose names start with ``intro``, then all
+ documents in the ``recipe`` folder, then all remaining documents (except the
+ one containing the directive, of course.) [#]_
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
+ explicitly exclude documents from building, 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
as a "full table of contents" if you don't give a ``maxdepth`` option.
+ .. versionchanged:: 0.2.1
+ Added "globbing" option.
+
Special names
-------------
@@ -110,3 +128,11 @@
Though only few such names are currently used by Sphinx, you should not create
documents or document-containing directories with such names. (Using ``_`` as
a prefix for a custom template directory is fine.)
+
+
+.. rubric:: Footnotes
+
+.. [#] A note on available globbing syntax: you can use the standard shell
+ constructs ``*``, ``?``, ``[...]`` and ``[!...]`` with the feature that
+ these all don't match slashes. A double star ``**`` can be used to match
+ any sequence of characters *including* slashes.
Modified: doctools/trunk/sphinx/directives.py
==============================================================================
--- doctools/trunk/sphinx/directives.py (original)
+++ doctools/trunk/sphinx/directives.py Sun May 4 18:57:15 2008
@@ -19,6 +19,7 @@
from docutils.parsers.rst import directives
from sphinx import addnodes
+from sphinx.util import patfilter
from sphinx.roles import caption_ref_re
from sphinx.util.compat import make_admonition
@@ -650,28 +651,46 @@
env = state.document.settings.env
suffix = env.config.source_suffix
dirname = posixpath.dirname(env.docname)
+ glob = 'glob' in options
ret = []
subnode = addnodes.toctree()
includefiles = []
includetitles = {}
- for docname in content:
- if not docname:
+ all_docnames = env.found_docs.copy()
+ # don't add the currently visited file in catch-all patterns
+ all_docnames.remove(env.docname)
+ for entry in content:
+ if not entry:
continue
- # look for explicit titles and documents ("Some Title <document>").
- m = caption_ref_re.match(docname)
- if m:
- docname = m.group(2)
- includetitles[docname] = m.group(1)
- # absolutize filenames, remove suffixes
- if docname.endswith(suffix):
- docname = docname[:-len(suffix)]
- docname = posixpath.normpath(posixpath.join(dirname, docname))
- if docname not in env.found_docs:
- ret.append(state.document.reporter.warning(
- 'toctree references unknown document %r' % docname, line=lineno))
+ if not glob:
+ # look for explicit titles and documents ("Some Title <document>").
+ m = caption_ref_re.match(entry)
+ if m:
+ docname = m.group(2)
+ includetitles[docname] = m.group(1)
+ else:
+ docname = entry
+ # remove suffixes (backwards compatibility)
+ if docname.endswith(suffix):
+ docname = docname[:-len(suffix)]
+ # absolutize filenames
+ docname = posixpath.normpath(posixpath.join(dirname, docname))
+ if docname not in env.found_docs:
+ ret.append(state.document.reporter.warning(
+ 'toctree references unknown document %r' % docname, line=lineno))
+ else:
+ includefiles.append(docname)
else:
- includefiles.append(docname)
+ patname = posixpath.normpath(posixpath.join(dirname, entry))
+ docnames = sorted(patfilter(all_docnames, patname))
+ for docname in docnames:
+ all_docnames.remove(docname) # don't include it again
+ includefiles.append(docname)
+ if not docnames:
+ ret.append(state.document.reporter.warning(
+ 'toctree glob pattern %r didn\'t match any documents' % entry,
+ line=lineno))
subnode['includefiles'] = includefiles
subnode['includetitles'] = includetitles
subnode['maxdepth'] = options.get('maxdepth', -1)
@@ -679,7 +698,7 @@
return ret
toctree_directive.content = 1
-toctree_directive.options = {'maxdepth': int}
+toctree_directive.options = {'maxdepth': int, 'glob': directives.flag}
directives.register_directive('toctree', toctree_directive)
Modified: doctools/trunk/sphinx/static/sphinxdoc.css
==============================================================================
--- doctools/trunk/sphinx/static/sphinxdoc.css (original)
+++ doctools/trunk/sphinx/static/sphinxdoc.css Sun May 4 18:57:15 2008
@@ -242,6 +242,10 @@
margin: 0.8em 0 0.5em 0;
}
+p.rubric {
+ font-weight: bold;
+}
+
h1 {
margin: 0;
padding: 0.7em 0 0.3em 0;
Modified: doctools/trunk/sphinx/util/__init__.py
==============================================================================
--- doctools/trunk/sphinx/util/__init__.py (original)
+++ doctools/trunk/sphinx/util/__init__.py Sun May 4 18:57:15 2008
@@ -10,6 +10,7 @@
"""
import os
+import re
import sys
import fnmatch
import tempfile
@@ -158,7 +159,7 @@
def rpartition(s, t):
- """Similar to str.rpartition from 2.5."""
+ """Similar to str.rpartition from 2.5, but doesn't return the separator."""
i = s.rfind(t)
if i != -1:
return s[:i], s[i+len(t):]
@@ -187,3 +188,64 @@
os.write(fd, exc)
os.close(fd)
return path
+
+
+def _translate_pattern(pat):
+ """
+ Translate a shell-style glob pattern to a regular expression.
+
+ Adapted from the fnmatch module, but enhanced so that single stars don't
+ match slashes.
+ """
+ i, n = 0, len(pat)
+ res = ''
+ while i < n:
+ c = pat[i]
+ i += 1
+ if c == '*':
+ if i < n and pat[i] == '*':
+ # double star matches slashes too
+ i += 1
+ res = res + '.*'
+ else:
+ # single star doesn't match slashes
+ res = res + '[^/]*'
+ elif c == '?':
+ # question mark doesn't match slashes too
+ res = res + '[^/]'
+ elif c == '[':
+ j = i
+ if j < n and pat[j] == '!':
+ j += 1
+ if j < n and pat[j] == ']':
+ j += 1
+ while j < n and pat[j] != ']':
+ j += 1
+ if j >= n:
+ res = res + '\\['
+ else:
+ stuff = pat[i:j].replace('\\', '\\\\')
+ i = j + 1
+ if stuff[0] == '!':
+ # negative pattern mustn't match slashes too
+ stuff = '^/' + stuff[1:]
+ elif stuff[0] == '^':
+ stuff = '\\' + stuff
+ res = '%s[%s]' % (res, stuff)
+ else:
+ res += re.escape(c)
+ return res + '$'
+
+
+_pat_cache = {}
+
+def patfilter(names, pat):
+ """
+ Return the subset of the list NAMES that match PAT.
+ Adapted from fnmatch module.
+ """
+ result = []
+ if not pat in _pat_cache:
+ _pat_cache[pat] = re.compile(_translate_pattern(pat))
+ match = _pat_cache[pat].match
+ return filter(match, names)
More information about the Python-checkins
mailing list