From c9345b33b28e38d646200e4d7986f73aa1203789 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Thu, 7 Jan 2010 16:20:52 +0100 Subject: [PATCH] ``html_static_path`` can now contain single file entries. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exclusion of static path files is not yet implemented. HG: Bitte gib eine Versions-Meldung ein. Zeilen beginnend mit 'HG:' werden entfernt. HG: Leere Versionsmeldung wird das Übernehmen abbrechen. HG: -- HG: Benutzer: Georg Brandl HG: branch 'default' HG: added tests/root/_static/excluded.css HG: added tests/root/_static/subdir/foo.css HG: added tests/root/templated.css_t HG: Geändert CHANGES HG: Geändert doc/config.rst HG: Geändert sphinx/builders/html.py HG: Geändert sphinx/util/__init__.py HG: Geändert tests/root/_static/README HG: Geändert tests/root/conf.py HG: Geändert tests/test_build_html.py --- CHANGES | 2 ++ doc/config.rst | 3 +++ sphinx/builders/changes.py | 5 ++--- sphinx/builders/html.py | 33 ++++++++++++++----------------- sphinx/util/__init__.py | 23 ++++++++++++++------- tests/root/_static/README | 2 +- tests/root/_static/excluded.css | 1 + tests/root/_static/subdir/foo.css | 1 + tests/root/conf.py | 2 +- tests/root/templated.css_t | 2 ++ tests/test_build_html.py | 19 +++++++++++++++--- 11 files changed, 60 insertions(+), 33 deletions(-) create mode 100644 tests/root/_static/excluded.css create mode 100644 tests/root/_static/subdir/foo.css create mode 100644 tests/root/templated.css_t diff --git a/CHANGES b/CHANGES index fc2a53c72..5de227f2a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ Release 1.0 (in development) ============================ +* ``html_static_path`` can now contain single file entries. + * The new universal config value ``exclude_patterns`` makes the old ``unused_docs``, ``exclude_trees`` and ``exclude_dirnames`` obsolete. diff --git a/doc/config.rst b/doc/config.rst index be956ffa3..745638c8f 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -419,6 +419,9 @@ that use Sphinx' HTMLWriter class. .. versionchanged:: 0.4 The paths in :confval:`html_static_path` can now contain subdirectories. + .. versionchanged:: 1.0 + The entries in :confval:`html_static_path` can now be single files. + .. confval:: html_last_updated_fmt If this is not the empty string, a 'Last updated on:' timestamp is inserted diff --git a/sphinx/builders/changes.py b/sphinx/builders/changes.py index 92c48f16e..3bc51d43d 100644 --- a/sphinx/builders/changes.py +++ b/sphinx/builders/changes.py @@ -139,11 +139,10 @@ class ChangesBuilder(Builder): self.theme.get_options({}).iteritems()) copy_static_entry(path.join(package_dir, 'themes', 'default', 'static', 'default.css_t'), - path.join(self.outdir, 'default.css_t'), - self, themectx) + self.outdir, self, themectx) copy_static_entry(path.join(package_dir, 'themes', 'basic', 'static', 'basic.css'), - path.join(self.outdir, 'basic.css'), self) + self.outdir, self) def hl(self, text, version): text = escape(text) diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index 0bf180b8c..46ed69917 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -556,26 +556,23 @@ class StandaloneHTMLBuilder(Builder): if path.isfile(jsfile): copyfile(jsfile, path.join(self.outdir, '_static', 'translations.js')) - # then, copy over all user-supplied static files + # then, copy over theme-supplied static files if self.theme: - staticdirnames = [path.join(themepath, 'static') - for themepath in self.theme.get_dirchain()[::-1]] - else: - staticdirnames = [] - staticdirnames += [path.join(self.confdir, spath) - for spath in self.config.html_static_path] - for staticdirname in staticdirnames: - if not path.isdir(staticdirname): - self.warn('static directory %r does not exist' % staticdirname) + themeentries = [path.join(themepath, 'static') + for themepath in self.theme.get_dirchain()[::-1]] + for entry in themeentries: + copy_static_entry(entry, path.join(self.outdir, '_static'), + self, self.globalcontext, exclude=False) + # then, copy over all user-supplied static files + staticentries = [path.join(self.confdir, spath) + for spath in self.config.html_static_path] + for entry in staticentries: + if not path.exists(entry): + self.warn('html_static_path entry %r does not exist' % entry) continue - for filename in os.listdir(staticdirname): - if filename.startswith('.'): - continue - fullname = path.join(staticdirname, filename) - targetname = path.join(self.outdir, '_static', filename) - copy_static_entry(fullname, targetname, self, - self.globalcontext) - # last, copy logo file (handled differently) + copy_static_entry(entry, path.join(self.outdir, '_static'), + self, self.globalcontext) + # last, copy logo file (handled differently XXX why?) if self.config.html_logo: logobase = path.basename(self.config.html_logo) copyfile(path.join(self.confdir, self.config.html_logo), diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py index b641a8dcd..2dbec72fe 100644 --- a/sphinx/util/__init__.py +++ b/sphinx/util/__init__.py @@ -432,9 +432,12 @@ def copyfile(source, dest): pass -def copy_static_entry(source, target, builder, context={}): +def copy_static_entry(source, targetdir, builder, context={}, + exclude=True, level=0): + # XXX: exclusion if path.isfile(source): - if source.lower().endswith('_t'): + target = path.join(targetdir, path.basename(source)) + if source.lower().endswith('_t') and builder.templates: # templated! fsrc = open(source, 'rb') fdst = open(target[:-2], 'wb') @@ -444,11 +447,17 @@ def copy_static_entry(source, target, builder, context={}): else: copyfile(source, target) elif path.isdir(source): - if source in builder.config.exclude_dirnames: - return - if path.exists(target): - shutil.rmtree(target) - shutil.copytree(source, target) + if level == 0: + for entry in os.listdir(source): + if entry.startswith('.'): + continue + copy_static_entry(path.join(source, entry), targetdir, + builder, context, level=1) + else: + target = path.join(targetdir, path.basename(source)) + if path.exists(target): + shutil.rmtree(target) + shutil.copytree(source, target) def clean_astext(node): diff --git a/tests/root/_static/README b/tests/root/_static/README index d517219be..9e1ec3569 100644 --- a/tests/root/_static/README +++ b/tests/root/_static/README @@ -1 +1 @@ -This placeholder file is there because Mercurial ignores empty directories. +This whole directory is there to test html_static_path. diff --git a/tests/root/_static/excluded.css b/tests/root/_static/excluded.css new file mode 100644 index 000000000..03c941a44 --- /dev/null +++ b/tests/root/_static/excluded.css @@ -0,0 +1 @@ +/* This file should be excluded from being copied over */ diff --git a/tests/root/_static/subdir/foo.css b/tests/root/_static/subdir/foo.css new file mode 100644 index 000000000..9427981d6 --- /dev/null +++ b/tests/root/_static/subdir/foo.css @@ -0,0 +1 @@ +/* Stub file */ diff --git a/tests/root/conf.py b/tests/root/conf.py index abd53dbed..880918771 100644 --- a/tests/root/conf.py +++ b/tests/root/conf.py @@ -33,7 +33,7 @@ html_theme_path = ['.'] html_theme_options = {'testopt': 'testoverride'} html_style = 'default.css' -html_static_path = ['_static'] +html_static_path = ['_static', 'templated.css_t'] html_last_updated_fmt = '%b %d, %Y' html_context = {'hckey': 'hcval', 'hckey_co': 'wrong_hcval_co'} diff --git a/tests/root/templated.css_t b/tests/root/templated.css_t new file mode 100644 index 000000000..72ddb807c --- /dev/null +++ b/tests/root/templated.css_t @@ -0,0 +1,2 @@ +/* Stub file, templated */ +{{ sphinx_version }} diff --git a/tests/test_build_html.py b/tests/test_build_html.py index 267950be1..f4a4aa21d 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -11,7 +11,6 @@ import os import re -import sys import difflib import htmlentitydefs from StringIO import StringIO @@ -21,8 +20,7 @@ try: except ImportError: pygments = None -from sphinx.builders.html import StandaloneHTMLBuilder - +from sphinx import __version__ from util import * from test_build import ENV_WARNINGS from etree13 import ElementTree as ET @@ -169,6 +167,19 @@ def check_xpath(etree, fname, path, check): 'path %s in %s: %r' % (check, path, fname, [node.text for node in nodes])) +def check_static_entries(outdir): + staticdir = outdir / '_static' + assert staticdir.isdir() + # a file from a directory entry in html_static_path + assert (staticdir / 'README').isfile() + # a directory from a directory entry in html_static_path + assert (staticdir / 'subdir' / 'foo.css').isfile() + # a file from a file entry in html_static_path + assert (staticdir / 'templated.css').isfile() + assert (staticdir / 'templated.css').text().splitlines()[1] == __version__ + # a file from _static, but matches exclude_patterns + ##assert not (staticdir / 'excluded.css').exists() + @gen_with_app(buildername='html', warning=html_warnfile, cleanenv=True, confoverrides={'html_context.hckey_co': 'hcval_co'}, tags=['testtag']) @@ -186,3 +197,5 @@ def test_html(app): etree = ET.parse(os.path.join(app.outdir, fname), parser) for path, check in paths.iteritems(): yield check_xpath, etree, fname, path, check + + check_static_entries(app.builder.outdir)