[Python-checkins] r61895 - in doctools/trunk: CHANGES doc/templating.rst sphinx/builder.py sphinx/environment.py sphinx/htmlwriter.py sphinx/latexwriter.py sphinx/util/__init__.py
georg.brandl
python-checkins at python.org
Tue Mar 25 16:22:25 CET 2008
Author: georg.brandl
Date: Tue Mar 25 16:22:25 2008
New Revision: 61895
Modified:
doctools/trunk/CHANGES
doctools/trunk/doc/templating.rst
doctools/trunk/sphinx/builder.py
doctools/trunk/sphinx/environment.py
doctools/trunk/sphinx/htmlwriter.py
doctools/trunk/sphinx/latexwriter.py
doctools/trunk/sphinx/util/__init__.py
Log:
Rebuild all HTML files in case of a template change.
Also, record image docnames in order to be able to delete image records from the env.
Modified: doctools/trunk/CHANGES
==============================================================================
--- doctools/trunk/CHANGES (original)
+++ doctools/trunk/CHANGES Tue Mar 25 16:22:25 2008
@@ -13,6 +13,8 @@
* sphinx.ext.autodoc: Record files from which docstrings are included
as dependencies.
+* sphinx.builder: Rebuild all HTML files in case of a template change.
+
* sphinx.builder: Handle unavailability of TOC relations (previous/
next chapter) more gracefully in the HTML builder.
Modified: doctools/trunk/doc/templating.rst
==============================================================================
--- doctools/trunk/doc/templating.rst (original)
+++ doctools/trunk/doc/templating.rst Tue Mar 25 16:22:25 2008
@@ -12,7 +12,7 @@
that you can overwrite only specific blocks within a template, customizing it
while also keeping the changes at a minimum.
-Inheritance is done via two directives, ``extends`` and ``block``.
+Inheritance is done via two (Jinja) directives, ``extends`` and ``block``.
.. template path
blocks
Modified: doctools/trunk/sphinx/builder.py
==============================================================================
--- doctools/trunk/sphinx/builder.py (original)
+++ doctools/trunk/sphinx/builder.py Tue Mar 25 16:22:25 2008
@@ -25,7 +25,8 @@
from docutils.readers.doctree import Reader as DoctreeReader
from sphinx import addnodes
-from sphinx.util import (get_matching_docs, ensuredir, relative_uri, SEP, os_path)
+from sphinx.util import (get_matching_docs, mtimes_of_files,
+ ensuredir, relative_uri, SEP, os_path)
from sphinx.htmlhelp import build_hhx
from sphinx.htmlwriter import HTMLWriter, HTMLTranslator, SmartyPantsHTMLTranslator
from sphinx.latexwriter import LaTeXWriter
@@ -83,6 +84,7 @@
base_templates_path = path.join(path.dirname(__file__), 'templates')
ext_templates_path = [path.join(self.srcdir, dir)
for dir in self.config.templates_path]
+ self.templates_path = [base_templates_path] + ext_templates_path
loader = SphinxFileSystemLoader(base_templates_path, ext_templates_path)
self.jinja_env = Environment(loader=loader,
# disable traceback, more likely that something
@@ -277,8 +279,9 @@
Builds standalone HTML docs.
"""
name = 'html'
-
copysource = True
+ out_suffix = '.html'
+ indexer_format = 'json'
def init(self):
"""Load templates."""
@@ -485,7 +488,7 @@
if self.env.images:
self.info(bold('copying images...'), nonl=1)
ensuredir(path.join(self.outdir, '_images'))
- for src, dest in self.env.images.iteritems():
+ for src, (_, dest) in self.env.images.iteritems():
self.info(' '+src, nonl=1)
shutil.copyfile(path.join(self.srcdir, src),
path.join(self.outdir, '_images', dest))
@@ -510,29 +513,26 @@
# dump the search index
self.handle_finish()
- # --------- these are overwritten by the Pickle builder
-
- def get_target_uri(self, docname, typ=None):
- return docname + '.html'
-
def get_outdated_docs(self):
+ template_mtime = max(mtimes_of_files(self.templates_path, '.html'))
for docname in self.env.found_docs:
- targetname = self.env.doc2path(docname, self.outdir, '.html')
+ if docname not in self.env.all_docs:
+ yield docname
+ continue
+ targetname = self.env.doc2path(docname, self.outdir, self.out_suffix)
try:
targetmtime = path.getmtime(targetname)
- except:
+ except Exception:
targetmtime = 0
- if docname not in self.env.all_docs:
+ srcmtime = max(path.getmtime(self.env.doc2path(docname)), template_mtime)
+ if srcmtime > targetmtime:
yield docname
- elif path.getmtime(self.env.doc2path(docname)) > targetmtime:
- yield docname
-
def load_indexer(self, docnames):
try:
- f = open(path.join(self.outdir, 'searchindex.json'), 'r')
+ f = open(path.join(self.outdir, 'searchindex.'+self.indexer_format), 'r')
try:
- self.indexer.load(f, 'json')
+ self.indexer.load(f, self.indexer_format)
finally:
f.close()
except (IOError, OSError):
@@ -545,6 +545,11 @@
if self.indexer is not None and title:
self.indexer.feed(pagename, title, doctree)
+ # --------- these are overwritten by the Pickle builder
+
+ def get_target_uri(self, docname, typ=None):
+ return docname + '.html'
+
def handle_page(self, pagename, addctx, templatename='page.html'):
ctx = self.globalcontext.copy()
ctx['current_page_name'] = pagename
@@ -593,20 +598,12 @@
Builds HTML docs without rendering templates.
"""
name = 'pickle'
+ out_suffix = '.fpickle'
+ indexer_format = 'pickle'
def init(self):
self.init_translator_class()
- def get_outdated_docs(self):
- for docname in self.env.found_docs:
- targetname = self.env.doc2path(docname, self.outdir, '.fpickle')
- try:
- targetmtime = path.getmtime(targetname)
- except:
- targetmtime = 0
- if path.getmtime(self.env.doc2path(docname)) > targetmtime:
- yield docname
-
def get_target_uri(self, docname, typ=None):
if docname == 'index':
return ''
@@ -614,23 +611,6 @@
return docname[:-5] # up to sep
return docname + SEP
- def load_indexer(self, docnames):
- try:
- f = open(path.join(self.outdir, 'searchindex.pickle'), 'r')
- try:
- self.indexer.load(f, 'pickle')
- finally:
- f.close()
- except (IOError, OSError):
- pass
- # delete all entries for files that will be rebuilt
- self.indexer.prune(set(self.env.all_docs) - set(docnames))
-
- def index_page(self, pagename, doctree, title):
- # only index pages with title
- if self.indexer is not None and title:
- self.indexer.feed(pagename, title, doctree)
-
def handle_page(self, pagename, ctx, templatename='page.html'):
ctx['current_page_name'] = pagename
sidebarfile = self.config.html_sidebars.get(pagename, '')
@@ -815,7 +795,7 @@
# copy image files
if self.env.images:
self.info(bold('copying images...'), nonl=1)
- for src, dest in self.env.images.iteritems():
+ for src, (_, dest) in self.env.images.iteritems():
self.info(' '+src, nonl=1)
shutil.copyfile(path.join(self.srcdir, src),
path.join(self.outdir, dest))
Modified: doctools/trunk/sphinx/environment.py
==============================================================================
--- doctools/trunk/sphinx/environment.py (original)
+++ doctools/trunk/sphinx/environment.py Tue Mar 25 16:22:25 2008
@@ -55,9 +55,9 @@
'sectsubtitle_xform': False,
}
-# This is increased every time a new environment attribute is added
-# to properly invalidate pickle files.
-ENV_VERSION = 20
+# This is increased every time an environment attribute is added
+# or changed to properly invalidate pickle files.
+ENV_VERSION = 21
def walk_depth(node, depth, maxdepth):
@@ -251,7 +251,7 @@
# (type, string, target, aliasname)
self.versionchanges = {} # version -> list of
# (type, docname, lineno, module, descname, content)
- self.images = {} # absolute path -> unique filename
+ self.images = {} # absolute path -> (docnames, unique filename)
# These are set while parsing a file
self.docname = None # current document name
@@ -287,13 +287,14 @@
self.titles.pop(docname, None)
self.tocs.pop(docname, None)
self.toc_num_entries.pop(docname, None)
+ self.filemodules.pop(docname, None)
+ self.indexentries.pop(docname, None)
for subfn, fnset in self.files_to_rebuild.iteritems():
fnset.discard(docname)
for fullname, (fn, _) in self.descrefs.items():
if fn == docname:
del self.descrefs[fullname]
- self.filemodules.pop(docname, None)
for modname, (fn, _, _, _) in self.modules.items():
if fn == docname:
del self.modules[modname]
@@ -303,10 +304,13 @@
for key, (fn, _) in self.reftargets.items():
if fn == docname:
del self.reftargets[key]
- self.indexentries.pop(docname, None)
for version, changes in self.versionchanges.items():
new = [change for change in changes if change[1] != docname]
changes[:] = new
+ for fullpath, (docs, _) in self.images.items():
+ docs.discard(docname)
+ if not docs:
+ del self.images[fullpath]
def doc2path(self, docname, base=True, suffix=None):
"""
@@ -501,6 +505,7 @@
"""
Process and rewrite image URIs.
"""
+ existing_names = set(v[1] for v in self.images.itervalues())
docdir = path.dirname(self.doc2path(docname, base=None))
for node in doctree.traverse(nodes.image):
imguri = node['uri']
@@ -513,15 +518,16 @@
if not os.access(path.join(self.srcdir, imgpath), os.R_OK):
self.warn(docname, 'Image file not readable: %s' % imguri, node.line)
if imgpath in self.images:
+ self.images[imgpath][0].add(docname)
continue
- names = set(self.images.values())
uniquename = path.basename(imgpath)
base, ext = path.splitext(uniquename)
i = 0
- while uniquename in names:
+ while uniquename in existing_names:
i += 1
uniquename = '%s%s%s' % (base, i, ext)
- self.images[imgpath] = uniquename
+ self.images[imgpath] = (set([docname]), uniquename)
+ existing_names.add(uniquename)
def process_metadata(self, docname, doctree):
"""
Modified: doctools/trunk/sphinx/htmlwriter.py
==============================================================================
--- doctools/trunk/sphinx/htmlwriter.py (original)
+++ doctools/trunk/sphinx/htmlwriter.py Tue Mar 25 16:22:25 2008
@@ -253,7 +253,7 @@
# rewrite the URI if the environment knows about it
if olduri in self.builder.env.images:
node['uri'] = path.join(self.builder.imgpath,
- self.builder.env.images[olduri])
+ self.builder.env.images[olduri][1])
BaseTranslator.visit_image(self, node)
def visit_toctree(self, node):
Modified: doctools/trunk/sphinx/latexwriter.py
==============================================================================
--- doctools/trunk/sphinx/latexwriter.py (original)
+++ doctools/trunk/sphinx/latexwriter.py Tue Mar 25 16:22:25 2008
@@ -547,7 +547,10 @@
pre.reverse()
self.body.extend(pre)
# XXX: for now, don't fiddle around with graphics formats
- uri = self.builder.env.images.get(node['uri'], node['uri'])
+ if node['uri'] in self.builder.env.images:
+ uri = self.builder.env.images[node['uri']][1]
+ else:
+ uri = node['uri']
self.body.append('\\includegraphics%s{%s}' % (include_graphics_options, uri))
self.body.extend(post)
def depart_image(self, node):
Modified: doctools/trunk/sphinx/util/__init__.py
==============================================================================
--- doctools/trunk/sphinx/util/__init__.py (original)
+++ doctools/trunk/sphinx/util/__init__.py Tue Mar 25 16:22:25 2008
@@ -54,6 +54,8 @@
"""
Get all file names (without suffix) matching a suffix in a
directory, recursively.
+
+ Exclude files in *exclude*, prune directories in *prune*.
"""
pattern = '*' + suffix
# dirname is a normalized absolute path.
@@ -75,6 +77,17 @@
yield qualified_name
+def mtimes_of_files(dirnames, suffix):
+ for dirname in dirnames:
+ for root, dirs, files in os.walk(dirname):
+ for sfile in files:
+ if sfile.endswith(suffix):
+ try:
+ yield path.getmtime(path.join(root, sfile))
+ except EnvironmentError:
+ pass
+
+
def shorten_result(text='', keywords=[], maxlen=240, fuzz=60):
if not text:
text = ''
More information about the Python-checkins
mailing list