Commits

Georg Brandl committed 66b1402

``html_static_path`` can now contain single file entries.

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 <georg@python.org>
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

Comments (0)

Files changed (11)

 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.
    .. 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

sphinx/builders/changes.py

                         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)

sphinx/builders/html.py

             if path.isfile(jsfile):
                 copyfile(jsfile, path.join(self.outdir, '_static',
                                            'translations.js'))
+        # then, copy over theme-supplied static files
+        if self.theme:
+            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
-        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)
+        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),

sphinx/util/__init__.py

         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')
         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):

tests/root/_static/README

-This placeholder file is there because Mercurial ignores empty directories.
+This whole directory is there to test html_static_path.

tests/root/_static/excluded.css

+/* This file should be excluded from being copied over */

tests/root/_static/subdir/foo.css

+/* Stub file */

tests/root/conf.py

 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'}
 

tests/root/templated.css_t

+/* Stub file, templated */
+{{ sphinx_version }}

tests/test_build_html.py

 
 import os
 import re
-import sys
 import difflib
 import htmlentitydefs
 from StringIO import StringIO
 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
                            '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'])
         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)