diff --git a/doc/extdev/appapi.rst b/doc/extdev/appapi.rst index 1df85907a..b096bca29 100644 --- a/doc/extdev/appapi.rst +++ b/doc/extdev/appapi.rst @@ -302,7 +302,7 @@ package. .. versionadded:: 0.5 -.. method:: Sphinx.add_stylesheet(filename) +.. method:: Sphinx.add_stylesheet(filename, alternate=None, title=None) Add *filename* to the list of CSS files that the default HTML template will include. Like for :meth:`add_javascript`, the filename must be relative to @@ -310,6 +310,12 @@ package. .. versionadded:: 1.0 + .. versionchanged:: 1.6 + Optional ``alternate`` and/or ``title`` attributes can be supplied with + the *alternate* (of boolean type) and *title* (a string) arguments. The + default is no title and *alternate*=``False`` (see `this explanation + `_). + .. method:: Sphinx.add_latex_package(packagename, options=None) Add *packagename* to the list of packages that LaTeX source code will include. diff --git a/doc/templating.rst b/doc/templating.rst index 41acea91b..66f72716b 100644 --- a/doc/templating.rst +++ b/doc/templating.rst @@ -200,11 +200,6 @@ Overriding works like this:: {% set script_files = script_files + ["_static/myscript.js"] %} -.. data:: css_files - - Similar to :data:`script_files`, for CSS files. - - Helper Functions ~~~~~~~~~~~~~~~~ diff --git a/sphinx/application.py b/sphinx/application.py index 7d9f84571..80c96d280 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -735,15 +735,18 @@ class Sphinx(object): StandaloneHTMLBuilder.script_files.append( posixpath.join('_static', filename)) - def add_stylesheet(self, filename): - # type: (unicode) -> None + def add_stylesheet(self, filename, alternate=False, title=None): + # type: (unicode, bool, unicode) -> None logger.debug('[app] adding stylesheet: %r', filename) from sphinx.builders.html import StandaloneHTMLBuilder - if '://' in filename: - StandaloneHTMLBuilder.css_files.append(filename) - else: - StandaloneHTMLBuilder.css_files.append( - posixpath.join('_static', filename)) + props = {'rel': 'stylesheet', + 'filename': filename, + 'title': title} # type: Dict[unicode, unicode] + if '://' not in filename: + props['filename'] = posixpath.join('_static', filename) + if alternate: + props['rel'] = 'alternate stylesheet' + StandaloneHTMLBuilder.css_files.append(props) def add_latex_package(self, packagename, options=None): # type: (unicode, unicode) -> None diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index 4aafe1f99..7bfce0ad6 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -113,8 +113,8 @@ class StandaloneHTMLBuilder(Builder): # This is a class attribute because it is mutated by Sphinx.add_javascript. script_files = ['_static/jquery.js', '_static/underscore.js', '_static/doctools.js'] # type: List[unicode] - # Dito for this one. - css_files = [] # type: List[unicode] + # Ditto for this one (Sphinx.add_stylesheet). + css_files = [] # type: List[Dict[unicode, unicode]] imgpath = None # type: unicode domain_indices = [] # type: List[Tuple[unicode, Type[Index], List[Tuple[unicode, List[List[Union[unicode, int]]]]], bool]] # NOQA diff --git a/sphinx/themes/basic/layout.html b/sphinx/themes/basic/layout.html index 587f8814b..4f1d71202 100644 --- a/sphinx/themes/basic/layout.html +++ b/sphinx/themes/basic/layout.html @@ -105,8 +105,8 @@ {%- macro css() %} - {%- for cssfile in css_files %} - + {%- for css in css_files %} + {%- endfor %} {%- endmacro %} @@ -117,9 +117,13 @@ {%- block htmltitle %} {{ title|striptags|e }}{{ titlesuffix }} {%- endblock %} + {%- block csss %} {{ css() }} + {%- endblock %} {%- if not embedded %} + {%- block scripts %} {{ script() }} + {%- endblock %} {%- if use_opensearch %} +{%- endblock %} {# do not display relbars #} {% block relbar1 %}{% endblock %} {% block relbar2 %}{% endblock %} diff --git a/tests/roots/test-stylesheets/_templates/layout.html b/tests/roots/test-stylesheets/_templates/layout.html new file mode 100644 index 000000000..f9e5a2bc9 --- /dev/null +++ b/tests/roots/test-stylesheets/_templates/layout.html @@ -0,0 +1,8 @@ +{% extends "!layout.html" %} +{%- block csss %} + {{ super() }} + + + + +{%- endblock %} diff --git a/tests/roots/test-stylesheets/conf.py b/tests/roots/test-stylesheets/conf.py new file mode 100644 index 000000000..208ca8243 --- /dev/null +++ b/tests/roots/test-stylesheets/conf.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +master_doc = 'index' +html_theme = 'classic' +templates_path = ['_templates'] + +def setup(app): + app.add_stylesheet('persistent.css') + app.add_stylesheet('default.css', title="Default") + app.add_stylesheet('alternate1.css', title="Alternate", alternate=True) + app.add_stylesheet('alternate2.css', alternate=True) + diff --git a/tests/roots/test-stylesheets/index.rst b/tests/roots/test-stylesheets/index.rst new file mode 100644 index 000000000..c5c5766ba --- /dev/null +++ b/tests/roots/test-stylesheets/index.rst @@ -0,0 +1,4 @@ +test-stylesheets +================ + +Lorem ipsum dolor diff --git a/tests/test_build_html.py b/tests/test_build_html.py index d4f37c787..4605629f7 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -1194,3 +1194,33 @@ def test_html_raw_directive(app, status, warning): # with substitution assert '

HTML: abc def ghi

' in result assert '

LaTeX: abc ghi

' in result + + +@pytest.mark.parametrize("fname,expect", flat_dict({ + 'index.html': [ + (".//link[@href='_static/persistent.css']" + "[@rel='stylesheet']", '', True), + (".//link[@href='_static/default.css']" + "[@rel='stylesheet']" + "[@title='Default']", '', True), + (".//link[@href='_static/alternate1.css']" + "[@rel='alternate stylesheet']" + "[@title='Alternate']", '', True), + (".//link[@href='_static/alternate2.css']" + "[@rel='alternate stylesheet']", '', True), + (".//link[@href='_static/more_persistent.css']" + "[@rel='stylesheet']", '', True), + (".//link[@href='_static/more_default.css']" + "[@rel='stylesheet']" + "[@title='Default']", '', True), + (".//link[@href='_static/more_alternate1.css']" + "[@rel='alternate stylesheet']" + "[@title='Alternate']", '', True), + (".//link[@href='_static/more_alternate2.css']" + "[@rel='alternate stylesheet']", '', True), + ], +})) +@pytest.mark.sphinx('html', testroot='stylesheets') +def test_alternate_stylesheets(app, cached_etree_parse, fname, expect): + app.build() + check_xpath(cached_etree_parse(app.outdir / fname), fname, *expect)