[Python-modules-commits] [cloud-sptheme] 01/10: Import cloud-sptheme_1.8.0.orig.tar.gz
Sandro Tosi
morph at moszumanska.debian.org
Tue Dec 13 12:22:13 UTC 2016
This is an automated email from the git hooks/post-receive script.
morph pushed a commit to branch master
in repository cloud-sptheme.
commit 8d2f240f4fd198977cd9c73a2b34804bada9bccb
Author: Sandro Tosi <morph at debian.org>
Date: Tue Dec 13 06:59:55 2016 -0500
Import cloud-sptheme_1.8.0.orig.tar.gz
---
CHANGES | 111 +-
MANIFEST.in | 1 +
PKG-INFO | 5 +-
cloud_sptheme.egg-info/PKG-INFO | 5 +-
cloud_sptheme.egg-info/SOURCES.txt | 30 +-
cloud_sptheme.egg-info/entry_points.txt | 3 +
cloud_sptheme.egg-info/requires.txt | 2 +-
cloud_sptheme/__init__.py | 31 +-
cloud_sptheme/ext/__init__.pyc | Bin 0 -> 413 bytes
cloud_sptheme/ext/autoattribute_search_bases.py | 62 +
cloud_sptheme/ext/autoattribute_search_bases.pyc | Bin 0 -> 1964 bytes
cloud_sptheme/ext/autodoc_sections.py | 420 +++-
cloud_sptheme/ext/autodoc_sections.pyc | Bin 0 -> 7433 bytes
cloud_sptheme/ext/docfield_markup.py | 67 +
cloud_sptheme/ext/docfield_markup.pyc | Bin 0 -> 1841 bytes
cloud_sptheme/ext/escaped_samp_literals.py | 27 +-
cloud_sptheme/ext/escaped_samp_literals.pyc | Bin 0 -> 2898 bytes
cloud_sptheme/ext/index_styling.py | 11 +-
cloud_sptheme/ext/index_styling.pyc | Bin 0 -> 2632 bytes
cloud_sptheme/ext/issue_tracker.py | 11 +-
cloud_sptheme/ext/issue_tracker.pyc | Bin 0 -> 3341 bytes
cloud_sptheme/ext/page_only.py | 191 ++
cloud_sptheme/ext/perpage.py | 5 +
cloud_sptheme/ext/relbar_toc.py | 21 +-
cloud_sptheme/ext/relbar_toc.pyc | Bin 0 -> 1407 bytes
cloud_sptheme/ext/role_index.py | 119 +
cloud_sptheme/ext/table_styling.css | 18 +
cloud_sptheme/ext/table_styling.py | 10 +-
cloud_sptheme/ext/table_styling.pyc | Bin 0 -> 7991 bytes
cloud_sptheme/make_helper.py | 44 +-
cloud_sptheme/themes/cloud/globaltoc.html | 2 +-
cloud_sptheme/themes/cloud/layout.html | 29 +-
cloud_sptheme/themes/cloud/localtoc.html | 2 +-
cloud_sptheme/themes/cloud/quicklinks.html | 2 +-
cloud_sptheme/themes/cloud/relations.html | 8 +-
cloud_sptheme/themes/cloud/static/cloud.css_t | 2482 ++++++++++++++------
cloud_sptheme/themes/cloud/static/cloud.js_t | 1420 ++++++++---
cloud_sptheme/themes/cloud/static/icon-caution.png | Bin 0 -> 1100 bytes
cloud_sptheme/themes/cloud/static/icon-danger.png | Bin 0 -> 1272 bytes
cloud_sptheme/themes/cloud/static/jquery.cookie.js | 154 +-
cloud_sptheme/themes/cloud/theme.conf | 137 +-
cloud_sptheme/themes/greencloud/theme.conf | 5 +-
cloud_sptheme/themes/magenta_cloud/theme.conf | 15 +
cloud_sptheme/themes/redcloud/static/overlay.jpg | Bin 7973 -> 0 bytes
cloud_sptheme/themes/redcloud/static/overlay.xcf | Bin 990868 -> 0 bytes
.../themes/redcloud/static/redcloud.css_t | 24 -
cloud_sptheme/themes/redcloud/theme.conf | 20 +-
cloud_sptheme/themes/solarcloud/theme.conf | 73 +
cloud_sptheme/utils.py | 81 +
docs/_static/logo-128.png | Bin 11941 -> 0 bytes
docs/_static/logo-64.png | Bin 5481 -> 0 bytes
docs/_static/longline.txt | 4 +
docs/cloud_theme.rst | 52 +-
docs/cloud_theme_test.rst | 93 +-
docs/conf.py | 5 +-
docs/contents.rst | 4 +
docs/index.rst | 18 +
docs/install.rst | 6 +-
...loud_sptheme.ext.autoattribute_search_bases.rst | 16 +
docs/lib/cloud_sptheme.ext.autodoc_sections.rst | 36 +-
docs/lib/cloud_sptheme.ext.docfield_markup.rst | 16 +
docs/lib/cloud_sptheme.ext.index_styling.rst | 2 +-
docs/lib/cloud_sptheme.ext.issue_tracker.rst | 2 +-
docs/lib/cloud_sptheme.ext.page_only.rst | 2 +
docs/lib/cloud_sptheme.ext.role_index.rst | 1 +
docs/lib/cloud_sptheme.ext.table_styling.rst | 4 +-
setup.cfg | 6 +-
setup.py | 35 +-
68 files changed, 4528 insertions(+), 1422 deletions(-)
diff --git a/CHANGES b/CHANGES
index d0c886a..099ad8a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,12 +1,120 @@
.. -*- restructuredtext -*-
+.. _whats-new:
+
===============
Release History
===============
-**1.6** (2013-12-28)
+**1.8** (2016-11-20)
+====================
+
+ * Admonitions now support "without-title" class to hide title prefix ("Note", "See also", etc)
+
+ * Added :mod:`~cloud_sptheme.ext.role_index` extension
+
+ * Added :mod:`~cloud_sptheme.ext.page_only` extension
+
+ * Fixed :mod:`~cloud_sptheme.ext.index_styling` extension to be compatible with Sphinx 1.4
+
+ * Sticky sidebar code now allows sidebar to be scrolled independantly
+ of main document -- just scroll mouse while overing over sidebar.
+
+ * Sidebar can now be viewed from mobile mode; hidden state is stored
+ independantly of large screen menu.
+
+ * ``collapsablesidebar`` flag is now ignored, sidebar is always collapsable.
+ flag will be removed in 1.9.
+
+ * A large amount of the sidebar css & js was rewritten,
+ many of the DOM classes have changed.
+
+**1.7.1** (2015-12-12)
+======================
+
+ Bugfix release
+
+ * Fixed divide-by-zero error under python 3 (:issue:`23`).
+
+ * JS url comparison code now handles ``file://`` urls (:issue:`24`).
+
+ * Now requires Sphinx >= 1.3.
+
+**1.7** (2015-07-25)
==========================
+.. note::
+
+ This theme now requires Sphinx >= 1.2 (some of the javascript code won't work
+ with the jquery version bundled in Sphinx 1.1 and earlier).
+
+New Features
+------------
+
+ * Function, class, and other object declaration now have colored backgrounds
+ (controlled by ``colored_objects`` flag).
+
+ * All python code blocks now have button to hide prompts & output text,
+ for easier copying (Adapted from python's copybutton.js) (:issue:`17`).
+
+ * Added :ref:`font sizing options <font-options>`.
+
+ * Added :ref:`document options <decor-options>` to customize look and feel.
+
+ * Added :mod:`cloud_sptheme.ext.autoattribute_search_bases` extension.
+
+ * Added :mod:`cloud_sptheme.ext.docfield_markup` extension.
+
+Other Changes
+-------------
+
+ * :mod:`~cloud_sptheme.ext.autodoc_sections` has been completely rewritten.
+ now utilitizes docutil's native RST parser, creates real section elements
+ rather than hacked up definition lists; should now handle *any* valid
+ rest directive that can be put at module-level.
+
+ * Added styling for 2nd-level section headers, and the nested section
+ headers generated by :mod:`!autodoc_sections`.
+
+ * Default font size adjusted for compactness.
+
+ * The ``popuptoc`` feature has been removed.
+ It was just too awkward to maintain the required styling.
+ May revisit in the future using a JS-based approach.
+
+ * Unified button hover look & color through relbar, sidebar, and body.
+
+ * Completely rewrote TOC highlighter code, now indicates active section,
+ and collapses inactive TOC entries that are too large.
+
+ * Makes use of Sphinx 1.2's egg entry point,
+ so :func:`~cloud_sptheme.get_theme_dir` no longer needs to be used directly.
+
+Bugfixes
+--------
+
+ * :mod:`~cloud_sptheme.ext.autodoc_sections` now monkeypatches sphinx
+ so that `:param foo:` and other fields get formatted correctly
+ when they're embedded in a nested section (:issue:`21`).
+
+ * now compatibile with Sphinx 1.3's switch from ``<tt>`` to ``<code>``
+ for literals.
+
+ * :mod:`!autodoc_sections` now monkeypatches sphinx
+ so that ``:param foo:`` and other fields get formatted correctly
+ when they're embedded in a nested section (:issue:`21`).
+
+ * :mod:`!autodoc_sections` now handles method descriptors
+ correctly (:issue:`16`).
+
+ * the sidebar collapse state is now consistent across subfolders of document
+ (:issue:`9`).
+
+ * jumping to method or attribute permalink will now highlight the object.
+
+**1.6** (2013-12-28)
+====================
+
New Features
------------
* Added ``rightsidebar`` option to base theme, ala the Sphinx default theme.
@@ -21,7 +129,6 @@ New Features
..
undocumented features:
- * ``lighter_decor``, ``beveled_decor``, and ``borderless_decor`` flags.
* :mod:`!cloud_sptheme.ext.perpage` extension.
Bugfixes
diff --git a/MANIFEST.in b/MANIFEST.in
index 7a8199f..819497d 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,5 +1,6 @@
recursive-include docs *
recursive-include cloud_sptheme/themes *
+recursive-include cloud_sptheme/ext *
include LICENSE CHANGES README
prune docs/_build
exclude .hgignore *.komodoproject
diff --git a/PKG-INFO b/PKG-INFO
index 7ff0078..0b35147 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: cloud_sptheme
-Version: 1.6
+Version: 1.8.0
Summary: a nice sphinx theme named 'Cloud', and some related extensions
Home-page: https://bitbucket.org/ecollins/cloud_sptheme
Author: Eli Collins
@@ -15,10 +15,11 @@ Description: This is a small package containing a Sphinx theme named "Cloud",
Keywords: sphinx extension theme
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
+Classifier: Framework :: Sphinx :: Extension
+Classifier: Framework :: Sphinx :: Theme
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python :: 2.5
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
diff --git a/cloud_sptheme.egg-info/PKG-INFO b/cloud_sptheme.egg-info/PKG-INFO
index b060f59..9a51024 100644
--- a/cloud_sptheme.egg-info/PKG-INFO
+++ b/cloud_sptheme.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: cloud-sptheme
-Version: 1.6
+Version: 1.8.0
Summary: a nice sphinx theme named 'Cloud', and some related extensions
Home-page: https://bitbucket.org/ecollins/cloud_sptheme
Author: Eli Collins
@@ -15,10 +15,11 @@ Description: This is a small package containing a Sphinx theme named "Cloud",
Keywords: sphinx extension theme
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
+Classifier: Framework :: Sphinx :: Extension
+Classifier: Framework :: Sphinx :: Theme
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python :: 2.5
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
diff --git a/cloud_sptheme.egg-info/SOURCES.txt b/cloud_sptheme.egg-info/SOURCES.txt
index 9312565..24d0499 100644
--- a/cloud_sptheme.egg-info/SOURCES.txt
+++ b/cloud_sptheme.egg-info/SOURCES.txt
@@ -6,20 +6,36 @@ setup.cfg
setup.py
cloud_sptheme/__init__.py
cloud_sptheme/make_helper.py
+cloud_sptheme/utils.py
cloud_sptheme.egg-info/PKG-INFO
cloud_sptheme.egg-info/SOURCES.txt
cloud_sptheme.egg-info/dependency_links.txt
+cloud_sptheme.egg-info/entry_points.txt
cloud_sptheme.egg-info/not-zip-safe
cloud_sptheme.egg-info/requires.txt
cloud_sptheme.egg-info/top_level.txt
cloud_sptheme/ext/__init__.py
+cloud_sptheme/ext/__init__.pyc
+cloud_sptheme/ext/autoattribute_search_bases.py
+cloud_sptheme/ext/autoattribute_search_bases.pyc
cloud_sptheme/ext/autodoc_sections.py
+cloud_sptheme/ext/autodoc_sections.pyc
+cloud_sptheme/ext/docfield_markup.py
+cloud_sptheme/ext/docfield_markup.pyc
cloud_sptheme/ext/escaped_samp_literals.py
+cloud_sptheme/ext/escaped_samp_literals.pyc
cloud_sptheme/ext/index_styling.py
+cloud_sptheme/ext/index_styling.pyc
cloud_sptheme/ext/issue_tracker.py
+cloud_sptheme/ext/issue_tracker.pyc
+cloud_sptheme/ext/page_only.py
cloud_sptheme/ext/perpage.py
cloud_sptheme/ext/relbar_toc.py
+cloud_sptheme/ext/relbar_toc.pyc
+cloud_sptheme/ext/role_index.py
+cloud_sptheme/ext/table_styling.css
cloud_sptheme/ext/table_styling.py
+cloud_sptheme/ext/table_styling.pyc
cloud_sptheme/themes/cloud/globaltoc.html
cloud_sptheme/themes/cloud/layout.html
cloud_sptheme/themes/cloud/localtoc.html
@@ -28,6 +44,8 @@ cloud_sptheme/themes/cloud/relations.html
cloud_sptheme/themes/cloud/theme.conf
cloud_sptheme/themes/cloud/static/cloud.css_t
cloud_sptheme/themes/cloud/static/cloud.js_t
+cloud_sptheme/themes/cloud/static/icon-caution.png
+cloud_sptheme/themes/cloud/static/icon-danger.png
cloud_sptheme/themes/cloud/static/icon-deprecated.png
cloud_sptheme/themes/cloud/static/icon-note.png
cloud_sptheme/themes/cloud/static/icon-seealso.png
@@ -35,10 +53,9 @@ cloud_sptheme/themes/cloud/static/icon-todo.png
cloud_sptheme/themes/cloud/static/icon-warning.png
cloud_sptheme/themes/cloud/static/jquery.cookie.js
cloud_sptheme/themes/greencloud/theme.conf
+cloud_sptheme/themes/magenta_cloud/theme.conf
cloud_sptheme/themes/redcloud/theme.conf
-cloud_sptheme/themes/redcloud/static/overlay.jpg
-cloud_sptheme/themes/redcloud/static/overlay.xcf
-cloud_sptheme/themes/redcloud/static/redcloud.css_t
+cloud_sptheme/themes/solarcloud/theme.conf
docs/cloud_theme.rst
docs/cloud_theme_test.rst
docs/conf.py
@@ -47,16 +64,19 @@ docs/copyright.rst
docs/history.rst
docs/index.rst
docs/install.rst
-docs/_static/logo-128.png
-docs/_static/logo-64.png
docs/_static/logo.svg
+docs/_static/longline.txt
docs/_static/masthead.png
docs/_static/masthead.svg
+docs/lib/cloud_sptheme.ext.autoattribute_search_bases.rst
docs/lib/cloud_sptheme.ext.autodoc_sections.rst
+docs/lib/cloud_sptheme.ext.docfield_markup.rst
docs/lib/cloud_sptheme.ext.escaped_samp_literals.rst
docs/lib/cloud_sptheme.ext.index_styling.rst
docs/lib/cloud_sptheme.ext.issue_tracker.rst
+docs/lib/cloud_sptheme.ext.page_only.rst
docs/lib/cloud_sptheme.ext.relbar_toc.rst
+docs/lib/cloud_sptheme.ext.role_index.rst
docs/lib/cloud_sptheme.ext.table_styling.rst
docs/lib/cloud_sptheme.make_helper.rst
docs/lib/cloud_sptheme.rst
\ No newline at end of file
diff --git a/cloud_sptheme.egg-info/entry_points.txt b/cloud_sptheme.egg-info/entry_points.txt
new file mode 100644
index 0000000..68d704b
--- /dev/null
+++ b/cloud_sptheme.egg-info/entry_points.txt
@@ -0,0 +1,3 @@
+[sphinx_themes]
+path = cloud_sptheme:get_theme_dir
+
diff --git a/cloud_sptheme.egg-info/requires.txt b/cloud_sptheme.egg-info/requires.txt
index dac9b70..3ce9efe 100644
--- a/cloud_sptheme.egg-info/requires.txt
+++ b/cloud_sptheme.egg-info/requires.txt
@@ -1 +1 @@
-sphinx>=1.1
\ No newline at end of file
+sphinx>=1.4
diff --git a/cloud_sptheme/__init__.py b/cloud_sptheme/__init__.py
index ff9acc1..d62ce10 100644
--- a/cloud_sptheme/__init__.py
+++ b/cloud_sptheme/__init__.py
@@ -24,18 +24,19 @@ __all__ = [
# internal helpers
"is_cloud_theme",
- "u",
]
#=============================================================================
# constants
#=============================================================================
-__version__ = "1.6"
+__version__ = "1.8.0"
-# names of standard cloud extensions
-# used by most cloud themes
+# names of standard cloud extensions used by most cloud themes
std_exts = [
'cloud_sptheme.ext.autodoc_sections',
+ 'cloud_sptheme.ext.autoattribute_search_bases',
+ 'cloud_sptheme.ext.docfield_markup',
+ 'cloud_sptheme.ext.escaped_samp_literals',
'cloud_sptheme.ext.index_styling',
'cloud_sptheme.ext.relbar_toc',
'cloud_sptheme.ext.table_styling',
@@ -44,7 +45,6 @@ std_exts = [
# names of all cloud extensions
all_exts = std_exts + [
'cloud_sptheme.ext.issue_tracker',
- 'cloud_sptheme.ext.escaped_samp_literals',
]
#=============================================================================
@@ -55,10 +55,10 @@ _root_dir = os.path.abspath(os.path.dirname(__file__))
def get_theme_dir():
"""Returns path to directory containing this package's Sphinx themes.
- This is designed to be used when setting the ``html_theme_path``
- option within Sphinx's ``conf.py`` file.
+ .. deprecated:: 1.7
- .. seealso:: The :ref:`Cloud Sphinx Theme <cloud-theme-usage>` for a usage example.
+ As of Sphinx 1.2, this is passed to Sphinx via a ``setup.py`` entry point,
+ and no longer needs to be included in your documentation's ``conf.py``.
"""
return os.path.join(_root_dir, "themes")
@@ -87,20 +87,5 @@ def is_cloud_theme(name):
return os.path.isfile(os.path.join(get_theme_dir(), name, "theme.conf"))
#=============================================================================
-# internal py2/3 compat helpers
-#=============================================================================
-PY2 = sys.version_info < (3,0)
-PY3 = not PY2
-if PY2:
- def u(s):
- return s.decode("unicode_escape")
- def ru(s):
- return s.decode("ascii")
-else:
- def u(s):
- return s
- ru = u
-
-#=============================================================================
# eof
#=============================================================================
diff --git a/cloud_sptheme/ext/__init__.pyc b/cloud_sptheme/ext/__init__.pyc
new file mode 100644
index 0000000..01be2ba
Binary files /dev/null and b/cloud_sptheme/ext/__init__.pyc differ
diff --git a/cloud_sptheme/ext/autoattribute_search_bases.py b/cloud_sptheme/ext/autoattribute_search_bases.py
new file mode 100644
index 0000000..2ba1462
--- /dev/null
+++ b/cloud_sptheme/ext/autoattribute_search_bases.py
@@ -0,0 +1,62 @@
+"""
+cloud_sptheme.ext.autoattribute_search_bases -- monkeypatches autodoc so ``autoattribute`` searches base classes for attr doc.
+"""
+#=============================================================================
+# imports
+#=============================================================================
+# core
+import logging; log = logging.getLogger(__name__)
+# site
+# pkg
+from cloud_sptheme import __version__
+from cloud_sptheme.utils import patchapplier, monkeypatch
+# local
+__all__ = [
+ "setup",
+]
+
+#=============================================================================
+# patch
+#=============================================================================
+ at patchapplier
+def _patch_autoattribute():
+ from sphinx.ext.autodoc import AttributeDocumenter, ModuleAnalyzer, PycodeError
+
+ @monkeypatch(AttributeDocumenter)
+ def add_content(_wrapped, self, *args, **kwds):
+ if not self._datadescriptor and self.analyzer and self.objpath:
+ attr_docs = self.analyzer.find_attr_docs()
+ key = ('.'.join(self.objpath[:-1]), self.objpath[-1])
+ if key not in attr_docs:
+ # look for parent class w/ correct attr
+ if hasattr(self.parent, "__mro__"):
+ for basecls in self.parent.__mro__[1:]:
+ try:
+ analyzer = ModuleAnalyzer.for_module(basecls.__module__)
+ base_attr_docs = analyzer.find_attr_docs()
+ except PycodeError as err:
+ continue
+ # FIXME: need qualname or equivalent for basecls
+ base_key = (basecls.__name__, self.objpath[-1])
+ if base_key in base_attr_docs:
+ # insert data into existing analyzer
+ # XXX: might be prettier way to handle this,
+ # (esp so actual source file was reported)
+ # but would have to duplicate much of add_content()
+ attr_docs[key] = base_attr_docs[base_key]
+ break
+ return _wrapped(self, *args, **kwds)
+
+#=============================================================================
+# sphinx entry point
+#=============================================================================
+def setup(app):
+ # don't apply our patch unless actually loaded by sphinx
+ _patch_autoattribute()
+
+ # identifies the version of our extension
+ return {'version': __version__}
+
+#=============================================================================
+# eoc
+#=============================================================================
diff --git a/cloud_sptheme/ext/autoattribute_search_bases.pyc b/cloud_sptheme/ext/autoattribute_search_bases.pyc
new file mode 100644
index 0000000..05787aa
Binary files /dev/null and b/cloud_sptheme/ext/autoattribute_search_bases.pyc differ
diff --git a/cloud_sptheme/ext/autodoc_sections.py b/cloud_sptheme/ext/autodoc_sections.py
index 7a8e45c..19ae99c 100644
--- a/cloud_sptheme/ext/autodoc_sections.py
+++ b/cloud_sptheme/ext/autodoc_sections.py
@@ -1,73 +1,293 @@
"""cloud_sptheme.ext.autodoc_sections - support ReST sections in docstrings"""
+#=============================================================================
+# imports
+#=============================================================================
+# core
+import inspect
import re
import logging; log = logging.getLogger(__name__)
+# site
+# pkg
+from cloud_sptheme import __version__
+from cloud_sptheme.utils import u, patchapplier, monkeypatch
+# local
+__all__ = [
+ "setup",
+]
-def indent_sections(lines, reference_prefix=''):
- "replaces any section headers with indented paragraphs"
- end = len(lines)-1
- out = []
-
- sections = []
- indent_char = ' ' * 4
- indent_level = 0
- SCHARS = '#*=-^"'
- section_chars = [""] #map of section char -> level (built up as scan progresses)
- def get_level(c):
- sc = section_chars[0]
- if c not in sc:
- sc = section_chars[0] = (sc+c)
- return sc.index(c)
- #FIXME: this doesn't detect double-barred sections
- def detect_section(idx):
- if idx == end:
- return None
- line = lines[idx].rstrip()
- if not line or line.lstrip() != line:
- return None
- next = lines[idx+1].rstrip()
- if next.lstrip() != next:
- return None
- for c in SCHARS:
- if next.startswith(c * len(line)):
- return c
- return None
- idx = 0
- lss = False #set to true last non-empty line was a section heading
- while idx <= end:
- line = lines[idx].rstrip()
- if not line:
- if not lss:
- out.append("")
- idx += 1
- continue
- new_char = detect_section(idx)
- if new_char:
- new_level = get_level(new_char)
- while sections and sections[-1] > new_level:
- sections.pop()
- if not sections or sections[-1] < new_level:
- sections.append(new_level)
- indent_level = max(0, len(sections))
- name = line.lower().strip().replace(" ", "-").replace("--", "-")
- indent = indent_char * (indent_level-1)
- out.extend([
- indent + ".. _%s:" % (reference_prefix + name),
- indent + ".. rst-class:: nested-section nested-section-%d" % (new_level+1,),
- "",
- indent + "%s\n" % line.rstrip(),
- ])
- idx += 2 #skip section header
- lss = True
- continue
- lss = False
- indent = indent_char * indent_level
- out.append(indent + line)
- idx += 1
- return out
-
-def _remove_oneline(name, lines):
- #remove one-line description from top of module, if present,
- #cause we don't want it being duplicated (should already be listed in module's header)
+#=============================================================================
+# internal helpers used for hacking up sphinx. almost ashamed to be doing this.
+#=============================================================================
+def get_caller_value(module, var, rtype=None, code=None):
+ """
+ helper which looks for nearest ancestor in call stack
+ which occurred in module, and return specified local variable.
+
+ :param module:
+ name of module to look for on stack
+
+ :param var:
+ name of local variable to return
+
+ :param rtype:
+ do optional type-check to ensure **name** has expected type.
+
+ :param code:
+ optionally match based on function name (``frame.f_code.co_name``)
+ as well as module.
+ """
+ frame = None
+ try:
+ frame = inspect.currentframe().f_back
+ while True:
+ if ((frame.f_globals.get("__name__") == module) and
+ (not code or frame.f_code.co_name == code)):
+ break
+ frame = frame.f_back
+ if not frame:
+ raise RuntimeError("couldn't find module=%r, code=%r in call stack" %
+ (module, code or '<any>'))
+ value = frame.f_locals[var]
+ if rtype and not isinstance(value, rtype):
+ raise TypeError("%s: expected a %r instance: %r" % (var, rtype, value))
+ return value
+ finally:
+ frame = None
+
+#=============================================================================
+# autodoc monkeypatches / hacks
+#=============================================================================
+ at patchapplier
+def _patch_sphinx():
+ """
+ helper which monkeypatches sphinx to install some of our hooks.
+ """
+
+ #----------------------------------------------------------------------
+ # patch document.note_implicit_target() to look for _modify_new_desc_section
+ # attribute, as signal that it should munge up node that's passed to it,
+ # to represent new description-level section, rather than document-level section.
+ # this flag is then set by RSTState.new_subsection() patch, below.
+ # NOTE: ideally, all this action could be done by a hook w/in
+ # RSTState.new_subsection(), but would have to modify source.
+ #----------------------------------------------------------------------
+ from docutils.nodes import document, make_id
+
+ @monkeypatch(document)
+ def note_implicit_target(_wrapped, self, target, *args, **kwds):
+ # use default behavior unless signal flag is set
+ entry = self._modify_new_desc_section
+ if not entry:
+ return _wrapped(self, target, *args, **kwds)
+ self._modify_new_desc_section = None
+
+ # NOTE: target should be section() node we're modifying,
+ # as we just got called from RSTState.new_subsection(),
+ # which is what sets modify_new_desc_section flag.
+ # 'entry' should be last item in memo.desc_stack
+ # (see below).
+
+ # add our custom css classes for styling
+ # NOTE: adding 'section-header' class to H<N> node,
+ # so that our css rules don't have to be duplicated for every H<N> value.
+ target['classes'].append("desc-section")
+ target['classes'].append("desc-section-%d" % entry['level'])
+ target[0]['classes'].append("section-header")
+
+ # for duration of call, modify settings.id_prefix to include
+ # decription prefix in any auto-generated ids. this helpers
+ # section names remaining unique even if used between classes
+ # (e.g. common names such as 'Constructor Options')
+ settings = self.settings
+ orig = settings.id_prefix
+ try:
+ if entry['prefix']:
+ if orig:
+ settings.id_prefix = u("%s-%s") % (settings.id_prefix, entry['prefix'])
+ else:
+ settings.id_prefix = entry['prefix']
+ return _wrapped(self, target, *args, **kwds)
+ finally:
+ settings.id_prefix = orig
+
+ document._modify_new_desc_section = None
+
+ #----------------------------------------------------------------------
+ # patch RSTState.new_subsection() to generate sections nested within
+ # a description. It reads ``memo.desc_stack`` to determine if it's within
+ # a description. If set, this attr should be a list of dicts,
+ # each entry representing a nested description (e.g. an ObjectDescription)
+ # whose content is being parsed, most recent should be last.
+ # Each entry should be a dict containing:
+ #
+ # If there are no description entries active, the normal behavior is used.
+ #
+ # Each dict should contain the following keys:
+ # * prefix -- None, or string to use as prefix for section identifiers.
+ # helps keep links unique w/in document.
+ # * signode -- signature node used to generate prefix (for debugging)
+ # * owner -- arbitary object (ObjectDescription in our case)
+ # which added this entry to list. intended as sanity check
+ # when popping entries back off stack.
+ # * level -- section level w/in declaration (autoset by code below)
+ #----------------------------------------------------------------------
+ from docutils.parsers.rst.states import RSTState
+
+ @monkeypatch(RSTState)
+ def new_subsection(_wrapped, self, *args, **kwds):
+ desc_stack = getattr(self.memo, "desc_stack", None)
+ if desc_stack:
+ # after new_subsection() creates section node,
+ # it will invoke document.note_implicit_target().
+ # setting this attr signals our monkeypatch of that method (above)
+ # to make changes to that node based on desc_stack entry.
+ # NOTE: ideally, the note_implicit_target() monkeypatch,
+ # as well as this code, would be placed inside RSTState.new_subsection(),
+ # but that would require modifying sphinx's source :(
+ entry = desc_stack[-1]
+ entry['level'] = self.memo.section_level+1 # set level w/in description
+ self.document._modify_new_desc_section = entry # enable note hack
+
+ # hand off to real method
+ return _wrapped(self, *args, **kwds)
+
+ #----------------------------------------------------------------------
+ # monkeypatch ObjectDescription.run() so that:
+ # 1. before calling state.nested_parse(), we push a desc context
+ # onto state_machine.desc_context_stack (see above).
+ # 2. when it does call state.nested_parse() the first time,
+ # ``match_titles=True`` gets set.
+ # FIXME: using a really awkward way to accomplish this :|
+ # 3. pop our context off desc_context_stack when done.
+ #----------------------------------------------------------------------
+ from sphinx.directives import ObjectDescription
+ from sphinx.addnodes import desc as DescNodeType
+
+ @monkeypatch(ObjectDescription)
+ def run(_wrapped_run, self):
+ # ObjectDescription.before_content() will be invoked right before
+ # run calls ``self.state.nested_parse()``. We take advantage of that
+ # by wrapping the instance's before_content() call so that the last
+ # thing is does is set up ``self.state`` the way we want.
+
+ # NOTE: have to patch per-instance, since subclasses that override this
+ # don't tend to invoke super()
+ @monkeypatch(self)
+ def before_content(_wrapped_before):
+ # let real method do all the setup it wants.
+ _wrapped_before()
+
+ #----------------------------------------------------------------------
+ # need to figure out prefix to prepend to our description sections,
+ # so their IDs are unique. for now, using signature node
+ # ObjectDescription.run() has finished generating right before before_content()
+ # was called. Unfortunately, it's not available via self,
+ # so we have to reach into call stack to grab it...
+ # NOTE: ideally we would do this in ObjectDescription.run().
+ #----------------------------------------------------------------------
+ node = get_caller_value("sphinx.directives", "node",
+ rtype=DescNodeType, code="run")
+ # FIXME: would like a more bullet-proof way of deriving our id prefix...
+ signode = node.children[0]
+ if signode.get("ids"):
+ base = signode['ids'][0]
+ elif signode.get("names"):
+ base = signode['names'][0]
+ else:
+ base = signode.astext()
+ prefix = re.sub("[^a-zA-Z0-9_.]+", "-", base).strip("-") + "-"
+
+ # now that we've got that info, add our description context entry
+ # to the stack
+ memo = self.state.memo
+ if not hasattr(memo, "desc_stack"):
+ memo.desc_stack = []
+ memo.desc_stack.append(dict( # see new_subsection() above for dict format
+ prefix=prefix,
+ owner=self,
+ signode=signode,
+ level=0,
+ ))
+
+ #----------------------------------------------------------------------
+ # hack up ``state.nested_parse()`` so that the next time it's called,
+ # 'match_titles=True' is set. that call should happen as soon as this
+ # function returns back to ObjectDescription.run()
+ # NOTE: ideally, we would just set match_titles=True within ObjectDescription.run()
+ #----------------------------------------------------------------------
+ state = self.state
+ if not hasattr(state, "_set_next_match_titles_flag"):
+ # state is persistent object, only want to patch it once.
+ @monkeypatch(state)
+ def nested_parse(_wrapped_parse, *args, **kwds):
+ if state._set_next_match_titles_flag:
+ kwds['match_titles'] = True
+ state._set_next_match_titles_flag = False
+ return _wrapped_parse(*args, **kwds)
+
+ # signal our hack to set match_titles
+ state._set_next_match_titles_flag = True
+
+ @monkeypatch(self)
+ def after_content(_wrapped_after):
+ # remove our description context entry
+ # NOTE: ideally would do this in ObjectDescription.run()
+ desc = self.state.memo.desc_stack.pop()
+ assert desc['owner'] is self, "sanity check failed"
+
+ # let real method do it's work
+ return _wrapped_after()
+
+ # now invoke the real run() method.
+ # as soon as it calls before_content(), our hack above will patch self.state.
+ # after before_content() returns, real run method will call self.state.nested_parse(),
+ # and invoke our patched version instead.
+ return _wrapped_run(self)
+
+ #----------------------------------------------------------------------
+ # make autodoc invoke parse_nested_section_with_titles() for ALL objects
+ # if this isn't done, autodoc generates paragraphs instead of sections.
+ # this causes all nested content to be omitted
+ # FIXME: why is the lack of this causing a problem? should track it down.
+ #----------------------------------------------------------------------
+ from sphinx.ext.autodoc import Documenter
+ Documenter.titles_allowed = True
+
+ #----------------------------------------------------------------------
+ # finally, monkeypatch DocFieldTransformer.transform_all()
+ # so that it transforms doc fields within one of our nested sections
+ # (default code only looks at top-level nodes)
+ #
+ # FIXME: find a cleaner way to do this :|
+ #----------------------------------------------------------------------
+ from sphinx.util.docfields import DocFieldTransformer
+ from docutils.nodes import section
+
+ @monkeypatch(DocFieldTransformer)
+ def transform_all(_wrapped, self, node):
+ # transform immediate node contents like normal
+ _wrapped(self, node)
+
+ # our nested sections show up as definition lists,
+ # so make sure transform_all is also invoked for the contents
+ # of any definition list
+ for child in node:
+ if isinstance(child, section):
+ _wrapped(self, child.children)
+
+ #----------------------------------------------------------------------
+ # sigh. done monkeypatching.
+ #----------------------------------------------------------------------
+
+#=============================================================================
+# docstring mangling
+#=============================================================================
+def trim_module_header(app, what, name, obj, options, lines):
+ """
+ helper to remove one-line description from top of module (if preset).
+ """
+ if what != "module":
+ return
_title_re = re.compile(r"""
^ \s*
( {0} \s* -- \s* )?
@@ -77,18 +297,58 @@ def _remove_oneline(name, lines):
if len(lines) > 1 and _title_re.match(lines[0]) and lines[1].strip() == '':
del lines[:2]
-def mangle_docstrings(app, what, name, obj, options, lines):
- if what == 'module':
- _remove_oneline(name, lines)
- elif what in ('class', 'exception', 'function', 'method'):
- name = "%s.%s" % (obj.__module__, obj.__name__)
- name = name.replace(".", "-").lower()
- lines[:] = indent_sections(lines, reference_prefix=name + "-")
- elif what in ('attribute',):
- pass
- else:
- #FIXME: handle other cases
- raise NotImplementedError("unknown node: %r %r" % (what, obj))
-
+#=============================================================================
+# sphinx extension entrypoint
+#=============================================================================
def setup(app):
- app.connect('autodoc-process-docstring', mangle_docstrings)
+ # don't patch sphinx unless this extension is actually in use
+ _patch_sphinx()
+
+ # clean up leading bit of module docstring
+ app.connect('autodoc-process-docstring', trim_module_header)
+
+ # identifies the version of our extension
+ return {'version': __version__}
+
+#=============================================================================
+# documentation helper
+#
+# NOTE: this function doesn't actually do anything,
+# it exists to test this extension's behavior as part of docs/cloud_theme_test
+#=============================================================================
+def _doctestfunc():
+ """
+ The :mod:`~cloud_sptheme.ext.autodoc_sections` extension should generate
+ nested sections as found within object docstrings.
+
+ Nested Section
+ ==============
+
+ :param arg: xxx
+
+ .. attribute:: foo
+
+ bar
+
+ These sections can in turn contain others:
+
+ Child Section
+ -------------
+
+ Which allows breaking long class docstrings up in meaningful ways.
+
+ Child Section 2
+ ---------------
+
+ And more content
+
+ Nested Section 2
+ ================
+
+ end of class
+ """
+ pass
+
+#=============================================================================
+# eof
+#=============================================================================
diff --git a/cloud_sptheme/ext/autodoc_sections.pyc b/cloud_sptheme/ext/autodoc_sections.pyc
new file mode 100644
index 0000000..18a8ac4
Binary files /dev/null and b/cloud_sptheme/ext/autodoc_sections.pyc differ
diff --git a/cloud_sptheme/ext/docfield_markup.py b/cloud_sptheme/ext/docfield_markup.py
new file mode 100644
index 0000000..3dd1c59
--- /dev/null
+++ b/cloud_sptheme/ext/docfield_markup.py
@@ -0,0 +1,67 @@
+"""
+cloud_sptheme.ext.docfield_markup -- monkeypatches sphinx to allow ``~`` in docfields.
+"""
+#=============================================================================
+# imports
+#=============================================================================
+# core
+import logging; log = logging.getLogger(__name__)
+# site
+# pkg
+from cloud_sptheme import __version__
+from cloud_sptheme.utils import patchapplier, monkeypatch
+# local
+__all__ = [
+ "setup",
+]
+
+#=============================================================================
+# patch
+#=============================================================================
+ at patchapplier
+def _patch_docfield():
+ from sphinx.util.docfields import Field, nodes, addnodes
+
+ # NOTE: would like to just wrap make_xref(), but have to override so
+ # many parts that just end up replicating all the code :(
+ # hence this ignored _wrapped() entirely
+
+ @monkeypatch(Field)
+ def make_xref(_wrapped, self, rolename, domain, target, innernode=nodes.emphasis, contnode=None):
+ # 'contnode' argument added in sphinx 1.3
+ # not sure what it does, aborting if feature is present
... 6708 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/cloud-sptheme.git
More information about the Python-modules-commits
mailing list