From eaefb883983ae37f743516787c5e73ffd12bb766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Klatt?= Date: Sun, 16 Feb 2014 13:56:54 +0100 Subject: [PATCH 01/21] extending examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit attention, see also and error directives Signed-off-by: Torbjörn Klatt --- demo/source/examples.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/demo/source/examples.rst b/demo/source/examples.rst index 06d695da..412e6be2 100644 --- a/demo/source/examples.rst +++ b/demo/source/examples.rst @@ -77,6 +77,18 @@ Danger ------ .. danger:: This is **danger**-ous. +Attention +--------- +.. attention:: This is a note. + +See Also +-------- +.. seealso:: Probably a reference. + +Error +----- +.. error:: This is a error. + Footnotes ========= I have footnoted a first item [#f1]_ and second item [#f2]_. From 77d53da884b051c51b514bf80145486a9fc6852a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Klatt?= Date: Sun, 16 Feb 2014 13:57:53 +0100 Subject: [PATCH 02/21] extending examples: autodoc/automodule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit adding an example module to show of sphinx.ext.autodoc features Signed-off-by: Torbjörn Klatt --- demo/source/conf.py | 30 +++++++++++++---- demo/source/example_module.rst | 8 +++++ demo/source/index.rst | 1 + sphinx_bootstrap_theme/example_module.py | 42 ++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 demo/source/example_module.rst create mode 100644 sphinx_bootstrap_theme/example_module.py diff --git a/demo/source/conf.py b/demo/source/conf.py index 574b75d7..2da6a396 100644 --- a/demo/source/conf.py +++ b/demo/source/conf.py @@ -17,7 +17,12 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. # Disabled: , 'sphinx.ext.intersphinx' -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode'] +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.todo', + 'sphinx.ext.ifconfig', + 'sphinx.ext.viewcode' +] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -62,15 +67,15 @@ #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +show_authors = True # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' @@ -81,8 +86,21 @@ # Enable todo output todo_include_todos = True +autoclass_content = 'class' +autodoc_member_order = 'bysource' +autodoc_default_flags = [ + 'members', + 'undoc-members', + 'private-members', + # 'special-members', + # 'inherited-members', + 'show-inheritance' +] + # -- Options for HTML output --------------------------------------------------- +html_translator_class = 'sphinx_bootstrap_theme.BootstrapTranslator' + # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'bootstrap' @@ -218,10 +236,10 @@ #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the diff --git a/demo/source/example_module.rst b/demo/source/example_module.rst new file mode 100644 index 00000000..dfc86d86 --- /dev/null +++ b/demo/source/example_module.rst @@ -0,0 +1,8 @@ +Example Module (:mod:`ExampleModule`) +===================================== + +.. automodule:: sphinx_bootstrap_theme.example_module + :members: + :undoc-members: + :private-members: + :special-members: diff --git a/demo/source/index.rst b/demo/source/index.rst index f7a7b20a..b6f3bd23 100644 --- a/demo/source/index.rst +++ b/demo/source/index.rst @@ -22,6 +22,7 @@ Setting up and using the theme. examples sidebar subdir/index + example_module.rst Development history and feature wish lists. diff --git a/sphinx_bootstrap_theme/example_module.py b/sphinx_bootstrap_theme/example_module.py new file mode 100644 index 00000000..8380466a --- /dev/null +++ b/sphinx_bootstrap_theme/example_module.py @@ -0,0 +1,42 @@ +# coding=utf-8 +""" +Example Module to show of :py:mod:`sphinx.autodoc` features with **Twitter Bootstrap**. + +.. moduleauthor:: Torbjörn Klatt +""" + + +class ExampleClass(object): + """ + Example Class + + An example class, which is documented. + """ + + def __init__(self): + """ + Constructor + + Constructs an instance of :py:class:`.Example`. + """ + self._private_variable = None + + def hello(self, greeting='Hello', name='world'): + """ + Prints a welcome message + + :param str greeting: Greeting text. + A second line. + + And second paragraph. + :param str name: Name to greet. + :returns: nothing + :raises ValueError: if ``name`` is not a string or empty + """ + if isinstance(name, str) and str != '': + print('%s %s!!' % (greeting, name)) + else: + raise ValueError("Name must not be empty.") + + +__all__ = ['ExampleClass'] From 9d4a1554dd60028940eccb58246896f197b0e850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Klatt?= Date: Sun, 16 Feb 2014 14:00:39 +0100 Subject: [PATCH 03/21] first draft of BootstrapHtmlTranslator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most sphinx and docutils directives are implemented to produce bootstrap-aware html. Some stuff needs some tweaking and cleanup (it's mostly a little too hacky). Signed-off-by: Torbjörn Klatt --- sphinx_bootstrap_theme/__init__.py | 3 + .../html_bootstrap_translator.py | 413 ++++++++++++++++++ 2 files changed, 416 insertions(+) create mode 100644 sphinx_bootstrap_theme/html_bootstrap_translator.py diff --git a/sphinx_bootstrap_theme/__init__.py b/sphinx_bootstrap_theme/__init__.py index 08736913..37e08524 100644 --- a/sphinx_bootstrap_theme/__init__.py +++ b/sphinx_bootstrap_theme/__init__.py @@ -6,7 +6,10 @@ __version__ = ".".join(str(v) for v in VERSION) __version_full__ = __version__ + def get_html_theme_path(): """Return list of HTML theme paths.""" cur_dir = os.path.abspath(os.path.dirname(__file__)) return [cur_dir] + +from sphinx_bootstrap_theme.html_bootstrap_translator import BootstrapTranslator diff --git a/sphinx_bootstrap_theme/html_bootstrap_translator.py b/sphinx_bootstrap_theme/html_bootstrap_translator.py new file mode 100644 index 00000000..99a02421 --- /dev/null +++ b/sphinx_bootstrap_theme/html_bootstrap_translator.py @@ -0,0 +1,413 @@ +# coding=utf-8 +import sys +import re + +from docutils import nodes +from docutils.writers.html4css1 import HTMLTranslator +from sphinx import addnodes +from sphinx.locale import admonitionlabels, l_ + + +admonitionlabels['todo'] = l_('Todo') + + +alert_classes = { + 'attention': 'primary', + 'caution': 'warning', + 'danger': 'danger', + 'error': 'danger', + 'hint': 'info', + 'important': 'primary', + 'note': 'info', + 'seealso': 'info', + 'tip': 'primary', + 'warning': 'warning', + 'todo': 'info' +} + + +member_types = { + 'function': 'function ', + 'method': 'method ', + 'attribute': 'attribute ', + 'staticmethod': 'static ', + 'static': 'static ' +} + + +split_parameter_types = re.compile('\sor\s|,\s') + + +class BootstrapTranslator(HTMLTranslator): + # Twitter Bootstrap is HTML5 + doctype = '\n' + + def __init__(self, builder, *args, **kwds): + # mostly copied from sphinx.writer.HTMLTranslator + HTMLTranslator.__init__(self, *args, **kwds) + self.highlighter = builder.highlighter + self.no_smarty = 0 + self.builder = builder + self.highlightlang = builder.config.highlight_language + self.highlightlinenothreshold = sys.maxsize + self.protect_literal_text = 0 + self.permalink_text = builder.config.html_add_permalinks + # support backwards-compatible setting to a bool + if not isinstance(self.permalink_text, basestring): + self.permalink_text = self.permalink_text and u'\u00B6' or '' + self.permalink_text = self.encode(self.permalink_text) + self.secnumber_suffix = builder.config.html_secnumber_suffix + self.param_separator = '' + self.optional_param_level = 0 + self._table_row_index = 0 + self.field_context = [] + self.collapse_context = [] + self.collapse_id_count = 0 + self.collapse_item_count = 0 + + def visit_comment(self, node): + self.body.append(self.starttag(node, 'div', '', CLASS='comment hidden')) + def depart_comment(self, node): + self.body.append('') + + def visit_compact_paragraph(self, node): + self.body.append(self.starttag(node, 'span', CLASS='compact-paragraph')) + def depart_compact_paragraph(self, node): + self.body.append('') + + def visit_admonition(self, node, name=''): + if name: + self.body.append(self.starttag(node, 'div', CLASS='panel panel-%s' % alert_classes[name])) + self.body.append('
%s
\n' % admonitionlabels[name]) + self.body.append(self.starttag(node, 'div', CLASS='panel-body')) + else: + self.body.append(self.starttag(node, 'div', CLASS='panel panel-default')) + def depart_admonition(self, node=None, name=''): + if name: + # closing off the additional div.panel-body + self.body.append('\n') + self.body.append('\n') + + def visit_note(self, node): + self.visit_admonition(node, 'note') + def depart_note(self, node): + self.depart_admonition(node, 'note') + + def visit_attention(self, node): + self.visit_admonition(node, 'attention') + def depart_attention(self, node): + self.depart_admonition(node, 'attention') + + def visit_warning(self, node): + self.visit_admonition(node, 'warning') + def depart_warning(self, node): + self.depart_admonition(node, 'warning') + + def visit_danger(self, node): + self.visit_admonition(node, 'danger') + def depart_danger(self, node): + self.depart_admonition(node, 'danger') + + def visit_error(self, node): + self.visit_admonition(node, 'error') + def depart_error(self, node): + self.depart_admonition(node, 'error') + + def visit_seealso(self, node): + self.visit_admonition(node, 'seealso') + def depart_seealso(self, node): + self.depart_admonition(node, 'seealso') + + def visit_todo_node(self, node): + node.remove(node[0]) # remove additional 'Todo' title node + self.visit_admonition(node, 'todo') + def depart_todo_node(self, node): + self.depart_admonition(node, 'todo') + + def visit_index(self, node): + pass + def depart_index(self, node): + pass + + def visit_bullet_list(self, node): + atts = {} + old_compact_simple = self.compact_simple + self.context.append((self.compact_simple, self.compact_p)) + self.compact_p = None + self.compact_simple = self.is_compactable(node) + if self.compact_simple and not old_compact_simple: + atts['class'] = ' simple' + self.body.append(self.starttag(node, 'ul', **atts)) + + def visit_list_item(self, node): + self.body.append(self.starttag(node, 'li', '',)) + if len(node): + node[0]['classes'].append('first') + + def visit_field_list(self, node): + self.body.append(self.starttag(node, 'div', CLASS='panel-group field-list')) + def depart_field_list(self, node): + self.body.append('\n') + + def visit_field(self, node): + _contextual_class = 'default' + _field_name_title = node[0][0].astext() + if _field_name_title == 'Raises': + _contextual_class = 'warning' + if _field_name_title == 'Return type': + _field_name_title = 'Returns' + node[0].replace(node[0][0], nodes.Text('Returns')) + if node[0][0].astext() in ['Raises']: + if node[0].__len__() == 3: + node[1][0].insert(0, nodes.Text(' -- ')) + node[1][0].insert(0, nodes.strong(text=node[0][2].astext())) + del node[0][2] + del node[0][1] + self.field_context.append(_field_name_title) + self.body.append(self.starttag(node, 'div', CLASS='panel panel-%s field' % _contextual_class)) + self.section_level += 1 + def depart_field(self, node): + self.field_context.pop() + self.section_level -= 1 + self.body.append('') + + def visit_field_name(self, node): + self.body.append(self.starttag(node, 'div', '', CLASS='panel-heading field-name')) + self.body.append('' % self.section_level) + def depart_field_name(self, node): + self.body.append('' % self.section_level) + + def visit_field_body(self, node): + self.body.append(self.starttag(node, 'div', '', CLASS='panel-body field-body')) + if self.field_context[-1] in ['Parameters']: + self._print_parameters(node) + if self.field_context[-1] in ['Raises']: + self._print_parameters(node) + def depart_field_body(self, node): + self.body.append('') + + def visit_table(self, node): + self.context.append(self.compact_p) + self.compact_p = True + classes = ' '.join(['table', self.settings.table_style]).strip() + self.body.append( + self.starttag(node, 'table', CLASS=classes)) + + def depart_table(self, node): + self.compact_p = self.context.pop() + self.body.append('\n') + + + def visit_desc(self, node): + if node['objtype'] in member_types.keys() and node['objtype'] != 'staticmethod': + node[0].insert(0, addnodes.desc_annotation(text=member_types[node['objtype']])) + self.body.append(self.starttag(node, 'div', + CLASS='panel panel-default %s' % node['objtype'])) + if node['objtype'] in ['class']: + self.collapse_context.append([node['objtype'], '%s-id%d' % (node['objtype'], self.collapse_id_count)]) + self.collapse_id_count += 1 + if len(self.collapse_context) > 0 and node['objtype'] in member_types.keys(): + self.collapse_context[-1].append('%s-id%d' % (node['objtype'], self.collapse_item_count)) + self.collapse_item_count += 1 + self.section_level += 1 + def depart_desc(self, node): + self.section_level -= 1 + if node['objtype'] in ['class']: + self.collapse_context.pop() + if len(self.collapse_context) > 0 and node['objtype'] in member_types.keys(): + self.collapse_context[-1].pop() + self.body.append('') + + def visit_desc_signature(self, node): + self.body.append(self.starttag(node, 'div', CLASS='panel-heading desc-signature')) + self.body.append('' % self.section_level) + if len(self.collapse_context) > 0 and self.collapse_context[-1][0] in ['class'] \ + and len(self.collapse_context[-1]) == 3: + self.body.append('' % (self.collapse_context[-1][1], self.collapse_context[-1][2])) + def depart_desc_signature(self, node): + if len(self.collapse_context) > 0 and self.collapse_context[-1][0] in ['class'] \ + and len(self.collapse_context[-1]) == 3: + self.body.append('') + self.body.append('' % self.section_level) + + def visit_desc_name(self, node): + self.body.append(self.starttag(node, 'tt', '', CLASS='desc-name')) + def depart_desc_name(self, node): + self.body.append('') + + def visit_desc_addname(self, node): + self.body.append(self.starttag(node, 'tt', '', CLASS='desc-addname')) + def depart_desc_addname(self, node): + self.body.append('') + + def visit_desc_parameterlist(self, node): + """ + The list of parameters in a method signature. + Including the enclosing brackets. + """ + self.body.append(self.starttag(node, 'tt', '', CLASS='desc-parameterlist')) + self.body.append('(') + self.first_param = 1 + self.optional_param_level = 0 + # How many required parameters are left. + self.required_params_left = sum([isinstance(c, addnodes.desc_parameter) + for c in node.children]) + self.param_separator = node.child_text_separator + def depart_desc_parameterlist(self, node): + self.body.append(')') + self.body.append('') + + def visit_desc_parameter(self, node): + """ + A single parameter in a method signature + """ + self.body.append(self.starttag(node, 'span', '', CLASS='desc-parameter')) + if self.first_param: + self.first_param = 0 + elif not self.required_params_left: + self.body.append(self.param_separator) + if self.optional_param_level == 0: + self.required_params_left -= 1 + if not node.hasattr('noemph'): + self.body.append('') + def depart_desc_parameter(self, node): + if not node.hasattr('noemph'): + self.body.append('') + if self.required_params_left: + self.body.append(self.param_separator) + self.body.append('') + + def visit_desc_optional(self, node): + """ + Optional parameters in a method signature. + """ + self.body.append(self.starttag(node, 'span', '', CLASS='desc-optional')) + self.optional_param_level += 1 + self.body.append('[') + def depart_desc_optional(self, node): + self.optional_param_level -= 1 + self.body.append(']') + + def visit_desc_returns(self, node): + self.body.append(self.starttag(node, 'tt', '', CLASS='desc-returns')) + def depart_desc_returns(self, node): + self.body.append('') + + def visit_desc_content(self, node): + """ + The content of a class, method or attribute. + """ + if len(self.collapse_context) > 0 and self.collapse_context[-1][0] in ['class'] \ + and len(self.collapse_context[-1]) == 2: + self.body.append('
' % self.collapse_context[-1][1]) + self.collapse_id_count += 1 + if len(self.collapse_context) > 0 and self.collapse_context[-1][0] in ['class'] \ + and len(self.collapse_context[-1]) == 3: + self.body.append('
' % (self.collapse_context[-1][2])) + self.body.append(self.starttag(node, 'div', CLASS='panel-body desc-content')) + def depart_desc_content(self, node): + if len(self.collapse_context) > 0 and self.collapse_context[-1][0] in ['class'] \ + and len(self.collapse_context[-1]) == 2: + self.body.append('
') + if len(self.collapse_context) > 0 and self.collapse_context[-1][0] in ['class'] \ + and len(self.collapse_context[-1]) == 3: + self.body.append('
') + self.body.append('') + + def visit_desc_annotation(self, node): + """ + The ``class``, ``method`` or ``attribute`` in a class signature or the + value of a class or instance attribute. + """ + _cls = 'desc-annotation' + if node[0].astext() in member_types.values(): + _cls += ' desc-annotation-type' + self.body.append(self.starttag(node, 'tt', '', CLASS=_cls)) + def depart_desc_annotation(self, node): + self.body.append('') + + def visit_toctree(self, node): + self.body.append(self.starttag(node, 'span', CLASS='toctree')) + def depart_toctree(self, node): + self.body.append('') + + # the following four methods are taken from + # http://stackoverflow.com/a/15562804 + def visit_displaymath(self, node): + import sphinx.ext.mathjax + sphinx.ext.mathjax.html_visit_displaymath(self, node) + def depart_displaymath(self, node): + return + def visit_math(self, node): + import sphinx.ext.mathjax + sphinx.ext.mathjax.html_visit_math(self, node) + def depart_math(self, node): + return + + def unknown_visit(self, node): + raise NotImplementedError('Unknown node: %s' % node.__class__.__name__) + + def _print_parameters(self, node): + self.body.append('' + '' + '' + '' + '' + '' + '') + # print("Raw: '%s'" % node.__str__()) + if isinstance(node.children[0], nodes.paragraph): + self._print_single_parameter(node[0]) + elif isinstance(node.children[0], nodes.bullet_list): + for _c in node.children[0]: + self._print_single_parameter(_c[0]) + self.body.append('
') + node.clear() + + def _print_single_parameter(self, node): + _name = None + _do_type = False + _type = None + _do_desc = False + _desc = [] + for _c in node.children: + if _do_desc: + _desc.append(_c) + elif node.children.index(_c) == 0 and isinstance(_c, nodes.strong): + _name = _c[0].astext() + elif isinstance(_c, nodes.Text): + if _do_type is False and _c.astext() == ' (': + _do_type = True + _type = '' + elif _c.astext() == ')': + _do_type = False + elif _c.astext() == ' -- ': + _do_desc = True + elif isinstance(_c, nodes.emphasis) and _do_type and _type == '': + _type = _c[0] + + self.body.append('' + '' + '
%s
' % _name + + '' + '' + '
') + + _type_str = '' + if isinstance(_type, nodes.Text): + _types = split_parameter_types.split(_type.astext()) + _type_str += '' + if len(_types) > 1: + _type_str += ', '.join(_types) + elif len(_types) == 1: + _type_str += _types[0] + _type_str += '' + self.body.append('%s
' % _type_str + + '' + '
') + + for _desc_elem in _desc: + _desc_elem.walkabout(self) + self.body.append('
' + '' + '') From d994b1b406e933853060ff6e0e0dde5d16bafc4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Klatt?= Date: Sun, 16 Feb 2014 14:01:14 +0100 Subject: [PATCH 04/21] custom javascript to patch the HTML shouldn't be needed any more MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Torbjörn Klatt --- sphinx_bootstrap_theme/bootstrap/layout.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sphinx_bootstrap_theme/bootstrap/layout.html b/sphinx_bootstrap_theme/bootstrap/layout.html index 18e16904..d2e87c4b 100644 --- a/sphinx_bootstrap_theme/bootstrap/layout.html +++ b/sphinx_bootstrap_theme/bootstrap/layout.html @@ -42,8 +42,7 @@ {% set script_files = script_files + [ '_static/js/jquery-1.11.0.min.js', '_static/js/jquery-fix.js', - '_static/bootstrap-' + bootstrap_version + '/js/bootstrap.min.js', - '_static/bootstrap-sphinx.js' + '_static/bootstrap-' + bootstrap_version + '/js/bootstrap.min.js' ] %} From 716d59c2a7f23badb7b3cb98adec4ac5dc738649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Klatt?= Date: Tue, 18 Feb 2014 10:37:30 +0100 Subject: [PATCH 05/21] add support for Notes+Examples as admonitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Notes and Examples can be rendered as admonitions automatically when using the Napoleon docstring parser. Signed-off-by: Torbjörn Klatt --- .../html_bootstrap_translator.py | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/sphinx_bootstrap_theme/html_bootstrap_translator.py b/sphinx_bootstrap_theme/html_bootstrap_translator.py index 99a02421..1f9c5812 100644 --- a/sphinx_bootstrap_theme/html_bootstrap_translator.py +++ b/sphinx_bootstrap_theme/html_bootstrap_translator.py @@ -9,6 +9,7 @@ admonitionlabels['todo'] = l_('Todo') +admonitionlabels['example'] = l_('Example') alert_classes = { @@ -22,7 +23,8 @@ 'seealso': 'info', 'tip': 'primary', 'warning': 'warning', - 'todo': 'info' + 'todo': 'info', + 'example': 'info' } @@ -76,6 +78,17 @@ def depart_compact_paragraph(self, node): self.body.append('') def visit_admonition(self, node, name=''): + if isinstance(node[0], nodes.title): + if node[0].astext() in ['Example', 'Examples']: + del node['classes'] + del node[0] + self.context.append('example') + name = 'example' + elif node[0].astext() in ['Note', 'Notes']: + del node['classes'] + del node[0] + self.context.append('note') + name = 'note' if name: self.body.append(self.starttag(node, 'div', CLASS='panel panel-%s' % alert_classes[name])) self.body.append('
%s
\n' % admonitionlabels[name]) @@ -86,6 +99,9 @@ def depart_admonition(self, node=None, name=''): if name: # closing off the additional div.panel-body self.body.append('\n') + elif self.context[-1] in alert_classes.keys(): + self.body.append('\n') + self.context.pop() self.body.append('\n') def visit_note(self, node): @@ -118,6 +134,11 @@ def visit_seealso(self, node): def depart_seealso(self, node): self.depart_admonition(node, 'seealso') + def visit_example(self, node): + self.visit_admonition(node, 'example') + def depart_example(self, node): + self.depart_admonition(node, 'example') + def visit_todo_node(self, node): node.remove(node[0]) # remove additional 'Todo' title node self.visit_admonition(node, 'todo') @@ -365,6 +386,7 @@ def _print_parameters(self, node): node.clear() def _print_single_parameter(self, node): + _do_name = True _name = None _do_type = False _type = None @@ -373,15 +395,18 @@ def _print_single_parameter(self, node): for _c in node.children: if _do_desc: _desc.append(_c) - elif node.children.index(_c) == 0 and isinstance(_c, nodes.strong): + elif _do_name and node.children.index(_c) == 0 and isinstance(_c, (nodes.strong, nodes.literal)): _name = _c[0].astext() + _do_name = False elif isinstance(_c, nodes.Text): if _do_type is False and _c.astext() == ' (': _do_type = True _type = '' elif _c.astext() == ')': _do_type = False - elif _c.astext() == ' -- ': + elif _c.astext().startswith(' -- '): + if len(_c.replace(' -- ', '', 1)) > 0: + _desc.append(nodes.Text(_c.replace(' -- ', '', 1))) _do_desc = True elif isinstance(_c, nodes.emphasis) and _do_type and _type == '': _type = _c[0] From 46180c2520f25ad02bdb97d5ffa6edc11e451482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Klatt?= Date: Tue, 18 Feb 2014 11:19:33 +0100 Subject: [PATCH 06/21] fix admonition heading level; blockquote footer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit also annotation style in member signatures Signed-off-by: Torbjörn Klatt --- .../html_bootstrap_translator.py | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/sphinx_bootstrap_theme/html_bootstrap_translator.py b/sphinx_bootstrap_theme/html_bootstrap_translator.py index 1f9c5812..0471cb79 100644 --- a/sphinx_bootstrap_theme/html_bootstrap_translator.py +++ b/sphinx_bootstrap_theme/html_bootstrap_translator.py @@ -77,6 +77,20 @@ def visit_compact_paragraph(self, node): def depart_compact_paragraph(self, node): self.body.append('') + def visit_attribution(self, node): + if isinstance(node.parent, nodes.block_quote): + self.body.append(self.starttag(node, 'footer')) + else: + prefix, suffix = self.attribution_formats[self.settings.attribution] + self.context.append(suffix) + self.body.append(self.starttag(node, 'p', prefix, CLASS='attribution')) + + def depart_attribution(self, node): + if isinstance(node.parent, nodes.block_quote): + self.body.append("\n") + else: + self.body.append(self.context.pop() + '

\n') + def visit_admonition(self, node, name=''): if isinstance(node[0], nodes.title): if node[0].astext() in ['Example', 'Examples']: @@ -91,7 +105,12 @@ def visit_admonition(self, node, name=''): name = 'note' if name: self.body.append(self.starttag(node, 'div', CLASS='panel panel-%s' % alert_classes[name])) - self.body.append('
%s
\n' % admonitionlabels[name]) + self.section_level += 1 + self.body.append( + '
%s
\n' % + (self.section_level, admonitionlabels[name], self.section_level) + ) + self.section_level -= 1 self.body.append(self.starttag(node, 'div', CLASS='panel-body')) else: self.body.append(self.starttag(node, 'div', CLASS='panel panel-default')) @@ -342,7 +361,7 @@ def visit_desc_annotation(self, node): """ _cls = 'desc-annotation' if node[0].astext() in member_types.values(): - _cls += ' desc-annotation-type' + _cls += ' desc-annotation-type text-muted' self.body.append(self.starttag(node, 'tt', '', CLASS=_cls)) def depart_desc_annotation(self, node): self.body.append('') From d3e58b0bcab6e953205ec95aa39d37176f084e36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Klatt?= Date: Tue, 18 Feb 2014 16:25:44 +0100 Subject: [PATCH 07/21] fix display of return values for Napoleon parser output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Torbjörn Klatt --- .../html_bootstrap_translator.py | 73 +++++++++++++------ 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/sphinx_bootstrap_theme/html_bootstrap_translator.py b/sphinx_bootstrap_theme/html_bootstrap_translator.py index 0471cb79..a3568f89 100644 --- a/sphinx_bootstrap_theme/html_bootstrap_translator.py +++ b/sphinx_bootstrap_theme/html_bootstrap_translator.py @@ -38,6 +38,7 @@ split_parameter_types = re.compile('\sor\s|,\s') +parameter_desc_start = re.compile('^[\s]--[\s]') class BootstrapTranslator(HTMLTranslator): @@ -189,14 +190,31 @@ def visit_field_list(self, node): def depart_field_list(self, node): self.body.append('\n') + def _fixup_return_type(self, node): + if node[0].astext() == 'Returns': + _return = node + _this_index = node.parent.index(node) + + if len(node.parent.children) > _this_index + 1: + if node.parent[_this_index + 1][0].astext() == 'Return type': + _rtype = node.parent[_this_index + 1] + _rtype_new = [nodes.Text(' (')] + if isinstance(_rtype[1][0], nodes.paragraph): + for elem in _rtype[1][0]: + _rtype_new.append(elem.deepcopy()) + _rtype_new.append(nodes.Text(')')) + _return[1][0].insert(1, _rtype_new) + def visit_field(self, node): + if node[0][0].astext() == 'Return type': + # return type should be handelt by _fixup_return_type on 'Returns' nodes + raise nodes.SkipNode + _contextual_class = 'default' + self._fixup_return_type(node) _field_name_title = node[0][0].astext() if _field_name_title == 'Raises': _contextual_class = 'warning' - if _field_name_title == 'Return type': - _field_name_title = 'Returns' - node[0].replace(node[0][0], nodes.Text('Returns')) if node[0][0].astext() in ['Raises']: if node[0].__len__() == 3: node[1][0].insert(0, nodes.Text(' -- ')) @@ -219,9 +237,7 @@ def depart_field_name(self, node): def visit_field_body(self, node): self.body.append(self.starttag(node, 'div', '', CLASS='panel-body field-body')) - if self.field_context[-1] in ['Parameters']: - self._print_parameters(node) - if self.field_context[-1] in ['Raises']: + if self.field_context[-1] in ['Parameters', 'Raises', 'Returns']: self._print_parameters(node) def depart_field_body(self, node): self.body.append('') @@ -395,7 +411,9 @@ def _print_parameters(self, node): '' '' '') - # print("Raw: '%s'" % node.__str__()) + + # if self.field_context[-1] in ['Returns']: + # print("\n\nRaw %s: '%s'" % (self.field_context[-1], node.__str__())) if isinstance(node.children[0], nodes.paragraph): self._print_single_parameter(node[0]) elif isinstance(node.children[0], nodes.bullet_list): @@ -408,7 +426,7 @@ def _print_single_parameter(self, node): _do_name = True _name = None _do_type = False - _type = None + _types = [] _do_desc = False _desc = [] for _c in node.children: @@ -421,14 +439,19 @@ def _print_single_parameter(self, node): if _do_type is False and _c.astext() == ' (': _do_type = True _type = '' - elif _c.astext() == ')': + if _c.astext() == ')': + _c.replace(')', '', 1) _do_type = False - elif _c.astext().startswith(' -- '): - if len(_c.replace(' -- ', '', 1)) > 0: - _desc.append(nodes.Text(_c.replace(' -- ', '', 1))) + if parameter_desc_start.search(_c.astext()) is not None: + _d = parameter_desc_start.findall(_c.astext()) + if len(re.sub(parameter_desc_start, '', _c.__str__(), count=1).strip()) > 0: + _desc.append(nodes.Text(re.sub(parameter_desc_start, '', _c.__str__(), count=1))) _do_desc = True - elif isinstance(_c, nodes.emphasis) and _do_type and _type == '': - _type = _c[0] + elif isinstance(_c, (nodes.emphasis, nodes.literal, nodes.reference)) and _do_type: + if isinstance(_c, (nodes.emphasis, nodes.literal)): + _types.append(_c[0]) + else: + _types.append(_c) self.body.append('' '' @@ -437,16 +460,18 @@ def _print_single_parameter(self, node): '' '
') - _type_str = '' - if isinstance(_type, nodes.Text): - _types = split_parameter_types.split(_type.astext()) - _type_str += '' - if len(_types) > 1: - _type_str += ', '.join(_types) - elif len(_types) == 1: - _type_str += _types[0] - _type_str += '' - self.body.append('%s
' % _type_str + + print("Types: %s" % _types) + for _ti in range(0, len(_types)): + if len(_types) > 1 and _ti > 0: + self.body.append(', ') + self.body.append('') + if isinstance(_types[_ti], nodes.reference): + _types[_ti].walkabout(self) + else: + self.body.append(_types[_ti].astext()) + self.body.append('') + + self.body.append('' '' '
') From fad612a5ff0c21a1afaca4f24222223d4f29fb06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Klatt?= Date: Wed, 19 Feb 2014 09:47:28 +0100 Subject: [PATCH 08/21] fixup return type descriptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Torbjörn Klatt --- .../html_bootstrap_translator.py | 104 +++++++++++++----- 1 file changed, 74 insertions(+), 30 deletions(-) diff --git a/sphinx_bootstrap_theme/html_bootstrap_translator.py b/sphinx_bootstrap_theme/html_bootstrap_translator.py index a3568f89..dd0f940d 100644 --- a/sphinx_bootstrap_theme/html_bootstrap_translator.py +++ b/sphinx_bootstrap_theme/html_bootstrap_translator.py @@ -38,7 +38,6 @@ split_parameter_types = re.compile('\sor\s|,\s') -parameter_desc_start = re.compile('^[\s]--[\s]') class BootstrapTranslator(HTMLTranslator): @@ -185,6 +184,9 @@ def visit_list_item(self, node): if len(node): node[0]['classes'].append('first') + def visit_definition_list(self, node): + self.body.append(self.starttag(node, 'dl', CLASS='dl-horizontal')) + def visit_field_list(self, node): self.body.append(self.starttag(node, 'div', CLASS='panel-group field-list')) def depart_field_list(self, node): @@ -192,7 +194,6 @@ def depart_field_list(self, node): def _fixup_return_type(self, node): if node[0].astext() == 'Returns': - _return = node _this_index = node.parent.index(node) if len(node.parent.children) > _this_index + 1: @@ -203,11 +204,30 @@ def _fixup_return_type(self, node): for elem in _rtype[1][0]: _rtype_new.append(elem.deepcopy()) _rtype_new.append(nodes.Text(')')) - _return[1][0].insert(1, _rtype_new) + _strongs = node.traverse(condition=nodes.strong) + + if len(_strongs) > 0: + _return_name = _strongs[0] + _return_para = _return_name.parent + _first_strong_id_in_its_parent = _return_para.index(_strongs[0]) + _return_para.insert(_first_strong_id_in_its_parent + 1, _rtype_new) + + if isinstance(_return_para, nodes.paragraph) \ + and isinstance(_return_para.parent, nodes.paragraph): + _return_para_parent = _return_para.parent + if len(_return_para_parent) > 1 \ + and isinstance(_return_para_parent[1], (nodes.bullet_list, nodes.definition_list, nodes.field_list)): + _para = [] + for _p in _return_para_parent[0]: + _para.append(_p.deepcopy()) + _list = _return_para_parent[1].deepcopy() + _return_para_parent.clear() + _return_para_parent.extend(_para) + _return_para_parent.append(_list) def visit_field(self, node): if node[0][0].astext() == 'Return type': - # return type should be handelt by _fixup_return_type on 'Returns' nodes + # return type should be handled by _fixup_return_type on 'Returns' nodes raise nodes.SkipNode _contextual_class = 'default' @@ -253,7 +273,6 @@ def depart_table(self, node): self.compact_p = self.context.pop() self.body.append('\n') - def visit_desc(self, node): if node['objtype'] in member_types.keys() and node['objtype'] != 'staticmethod': node[0].insert(0, addnodes.desc_annotation(text=member_types[node['objtype']])) @@ -406,23 +425,30 @@ def unknown_visit(self, node): def _print_parameters(self, node): self.body.append('' '' - '' - '' - '' + '' + '' + '' '' '') - # if self.field_context[-1] in ['Returns']: - # print("\n\nRaw %s: '%s'" % (self.field_context[-1], node.__str__())) if isinstance(node.children[0], nodes.paragraph): + if self.field_context[-1] in ['Raises']: + if len(node.children) > 1: + if isinstance(node[1], nodes.bullet_list): + node[0].append(node[1].deepcopy()) + node.remove(node[1]) + self._print_single_parameter(node[0]) elif isinstance(node.children[0], nodes.bullet_list): + first = True for _c in node.children[0]: - self._print_single_parameter(_c[0]) + self._print_single_parameter(_c[0], first=first) + if first: + first = False self.body.append('
') node.clear() - def _print_single_parameter(self, node): + def _print_single_parameter(self, node, first=False): _do_name = True _name = None _do_type = False @@ -438,42 +464,60 @@ def _print_single_parameter(self, node): elif isinstance(_c, nodes.Text): if _do_type is False and _c.astext() == ' (': _do_type = True - _type = '' if _c.astext() == ')': _c.replace(')', '', 1) _do_type = False - if parameter_desc_start.search(_c.astext()) is not None: - _d = parameter_desc_start.findall(_c.astext()) - if len(re.sub(parameter_desc_start, '', _c.__str__(), count=1).strip()) > 0: - _desc.append(nodes.Text(re.sub(parameter_desc_start, '', _c.__str__(), count=1))) + if _c.astext() in [' -- ', ' --'] or _c.astext().find(' --') != -1: + if len(_c.astext().replace(' --', '', 1).lstrip()) > 0: + _desc.append(nodes.Text(_c.astext().replace(' --', '', 1).lstrip())) _do_desc = True + if ' of ' in _c.astext() and _do_type: + _types.append(_c) elif isinstance(_c, (nodes.emphasis, nodes.literal, nodes.reference)) and _do_type: if isinstance(_c, (nodes.emphasis, nodes.literal)): _types.append(_c[0]) else: _types.append(_c) + _cls = 'parameter-name' + if first: + _cls += ' first-parameter' self.body.append('' '' - '
%s
' % _name + - '' + '
%s
' % (_cls, _name)) + _cls = 'parameter-type' + if first: + _cls += ' first-parameter' + self.body.append('' '' - '
') - - print("Types: %s" % _types) + '
' % _cls) + _of_type = False for _ti in range(0, len(_types)): - if len(_types) > 1 and _ti > 0: - self.body.append(', ') - self.body.append('') - if isinstance(_types[_ti], nodes.reference): - _types[_ti].walkabout(self) - else: + if _types[_ti].astext() == ' of ': self.body.append(_types[_ti].astext()) - self.body.append('') + _of_type = True + else: + if len(_types) > 1 and _ti > 0 and not _of_type: + self.body.append(', ') + if _of_type: + _of_type = False + self.body.append('') + if isinstance(_types[_ti], nodes.reference): + if isinstance(_types[_ti][0], nodes.literal): + _type = nodes.Text(_types[_ti][0].astext()) + _types[_ti].clear() + _types[_ti].append(_type) + _types[_ti].walkabout(self) + else: + self.body.append(_types[_ti].astext()) + self.body.append('') + _cls = 'parameter-desc' + if first: + _cls += ' first-parameter' self.body.append('
' '' - '
') + '
' % _cls) for _desc_elem in _desc: _desc_elem.walkabout(self) From 7852aa38743662e52ff3f27587e7dd26aa09c08e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Klatt?= Date: Wed, 19 Feb 2014 09:54:47 +0100 Subject: [PATCH 09/21] Revert "custom javascript to patch the HTML shouldn't be needed any more" This reverts commit d994b1b406e933853060ff6e0e0dde5d16bafc4c. --- sphinx_bootstrap_theme/bootstrap/layout.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sphinx_bootstrap_theme/bootstrap/layout.html b/sphinx_bootstrap_theme/bootstrap/layout.html index d2e87c4b..18e16904 100644 --- a/sphinx_bootstrap_theme/bootstrap/layout.html +++ b/sphinx_bootstrap_theme/bootstrap/layout.html @@ -42,7 +42,8 @@ {% set script_files = script_files + [ '_static/js/jquery-1.11.0.min.js', '_static/js/jquery-fix.js', - '_static/bootstrap-' + bootstrap_version + '/js/bootstrap.min.js' + '_static/bootstrap-' + bootstrap_version + '/js/bootstrap.min.js', + '_static/bootstrap-sphinx.js' ] %} From a9c161a4a4b1652bd8618e2ba563c8bc9c34bbdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Klatt?= Date: Thu, 20 Feb 2014 08:17:48 +0100 Subject: [PATCH 10/21] add Font Awesome for better icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Torbjörn Klatt --- .../font-awesome-4.0.3/css/font-awesome.css | 1338 +++++++++++++++++ .../css/font-awesome.min.css | 4 + .../font-awesome-4.0.3/fonts/FontAwesome.otf | Bin 0 -> 62856 bytes .../fonts/fontawesome-webfont.eot | Bin 0 -> 38205 bytes .../fonts/fontawesome-webfont.svg | 414 +++++ .../fonts/fontawesome-webfont.ttf | Bin 0 -> 80652 bytes .../fonts/fontawesome-webfont.woff | Bin 0 -> 44432 bytes 7 files changed, 1756 insertions(+) create mode 100644 sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/css/font-awesome.css create mode 100644 sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/css/font-awesome.min.css create mode 100644 sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/fonts/FontAwesome.otf create mode 100755 sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/fonts/fontawesome-webfont.eot create mode 100755 sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/fonts/fontawesome-webfont.svg create mode 100755 sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/fonts/fontawesome-webfont.ttf create mode 100755 sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/fonts/fontawesome-webfont.woff diff --git a/sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/css/font-awesome.css b/sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/css/font-awesome.css new file mode 100644 index 00000000..048cff97 --- /dev/null +++ b/sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/css/font-awesome.css @@ -0,0 +1,1338 @@ +/*! + * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ +/* FONT PATH + * -------------------------- */ +@font-face { + font-family: 'FontAwesome'; + src: url('../fonts/fontawesome-webfont.eot?v=4.0.3'); + src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.0.3') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.0.3') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg'); + font-weight: normal; + font-style: normal; +} +.fa { + display: inline-block; + font-family: FontAwesome; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +/* makes the font 33% larger relative to the icon container */ +.fa-lg { + font-size: 1.3333333333333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fa-2x { + font-size: 2em; +} +.fa-3x { + font-size: 3em; +} +.fa-4x { + font-size: 4em; +} +.fa-5x { + font-size: 5em; +} +.fa-fw { + width: 1.2857142857142858em; + text-align: center; +} +.fa-ul { + padding-left: 0; + margin-left: 2.142857142857143em; + list-style-type: none; +} +.fa-ul > li { + position: relative; +} +.fa-li { + position: absolute; + left: -2.142857142857143em; + width: 2.142857142857143em; + top: 0.14285714285714285em; + text-align: center; +} +.fa-li.fa-lg { + left: -1.8571428571428572em; +} +.fa-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.fa.pull-left { + margin-right: .3em; +} +.fa.pull-right { + margin-left: .3em; +} +.fa-spin { + -webkit-animation: spin 2s infinite linear; + -moz-animation: spin 2s infinite linear; + -o-animation: spin 2s infinite linear; + animation: spin 2s infinite linear; +} +@-moz-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + } + 100% { + -moz-transform: rotate(359deg); + } +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + } +} +@-o-keyframes spin { + 0% { + -o-transform: rotate(0deg); + } + 100% { + -o-transform: rotate(359deg); + } +} +@-ms-keyframes spin { + 0% { + -ms-transform: rotate(0deg); + } + 100% { + -ms-transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(359deg); + } +} +.fa-rotate-90 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); + -webkit-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -ms-transform: rotate(90deg); + -o-transform: rotate(90deg); + transform: rotate(90deg); +} +.fa-rotate-180 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -webkit-transform: rotate(180deg); + -moz-transform: rotate(180deg); + -ms-transform: rotate(180deg); + -o-transform: rotate(180deg); + transform: rotate(180deg); +} +.fa-rotate-270 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + -webkit-transform: rotate(270deg); + -moz-transform: rotate(270deg); + -ms-transform: rotate(270deg); + -o-transform: rotate(270deg); + transform: rotate(270deg); +} +.fa-flip-horizontal { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); + -webkit-transform: scale(-1, 1); + -moz-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + -o-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fa-flip-vertical { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); + -webkit-transform: scale(1, -1); + -moz-transform: scale(1, -1); + -ms-transform: scale(1, -1); + -o-transform: scale(1, -1); + transform: scale(1, -1); +} +.fa-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle; +} +.fa-stack-1x, +.fa-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.fa-stack-1x { + line-height: inherit; +} +.fa-stack-2x { + font-size: 2em; +} +.fa-inverse { + color: #ffffff; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.fa-glass:before { + content: "\f000"; +} +.fa-music:before { + content: "\f001"; +} +.fa-search:before { + content: "\f002"; +} +.fa-envelope-o:before { + content: "\f003"; +} +.fa-heart:before { + content: "\f004"; +} +.fa-star:before { + content: "\f005"; +} +.fa-star-o:before { + content: "\f006"; +} +.fa-user:before { + content: "\f007"; +} +.fa-film:before { + content: "\f008"; +} +.fa-th-large:before { + content: "\f009"; +} +.fa-th:before { + content: "\f00a"; +} +.fa-th-list:before { + content: "\f00b"; +} +.fa-check:before { + content: "\f00c"; +} +.fa-times:before { + content: "\f00d"; +} +.fa-search-plus:before { + content: "\f00e"; +} +.fa-search-minus:before { + content: "\f010"; +} +.fa-power-off:before { + content: "\f011"; +} +.fa-signal:before { + content: "\f012"; +} +.fa-gear:before, +.fa-cog:before { + content: "\f013"; +} +.fa-trash-o:before { + content: "\f014"; +} +.fa-home:before { + content: "\f015"; +} +.fa-file-o:before { + content: "\f016"; +} +.fa-clock-o:before { + content: "\f017"; +} +.fa-road:before { + content: "\f018"; +} +.fa-download:before { + content: "\f019"; +} +.fa-arrow-circle-o-down:before { + content: "\f01a"; +} +.fa-arrow-circle-o-up:before { + content: "\f01b"; +} +.fa-inbox:before { + content: "\f01c"; +} +.fa-play-circle-o:before { + content: "\f01d"; +} +.fa-rotate-right:before, +.fa-repeat:before { + content: "\f01e"; +} +.fa-refresh:before { + content: "\f021"; +} +.fa-list-alt:before { + content: "\f022"; +} +.fa-lock:before { + content: "\f023"; +} +.fa-flag:before { + content: "\f024"; +} +.fa-headphones:before { + content: "\f025"; +} +.fa-volume-off:before { + content: "\f026"; +} +.fa-volume-down:before { + content: "\f027"; +} +.fa-volume-up:before { + content: "\f028"; +} +.fa-qrcode:before { + content: "\f029"; +} +.fa-barcode:before { + content: "\f02a"; +} +.fa-tag:before { + content: "\f02b"; +} +.fa-tags:before { + content: "\f02c"; +} +.fa-book:before { + content: "\f02d"; +} +.fa-bookmark:before { + content: "\f02e"; +} +.fa-print:before { + content: "\f02f"; +} +.fa-camera:before { + content: "\f030"; +} +.fa-font:before { + content: "\f031"; +} +.fa-bold:before { + content: "\f032"; +} +.fa-italic:before { + content: "\f033"; +} +.fa-text-height:before { + content: "\f034"; +} +.fa-text-width:before { + content: "\f035"; +} +.fa-align-left:before { + content: "\f036"; +} +.fa-align-center:before { + content: "\f037"; +} +.fa-align-right:before { + content: "\f038"; +} +.fa-align-justify:before { + content: "\f039"; +} +.fa-list:before { + content: "\f03a"; +} +.fa-dedent:before, +.fa-outdent:before { + content: "\f03b"; +} +.fa-indent:before { + content: "\f03c"; +} +.fa-video-camera:before { + content: "\f03d"; +} +.fa-picture-o:before { + content: "\f03e"; +} +.fa-pencil:before { + content: "\f040"; +} +.fa-map-marker:before { + content: "\f041"; +} +.fa-adjust:before { + content: "\f042"; +} +.fa-tint:before { + content: "\f043"; +} +.fa-edit:before, +.fa-pencil-square-o:before { + content: "\f044"; +} +.fa-share-square-o:before { + content: "\f045"; +} +.fa-check-square-o:before { + content: "\f046"; +} +.fa-arrows:before { + content: "\f047"; +} +.fa-step-backward:before { + content: "\f048"; +} +.fa-fast-backward:before { + content: "\f049"; +} +.fa-backward:before { + content: "\f04a"; +} +.fa-play:before { + content: "\f04b"; +} +.fa-pause:before { + content: "\f04c"; +} +.fa-stop:before { + content: "\f04d"; +} +.fa-forward:before { + content: "\f04e"; +} +.fa-fast-forward:before { + content: "\f050"; +} +.fa-step-forward:before { + content: "\f051"; +} +.fa-eject:before { + content: "\f052"; +} +.fa-chevron-left:before { + content: "\f053"; +} +.fa-chevron-right:before { + content: "\f054"; +} +.fa-plus-circle:before { + content: "\f055"; +} +.fa-minus-circle:before { + content: "\f056"; +} +.fa-times-circle:before { + content: "\f057"; +} +.fa-check-circle:before { + content: "\f058"; +} +.fa-question-circle:before { + content: "\f059"; +} +.fa-info-circle:before { + content: "\f05a"; +} +.fa-crosshairs:before { + content: "\f05b"; +} +.fa-times-circle-o:before { + content: "\f05c"; +} +.fa-check-circle-o:before { + content: "\f05d"; +} +.fa-ban:before { + content: "\f05e"; +} +.fa-arrow-left:before { + content: "\f060"; +} +.fa-arrow-right:before { + content: "\f061"; +} +.fa-arrow-up:before { + content: "\f062"; +} +.fa-arrow-down:before { + content: "\f063"; +} +.fa-mail-forward:before, +.fa-share:before { + content: "\f064"; +} +.fa-expand:before { + content: "\f065"; +} +.fa-compress:before { + content: "\f066"; +} +.fa-plus:before { + content: "\f067"; +} +.fa-minus:before { + content: "\f068"; +} +.fa-asterisk:before { + content: "\f069"; +} +.fa-exclamation-circle:before { + content: "\f06a"; +} +.fa-gift:before { + content: "\f06b"; +} +.fa-leaf:before { + content: "\f06c"; +} +.fa-fire:before { + content: "\f06d"; +} +.fa-eye:before { + content: "\f06e"; +} +.fa-eye-slash:before { + content: "\f070"; +} +.fa-warning:before, +.fa-exclamation-triangle:before { + content: "\f071"; +} +.fa-plane:before { + content: "\f072"; +} +.fa-calendar:before { + content: "\f073"; +} +.fa-random:before { + content: "\f074"; +} +.fa-comment:before { + content: "\f075"; +} +.fa-magnet:before { + content: "\f076"; +} +.fa-chevron-up:before { + content: "\f077"; +} +.fa-chevron-down:before { + content: "\f078"; +} +.fa-retweet:before { + content: "\f079"; +} +.fa-shopping-cart:before { + content: "\f07a"; +} +.fa-folder:before { + content: "\f07b"; +} +.fa-folder-open:before { + content: "\f07c"; +} +.fa-arrows-v:before { + content: "\f07d"; +} +.fa-arrows-h:before { + content: "\f07e"; +} +.fa-bar-chart-o:before { + content: "\f080"; +} +.fa-twitter-square:before { + content: "\f081"; +} +.fa-facebook-square:before { + content: "\f082"; +} +.fa-camera-retro:before { + content: "\f083"; +} +.fa-key:before { + content: "\f084"; +} +.fa-gears:before, +.fa-cogs:before { + content: "\f085"; +} +.fa-comments:before { + content: "\f086"; +} +.fa-thumbs-o-up:before { + content: "\f087"; +} +.fa-thumbs-o-down:before { + content: "\f088"; +} +.fa-star-half:before { + content: "\f089"; +} +.fa-heart-o:before { + content: "\f08a"; +} +.fa-sign-out:before { + content: "\f08b"; +} +.fa-linkedin-square:before { + content: "\f08c"; +} +.fa-thumb-tack:before { + content: "\f08d"; +} +.fa-external-link:before { + content: "\f08e"; +} +.fa-sign-in:before { + content: "\f090"; +} +.fa-trophy:before { + content: "\f091"; +} +.fa-github-square:before { + content: "\f092"; +} +.fa-upload:before { + content: "\f093"; +} +.fa-lemon-o:before { + content: "\f094"; +} +.fa-phone:before { + content: "\f095"; +} +.fa-square-o:before { + content: "\f096"; +} +.fa-bookmark-o:before { + content: "\f097"; +} +.fa-phone-square:before { + content: "\f098"; +} +.fa-twitter:before { + content: "\f099"; +} +.fa-facebook:before { + content: "\f09a"; +} +.fa-github:before { + content: "\f09b"; +} +.fa-unlock:before { + content: "\f09c"; +} +.fa-credit-card:before { + content: "\f09d"; +} +.fa-rss:before { + content: "\f09e"; +} +.fa-hdd-o:before { + content: "\f0a0"; +} +.fa-bullhorn:before { + content: "\f0a1"; +} +.fa-bell:before { + content: "\f0f3"; +} +.fa-certificate:before { + content: "\f0a3"; +} +.fa-hand-o-right:before { + content: "\f0a4"; +} +.fa-hand-o-left:before { + content: "\f0a5"; +} +.fa-hand-o-up:before { + content: "\f0a6"; +} +.fa-hand-o-down:before { + content: "\f0a7"; +} +.fa-arrow-circle-left:before { + content: "\f0a8"; +} +.fa-arrow-circle-right:before { + content: "\f0a9"; +} +.fa-arrow-circle-up:before { + content: "\f0aa"; +} +.fa-arrow-circle-down:before { + content: "\f0ab"; +} +.fa-globe:before { + content: "\f0ac"; +} +.fa-wrench:before { + content: "\f0ad"; +} +.fa-tasks:before { + content: "\f0ae"; +} +.fa-filter:before { + content: "\f0b0"; +} +.fa-briefcase:before { + content: "\f0b1"; +} +.fa-arrows-alt:before { + content: "\f0b2"; +} +.fa-group:before, +.fa-users:before { + content: "\f0c0"; +} +.fa-chain:before, +.fa-link:before { + content: "\f0c1"; +} +.fa-cloud:before { + content: "\f0c2"; +} +.fa-flask:before { + content: "\f0c3"; +} +.fa-cut:before, +.fa-scissors:before { + content: "\f0c4"; +} +.fa-copy:before, +.fa-files-o:before { + content: "\f0c5"; +} +.fa-paperclip:before { + content: "\f0c6"; +} +.fa-save:before, +.fa-floppy-o:before { + content: "\f0c7"; +} +.fa-square:before { + content: "\f0c8"; +} +.fa-bars:before { + content: "\f0c9"; +} +.fa-list-ul:before { + content: "\f0ca"; +} +.fa-list-ol:before { + content: "\f0cb"; +} +.fa-strikethrough:before { + content: "\f0cc"; +} +.fa-underline:before { + content: "\f0cd"; +} +.fa-table:before { + content: "\f0ce"; +} +.fa-magic:before { + content: "\f0d0"; +} +.fa-truck:before { + content: "\f0d1"; +} +.fa-pinterest:before { + content: "\f0d2"; +} +.fa-pinterest-square:before { + content: "\f0d3"; +} +.fa-google-plus-square:before { + content: "\f0d4"; +} +.fa-google-plus:before { + content: "\f0d5"; +} +.fa-money:before { + content: "\f0d6"; +} +.fa-caret-down:before { + content: "\f0d7"; +} +.fa-caret-up:before { + content: "\f0d8"; +} +.fa-caret-left:before { + content: "\f0d9"; +} +.fa-caret-right:before { + content: "\f0da"; +} +.fa-columns:before { + content: "\f0db"; +} +.fa-unsorted:before, +.fa-sort:before { + content: "\f0dc"; +} +.fa-sort-down:before, +.fa-sort-asc:before { + content: "\f0dd"; +} +.fa-sort-up:before, +.fa-sort-desc:before { + content: "\f0de"; +} +.fa-envelope:before { + content: "\f0e0"; +} +.fa-linkedin:before { + content: "\f0e1"; +} +.fa-rotate-left:before, +.fa-undo:before { + content: "\f0e2"; +} +.fa-legal:before, +.fa-gavel:before { + content: "\f0e3"; +} +.fa-dashboard:before, +.fa-tachometer:before { + content: "\f0e4"; +} +.fa-comment-o:before { + content: "\f0e5"; +} +.fa-comments-o:before { + content: "\f0e6"; +} +.fa-flash:before, +.fa-bolt:before { + content: "\f0e7"; +} +.fa-sitemap:before { + content: "\f0e8"; +} +.fa-umbrella:before { + content: "\f0e9"; +} +.fa-paste:before, +.fa-clipboard:before { + content: "\f0ea"; +} +.fa-lightbulb-o:before { + content: "\f0eb"; +} +.fa-exchange:before { + content: "\f0ec"; +} +.fa-cloud-download:before { + content: "\f0ed"; +} +.fa-cloud-upload:before { + content: "\f0ee"; +} +.fa-user-md:before { + content: "\f0f0"; +} +.fa-stethoscope:before { + content: "\f0f1"; +} +.fa-suitcase:before { + content: "\f0f2"; +} +.fa-bell-o:before { + content: "\f0a2"; +} +.fa-coffee:before { + content: "\f0f4"; +} +.fa-cutlery:before { + content: "\f0f5"; +} +.fa-file-text-o:before { + content: "\f0f6"; +} +.fa-building-o:before { + content: "\f0f7"; +} +.fa-hospital-o:before { + content: "\f0f8"; +} +.fa-ambulance:before { + content: "\f0f9"; +} +.fa-medkit:before { + content: "\f0fa"; +} +.fa-fighter-jet:before { + content: "\f0fb"; +} +.fa-beer:before { + content: "\f0fc"; +} +.fa-h-square:before { + content: "\f0fd"; +} +.fa-plus-square:before { + content: "\f0fe"; +} +.fa-angle-double-left:before { + content: "\f100"; +} +.fa-angle-double-right:before { + content: "\f101"; +} +.fa-angle-double-up:before { + content: "\f102"; +} +.fa-angle-double-down:before { + content: "\f103"; +} +.fa-angle-left:before { + content: "\f104"; +} +.fa-angle-right:before { + content: "\f105"; +} +.fa-angle-up:before { + content: "\f106"; +} +.fa-angle-down:before { + content: "\f107"; +} +.fa-desktop:before { + content: "\f108"; +} +.fa-laptop:before { + content: "\f109"; +} +.fa-tablet:before { + content: "\f10a"; +} +.fa-mobile-phone:before, +.fa-mobile:before { + content: "\f10b"; +} +.fa-circle-o:before { + content: "\f10c"; +} +.fa-quote-left:before { + content: "\f10d"; +} +.fa-quote-right:before { + content: "\f10e"; +} +.fa-spinner:before { + content: "\f110"; +} +.fa-circle:before { + content: "\f111"; +} +.fa-mail-reply:before, +.fa-reply:before { + content: "\f112"; +} +.fa-github-alt:before { + content: "\f113"; +} +.fa-folder-o:before { + content: "\f114"; +} +.fa-folder-open-o:before { + content: "\f115"; +} +.fa-smile-o:before { + content: "\f118"; +} +.fa-frown-o:before { + content: "\f119"; +} +.fa-meh-o:before { + content: "\f11a"; +} +.fa-gamepad:before { + content: "\f11b"; +} +.fa-keyboard-o:before { + content: "\f11c"; +} +.fa-flag-o:before { + content: "\f11d"; +} +.fa-flag-checkered:before { + content: "\f11e"; +} +.fa-terminal:before { + content: "\f120"; +} +.fa-code:before { + content: "\f121"; +} +.fa-reply-all:before { + content: "\f122"; +} +.fa-mail-reply-all:before { + content: "\f122"; +} +.fa-star-half-empty:before, +.fa-star-half-full:before, +.fa-star-half-o:before { + content: "\f123"; +} +.fa-location-arrow:before { + content: "\f124"; +} +.fa-crop:before { + content: "\f125"; +} +.fa-code-fork:before { + content: "\f126"; +} +.fa-unlink:before, +.fa-chain-broken:before { + content: "\f127"; +} +.fa-question:before { + content: "\f128"; +} +.fa-info:before { + content: "\f129"; +} +.fa-exclamation:before { + content: "\f12a"; +} +.fa-superscript:before { + content: "\f12b"; +} +.fa-subscript:before { + content: "\f12c"; +} +.fa-eraser:before { + content: "\f12d"; +} +.fa-puzzle-piece:before { + content: "\f12e"; +} +.fa-microphone:before { + content: "\f130"; +} +.fa-microphone-slash:before { + content: "\f131"; +} +.fa-shield:before { + content: "\f132"; +} +.fa-calendar-o:before { + content: "\f133"; +} +.fa-fire-extinguisher:before { + content: "\f134"; +} +.fa-rocket:before { + content: "\f135"; +} +.fa-maxcdn:before { + content: "\f136"; +} +.fa-chevron-circle-left:before { + content: "\f137"; +} +.fa-chevron-circle-right:before { + content: "\f138"; +} +.fa-chevron-circle-up:before { + content: "\f139"; +} +.fa-chevron-circle-down:before { + content: "\f13a"; +} +.fa-html5:before { + content: "\f13b"; +} +.fa-css3:before { + content: "\f13c"; +} +.fa-anchor:before { + content: "\f13d"; +} +.fa-unlock-alt:before { + content: "\f13e"; +} +.fa-bullseye:before { + content: "\f140"; +} +.fa-ellipsis-h:before { + content: "\f141"; +} +.fa-ellipsis-v:before { + content: "\f142"; +} +.fa-rss-square:before { + content: "\f143"; +} +.fa-play-circle:before { + content: "\f144"; +} +.fa-ticket:before { + content: "\f145"; +} +.fa-minus-square:before { + content: "\f146"; +} +.fa-minus-square-o:before { + content: "\f147"; +} +.fa-level-up:before { + content: "\f148"; +} +.fa-level-down:before { + content: "\f149"; +} +.fa-check-square:before { + content: "\f14a"; +} +.fa-pencil-square:before { + content: "\f14b"; +} +.fa-external-link-square:before { + content: "\f14c"; +} +.fa-share-square:before { + content: "\f14d"; +} +.fa-compass:before { + content: "\f14e"; +} +.fa-toggle-down:before, +.fa-caret-square-o-down:before { + content: "\f150"; +} +.fa-toggle-up:before, +.fa-caret-square-o-up:before { + content: "\f151"; +} +.fa-toggle-right:before, +.fa-caret-square-o-right:before { + content: "\f152"; +} +.fa-euro:before, +.fa-eur:before { + content: "\f153"; +} +.fa-gbp:before { + content: "\f154"; +} +.fa-dollar:before, +.fa-usd:before { + content: "\f155"; +} +.fa-rupee:before, +.fa-inr:before { + content: "\f156"; +} +.fa-cny:before, +.fa-rmb:before, +.fa-yen:before, +.fa-jpy:before { + content: "\f157"; +} +.fa-ruble:before, +.fa-rouble:before, +.fa-rub:before { + content: "\f158"; +} +.fa-won:before, +.fa-krw:before { + content: "\f159"; +} +.fa-bitcoin:before, +.fa-btc:before { + content: "\f15a"; +} +.fa-file:before { + content: "\f15b"; +} +.fa-file-text:before { + content: "\f15c"; +} +.fa-sort-alpha-asc:before { + content: "\f15d"; +} +.fa-sort-alpha-desc:before { + content: "\f15e"; +} +.fa-sort-amount-asc:before { + content: "\f160"; +} +.fa-sort-amount-desc:before { + content: "\f161"; +} +.fa-sort-numeric-asc:before { + content: "\f162"; +} +.fa-sort-numeric-desc:before { + content: "\f163"; +} +.fa-thumbs-up:before { + content: "\f164"; +} +.fa-thumbs-down:before { + content: "\f165"; +} +.fa-youtube-square:before { + content: "\f166"; +} +.fa-youtube:before { + content: "\f167"; +} +.fa-xing:before { + content: "\f168"; +} +.fa-xing-square:before { + content: "\f169"; +} +.fa-youtube-play:before { + content: "\f16a"; +} +.fa-dropbox:before { + content: "\f16b"; +} +.fa-stack-overflow:before { + content: "\f16c"; +} +.fa-instagram:before { + content: "\f16d"; +} +.fa-flickr:before { + content: "\f16e"; +} +.fa-adn:before { + content: "\f170"; +} +.fa-bitbucket:before { + content: "\f171"; +} +.fa-bitbucket-square:before { + content: "\f172"; +} +.fa-tumblr:before { + content: "\f173"; +} +.fa-tumblr-square:before { + content: "\f174"; +} +.fa-long-arrow-down:before { + content: "\f175"; +} +.fa-long-arrow-up:before { + content: "\f176"; +} +.fa-long-arrow-left:before { + content: "\f177"; +} +.fa-long-arrow-right:before { + content: "\f178"; +} +.fa-apple:before { + content: "\f179"; +} +.fa-windows:before { + content: "\f17a"; +} +.fa-android:before { + content: "\f17b"; +} +.fa-linux:before { + content: "\f17c"; +} +.fa-dribbble:before { + content: "\f17d"; +} +.fa-skype:before { + content: "\f17e"; +} +.fa-foursquare:before { + content: "\f180"; +} +.fa-trello:before { + content: "\f181"; +} +.fa-female:before { + content: "\f182"; +} +.fa-male:before { + content: "\f183"; +} +.fa-gittip:before { + content: "\f184"; +} +.fa-sun-o:before { + content: "\f185"; +} +.fa-moon-o:before { + content: "\f186"; +} +.fa-archive:before { + content: "\f187"; +} +.fa-bug:before { + content: "\f188"; +} +.fa-vk:before { + content: "\f189"; +} +.fa-weibo:before { + content: "\f18a"; +} +.fa-renren:before { + content: "\f18b"; +} +.fa-pagelines:before { + content: "\f18c"; +} +.fa-stack-exchange:before { + content: "\f18d"; +} +.fa-arrow-circle-o-right:before { + content: "\f18e"; +} +.fa-arrow-circle-o-left:before { + content: "\f190"; +} +.fa-toggle-left:before, +.fa-caret-square-o-left:before { + content: "\f191"; +} +.fa-dot-circle-o:before { + content: "\f192"; +} +.fa-wheelchair:before { + content: "\f193"; +} +.fa-vimeo-square:before { + content: "\f194"; +} +.fa-turkish-lira:before, +.fa-try:before { + content: "\f195"; +} +.fa-plus-square-o:before { + content: "\f196"; +} diff --git a/sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/css/font-awesome.min.css b/sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/css/font-awesome.min.css new file mode 100644 index 00000000..449d6ac5 --- /dev/null +++ b/sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.0.3');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.0.3') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.0.3') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.3333333333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857142858em;text-align:center}.fa-ul{padding-left:0;margin-left:2.142857142857143em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.142857142857143em;width:2.142857142857143em;top:.14285714285714285em;text-align:center}.fa-li.fa-lg{left:-1.8571428571428572em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0,mirror=1);-webkit-transform:scale(-1,1);-moz-transform:scale(-1,1);-ms-transform:scale(-1,1);-o-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2,mirror=1);-webkit-transform:scale(1,-1);-moz-transform:scale(1,-1);-ms-transform:scale(1,-1);-o-transform:scale(1,-1);transform:scale(1,-1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-asc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-desc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-reply-all:before{content:"\f122"}.fa-mail-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"} \ No newline at end of file diff --git a/sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/fonts/FontAwesome.otf b/sphinx_bootstrap_theme/bootstrap/static/font-awesome-4.0.3/fonts/FontAwesome.otf new file mode 100644 index 0000000000000000000000000000000000000000..8b0f54e47e1d356dcf1496942a50e228e0f1ee14 GIT binary patch literal 62856 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
') def visit_compact_paragraph(self, node): - self.body.append(self.starttag(node, 'span', CLASS='compact-paragraph')) + pass def depart_compact_paragraph(self, node): - self.body.append('') + pass def visit_attribution(self, node): if isinstance(node.parent, nodes.block_quote): From efeab9bed6ab213992c5dfda9786e28d825d29af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Klatt?= Date: Thu, 20 Feb 2014 08:24:14 +0100 Subject: [PATCH 12/21] make the navbar hidden for print MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Torbjörn Klatt --- sphinx_bootstrap_theme/bootstrap/navbar.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinx_bootstrap_theme/bootstrap/navbar.html b/sphinx_bootstrap_theme/bootstrap/navbar.html index d0bc85aa..f6953999 100644 --- a/sphinx_bootstrap_theme/bootstrap/navbar.html +++ b/sphinx_bootstrap_theme/bootstrap/navbar.html @@ -1,4 +1,4 @@ - ' % self.section_level) + # overridden def visit_field_body(self, node): - self.body.append(self.starttag(node, 'div', '', CLASS='panel-body field-body')) + self.body.append( + self.starttag(node, 'div', '', CLASS='panel-body field-body')) if self.field_context[-1] in ['Parameters', 'Raises', 'Returns']: self._print_parameters(node) + + # overridden def depart_field_body(self, node): self.body.append('
') + # overridden def visit_table(self, node): self.context.append(self.compact_p) self.compact_p = True @@ -269,58 +409,80 @@ def visit_table(self, node): self.body.append( self.starttag(node, 'table', CLASS=classes)) + # overridden def depart_table(self, node): self.compact_p = self.context.pop() self.body.append('\n') def visit_desc(self, node): - if node['objtype'] in member_types.keys() and node['objtype'] != 'staticmethod': - node[0].insert(0, addnodes.desc_annotation(text=member_types[node['objtype']])) - self.body.append(self.starttag(node, 'div', - CLASS='panel panel-default %s' % node['objtype'])) + if node['objtype'] in member_types.keys() \ + and node['objtype'] != 'staticmethod': + node[0].insert(0, + addnodes + .desc_annotation(text=member_types[node['objtype']])) + self.body.append( + self.starttag(node, 'div', + CLASS='panel panel-default %s' % node['objtype'])) if node['objtype'] in ['class']: - self.collapse_context.append([node['objtype'], '%s-id%d' % (node['objtype'], self.collapse_id_count)]) + self.collapse_context.append([node['objtype'], + '%s-id%d' % (node['objtype'], + self.collapse_id_count)]) self.collapse_id_count += 1 - if len(self.collapse_context) > 0 and node['objtype'] in member_types.keys(): - self.collapse_context[-1].append('%s-id%d' % (node['objtype'], self.collapse_item_count)) + if len(self.collapse_context) > 0 \ + and node['objtype'] in member_types.keys(): + self.collapse_context[-1]\ + .append('%s-id%d' % (node['objtype'], self.collapse_item_count)) self.collapse_item_count += 1 self.section_level += 1 + def depart_desc(self, node): self.section_level -= 1 if node['objtype'] in ['class']: self.collapse_context.pop() - if len(self.collapse_context) > 0 and node['objtype'] in member_types.keys(): + if len(self.collapse_context) > 0 \ + and node['objtype'] in member_types.keys(): self.collapse_context[-1].pop() self.body.append('
') def visit_desc_signature(self, node): - self.body.append(self.starttag(node, 'div', CLASS='panel-heading desc-signature')) + self.body.append( + self.starttag(node, 'div', CLASS='panel-heading desc-signature')) self.body.append('' % self.section_level) - if len(self.collapse_context) > 0 and self.collapse_context[-1][0] in ['class'] \ + if len(self.collapse_context) > 0 \ + and self.collapse_context[-1][0] in ['class'] \ and len(self.collapse_context[-1]) == 3: - self.body.append('' % (self.collapse_context[-1][1], self.collapse_context[-1][2])) + self.body.append( + '' % self.collapse_context[-1][2]) + def depart_desc_signature(self, node): - if len(self.collapse_context) > 0 and self.collapse_context[-1][0] in ['class'] \ + if len(self.collapse_context) > 0 \ + and self.collapse_context[-1][0] in ['class'] \ and len(self.collapse_context[-1]) == 3: self.body.append('') self.body.append('
' % self.section_level) def visit_desc_name(self, node): self.body.append(self.starttag(node, 'tt', '', CLASS='desc-name')) + def depart_desc_name(self, node): self.body.append('') def visit_desc_addname(self, node): - self.body.append(self.starttag(node, 'tt', '', CLASS='desc-addname')) + self.body.append( + self.starttag(node, 'tt', '', CLASS='desc-addname')) + self.body.append('') + def depart_desc_addname(self, node): - self.body.append('') + self.body.append('') def visit_desc_parameterlist(self, node): - """ - The list of parameters in a method signature. + """The list of parameters in a method signature. Including the enclosing brackets. """ - self.body.append(self.starttag(node, 'tt', '', CLASS='desc-parameterlist')) + self.body.append( + self.starttag(node, 'tt', '', CLASS='desc-parameterlist')) self.body.append('(') self.first_param = 1 self.optional_param_level = 0 @@ -328,15 +490,16 @@ def visit_desc_parameterlist(self, node): self.required_params_left = sum([isinstance(c, addnodes.desc_parameter) for c in node.children]) self.param_separator = node.child_text_separator + def depart_desc_parameterlist(self, node): self.body.append(')') self.body.append('') def visit_desc_parameter(self, node): + """A single parameter in a method signature """ - A single parameter in a method signature - """ - self.body.append(self.starttag(node, 'span', '', CLASS='desc-parameter')) + self.body.append( + self.starttag(node, 'span', '', CLASS='desc-parameter')) if self.first_param: self.first_param = 0 elif not self.required_params_left: @@ -345,6 +508,7 @@ def visit_desc_parameter(self, node): self.required_params_left -= 1 if not node.hasattr('noemph'): self.body.append('') + def depart_desc_parameter(self, node): if not node.hasattr('noemph'): self.body.append('') @@ -353,56 +517,69 @@ def depart_desc_parameter(self, node): self.body.append('') def visit_desc_optional(self, node): - """ - Optional parameters in a method signature. + """Optional parameters in a method signature. """ self.body.append(self.starttag(node, 'span', '', CLASS='desc-optional')) self.optional_param_level += 1 self.body.append('[') + def depart_desc_optional(self, node): self.optional_param_level -= 1 self.body.append(']') def visit_desc_returns(self, node): self.body.append(self.starttag(node, 'tt', '', CLASS='desc-returns')) + def depart_desc_returns(self, node): self.body.append('') def visit_desc_content(self, node): + """The content of a class, method or attribute. """ - The content of a class, method or attribute. - """ - if len(self.collapse_context) > 0 and self.collapse_context[-1][0] in ['class'] \ + if len(self.collapse_context) > 0 \ + and self.collapse_context[-1][0] in ['class'] \ and len(self.collapse_context[-1]) == 2: - self.body.append('
' % self.collapse_context[-1][1]) + self.body.append( + '
' % self.collapse_context[-1][1]) self.collapse_id_count += 1 - if len(self.collapse_context) > 0 and self.collapse_context[-1][0] in ['class'] \ + + if len(self.collapse_context) > 0 \ + and self.collapse_context[-1][0] in ['class'] \ and len(self.collapse_context[-1]) == 3: - self.body.append('
' % (self.collapse_context[-1][2])) - self.body.append(self.starttag(node, 'div', CLASS='panel-body desc-content')) + self.body.append( + '
') + self.body.append( + self.starttag(node, 'div', CLASS='panel-body desc-content')) + def depart_desc_content(self, node): - if len(self.collapse_context) > 0 and self.collapse_context[-1][0] in ['class'] \ + if len(self.collapse_context) > 0 \ + and self.collapse_context[-1][0] in ['class'] \ and len(self.collapse_context[-1]) == 2: self.body.append('
') - if len(self.collapse_context) > 0 and self.collapse_context[-1][0] in ['class'] \ + + if len(self.collapse_context) > 0 \ + and self.collapse_context[-1][0] in ['class'] \ and len(self.collapse_context[-1]) == 3: self.body.append('
') self.body.append('
') def visit_desc_annotation(self, node): + """Annotations in object signatures. + + This is either the ``class``, ``method`` or ``attribute`` identifier or + the value of module or class attributes. """ - The ``class``, ``method`` or ``attribute`` in a class signature or the - value of a class or instance attribute. - """ - _cls = 'desc-annotation' - if node[0].astext() in member_types.values(): - _cls += ' desc-annotation-type text-muted' - self.body.append(self.starttag(node, 'tt', '', CLASS=_cls)) + self.body.append( + self.starttag(node, 'tt', '', CLASS='desc-annotation text-muted')) + def depart_desc_annotation(self, node): self.body.append('') def visit_toctree(self, node): self.body.append(self.starttag(node, 'span', CLASS='toctree')) + def depart_toctree(self, node): self.body.append('') @@ -411,14 +588,20 @@ def depart_toctree(self, node): def visit_displaymath(self, node): import sphinx.ext.mathjax sphinx.ext.mathjax.html_visit_displaymath(self, node) + def depart_displaymath(self, node): return + + # overridden def visit_math(self, node): import sphinx.ext.mathjax sphinx.ext.mathjax.html_visit_math(self, node) + + # overridden def depart_math(self, node): return + # overridden def unknown_visit(self, node): raise NotImplementedError('Unknown node: %s' % node.__class__.__name__) @@ -458,22 +641,31 @@ def _print_single_parameter(self, node, first=False): for _c in node.children: if _do_desc: _desc.append(_c) - elif _do_name and node.children.index(_c) == 0 and isinstance(_c, (nodes.strong, nodes.literal)): + + elif _do_name and node.children.index(_c) == 0 \ + and isinstance(_c, (nodes.strong, nodes.literal)): _name = _c[0].astext() _do_name = False + elif isinstance(_c, nodes.Text): if _do_type is False and _c.astext() == ' (': _do_type = True if _c.astext() == ')': _c.replace(')', '', 1) _do_type = False - if _c.astext() in [' -- ', ' --'] or _c.astext().find(' --') != -1: + if _c.astext() in [' -- ', ' --'] \ + or _c.astext().find(' --') != -1: if len(_c.astext().replace(' --', '', 1).lstrip()) > 0: - _desc.append(nodes.Text(_c.astext().replace(' --', '', 1).lstrip())) + _desc.append( + nodes.Text( + _c.astext().replace(' --', '', 1).lstrip())) _do_desc = True if ' of ' in _c.astext() and _do_type: _types.append(_c) - elif isinstance(_c, (nodes.emphasis, nodes.literal, nodes.reference)) and _do_type: + + elif isinstance(_c, (nodes.emphasis, nodes.literal, + nodes.reference)) \ + and _do_type: if isinstance(_c, (nodes.emphasis, nodes.literal)): _types.append(_c[0]) else: @@ -482,9 +674,10 @@ def _print_single_parameter(self, node, first=False): _cls = 'parameter-name' if first: _cls += ' first-parameter' - self.body.append('' - '' - '
%s
' % (_cls, _name)) + self.body.append( + '' + '' + '
%s
' % (_cls, _name)) _cls = 'parameter-type' if first: _cls += ' first-parameter' From 010dc90b4fe99f7646939b85e1837d5ccf064e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Klatt?= Date: Fri, 21 Feb 2014 10:26:25 +0100 Subject: [PATCH 21/21] some adjustments to fix up BS 2.x styling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the most ugliest styling errors/flaws with BS2 should be fixed now Signed-off-by: Torbjörn Klatt --- sphinx_bootstrap_theme/bootstrap/layout.html | 103 ++++++++++++------ .../bootstrap/navbar-2.html | 5 - .../bootstrap/static/bootstrap-sphinx.css_t | 11 ++ .../bootstrap/static/bootswatch-2.3.2/img | 1 + .../html_bootstrap_translator.py | 44 +++++--- 5 files changed, 109 insertions(+), 55 deletions(-) create mode 120000 sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/img diff --git a/sphinx_bootstrap_theme/bootstrap/layout.html b/sphinx_bootstrap_theme/bootstrap/layout.html index 482e52a7..993d5381 100644 --- a/sphinx_bootstrap_theme/bootstrap/layout.html +++ b/sphinx_bootstrap_theme/bootstrap/layout.html @@ -105,7 +105,7 @@ {%- block content %} {{ navBar() }}
-
+
{%- block sidebar1 %}{{ bsidebar() }}{% endblock %}
{% block body %}{% endblock %} @@ -117,41 +117,76 @@ {%- block footer %}