zzzeeksphinx-1.0.17/0000755000076500000240000000000012530636260015123 5ustar classicstaff00000000000000zzzeeksphinx-1.0.17/LICENSE0000644000076500000240000000216212444064546016137 0ustar classicstaff00000000000000This is the MIT license: http://www.opensource.org/licenses/mit-license.php Copyright (C) 2012 by Michael Bayer. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. zzzeeksphinx-1.0.17/MANIFEST.in0000644000076500000240000000013212444066555016665 0ustar classicstaff00000000000000recursive-include zzzeeksphinx *.py *.scss *.js *.conf *.mako include README* LICENSE zzzeeksphinx-1.0.17/PKG-INFO0000644000076500000240000001100012530636260016210 0ustar classicstaff00000000000000Metadata-Version: 1.1 Name: zzzeeksphinx Version: 1.0.17 Summary: Zzzeek's Sphinx Layout and Utilities. Home-page: http://bitbucket.org/zzzeek/zzzeeksphinx Author: Mike Bayer Author-email: mike@zzzcomputing.com License: MIT Description: ============= zzzeeksphinx ============= This is zzzeek's own Sphinx layout, used by SQLAlchemy. This layout is first and foremost pulled in for the SQLAlchemy documentation builds (and possibly other related projects), but is also usable as a standalone theme / utility set for any project. Feel free to fork off features from it as needed, the project here first and foremost has to work with SQLAlchemy. Features include: * Uses Mako templates instead of Jinja, for more programmatic capabilities inside of templates. * Layout includes an independently scrollable sidebar * A unique (to Sphinx) "contextual" sidebar contents that shows the current page in context with all sibling pages (like that of MySQL's docs). This is a form of TOC that Sphinx doesn't typically have a lot of capability to do (well it could, with some simple feature adds), but IMO this kind of navigation is critical for very large and nested documentation sets, so that the navbar stays relatively small yet provides context as to where you are in the docs and what else is locally available. * Modifications to autodoc which illustrate inherited classes, bases, method documentation illustrates if a method is only inherited from the base or overridden. * A "dynamic base" feature that will, under ReadTheDocs, pull in optional ``.mako`` and ``.py`` files from the website of your choice that will serve as an alternate base template and a source of extra config setup, respectively, allowing the layout to be integrated into the layout of an external site when viewing on the web. * A "viewsource" extension that can provide highlighted sourcecode to any Python file arbitrarily. * SQLAlchemy-specific stuff, like the [SQL] popups, the dialect info directives. * scss support using pyscss. Config ====== in conf.py, the extension is:: extensions = [ 'zzzeeksphinx', ] The theme is:: html_theme = 'zzzeeksphinx' Other configs that SQLAlchemy has set up; these two are probably needed:: # The short X.Y version. version = "1.0" # The full version, including alpha/beta/rc tags. release = "1.0.0" release_date = "Not released" Additional configs for the "dynamic site thing" look like:: site_base = os.environ.get("RTD_SITE_BASE", "http://www.sqlalchemy.org") site_adapter_template = "docs_adapter.mako" site_adapter_py = "docs_adapter.py" Configs which do some last-minute translation of module names when running autodoc to display API documentation:: autodocmods_convert_modname = { "sqlalchemy.sql.sqltypes": "sqlalchemy.types", "sqlalchemy.sql.type_api": "sqlalchemy.types", "sqlalchemy.sql.schema": "sqlalchemy.schema", "sqlalchemy.sql.elements": "sqlalchemy.sql.expression", "sqlalchemy.sql.selectable": "sqlalchemy.sql.expression", "sqlalchemy.sql.dml": "sqlalchemy.sql.expression", "sqlalchemy.sql.ddl": "sqlalchemy.schema", "sqlalchemy.sql.base": "sqlalchemy.sql.expression" } autodocmods_convert_modname_w_class = { ("sqlalchemy.engine.interfaces", "Connectable"): "sqlalchemy.engine", ("sqlalchemy.sql.base", "DialectKWArgs"): "sqlalchemy.sql.base", } Keywords: Sphinx Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha Classifier: Environment :: Console Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Documentation zzzeeksphinx-1.0.17/README.rst0000644000076500000240000000617112444073745016626 0ustar classicstaff00000000000000============= zzzeeksphinx ============= This is zzzeek's own Sphinx layout, used by SQLAlchemy. This layout is first and foremost pulled in for the SQLAlchemy documentation builds (and possibly other related projects), but is also usable as a standalone theme / utility set for any project. Feel free to fork off features from it as needed, the project here first and foremost has to work with SQLAlchemy. Features include: * Uses Mako templates instead of Jinja, for more programmatic capabilities inside of templates. * Layout includes an independently scrollable sidebar * A unique (to Sphinx) "contextual" sidebar contents that shows the current page in context with all sibling pages (like that of MySQL's docs). This is a form of TOC that Sphinx doesn't typically have a lot of capability to do (well it could, with some simple feature adds), but IMO this kind of navigation is critical for very large and nested documentation sets, so that the navbar stays relatively small yet provides context as to where you are in the docs and what else is locally available. * Modifications to autodoc which illustrate inherited classes, bases, method documentation illustrates if a method is only inherited from the base or overridden. * A "dynamic base" feature that will, under ReadTheDocs, pull in optional ``.mako`` and ``.py`` files from the website of your choice that will serve as an alternate base template and a source of extra config setup, respectively, allowing the layout to be integrated into the layout of an external site when viewing on the web. * A "viewsource" extension that can provide highlighted sourcecode to any Python file arbitrarily. * SQLAlchemy-specific stuff, like the [SQL] popups, the dialect info directives. * scss support using pyscss. Config ====== in conf.py, the extension is:: extensions = [ 'zzzeeksphinx', ] The theme is:: html_theme = 'zzzeeksphinx' Other configs that SQLAlchemy has set up; these two are probably needed:: # The short X.Y version. version = "1.0" # The full version, including alpha/beta/rc tags. release = "1.0.0" release_date = "Not released" Additional configs for the "dynamic site thing" look like:: site_base = os.environ.get("RTD_SITE_BASE", "http://www.sqlalchemy.org") site_adapter_template = "docs_adapter.mako" site_adapter_py = "docs_adapter.py" Configs which do some last-minute translation of module names when running autodoc to display API documentation:: autodocmods_convert_modname = { "sqlalchemy.sql.sqltypes": "sqlalchemy.types", "sqlalchemy.sql.type_api": "sqlalchemy.types", "sqlalchemy.sql.schema": "sqlalchemy.schema", "sqlalchemy.sql.elements": "sqlalchemy.sql.expression", "sqlalchemy.sql.selectable": "sqlalchemy.sql.expression", "sqlalchemy.sql.dml": "sqlalchemy.sql.expression", "sqlalchemy.sql.ddl": "sqlalchemy.schema", "sqlalchemy.sql.base": "sqlalchemy.sql.expression" } autodocmods_convert_modname_w_class = { ("sqlalchemy.engine.interfaces", "Connectable"): "sqlalchemy.engine", ("sqlalchemy.sql.base", "DialectKWArgs"): "sqlalchemy.sql.base", } zzzeeksphinx-1.0.17/setup.cfg0000644000076500000240000000007312530636260016744 0ustar classicstaff00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 zzzeeksphinx-1.0.17/setup.py0000644000076500000240000000234612444070232016635 0ustar classicstaff00000000000000from setuptools import setup import os import re v = open(os.path.join(os.path.dirname(__file__), 'zzzeeksphinx', '__init__.py')) VERSION = re.compile(r".*__version__ = '(.*?)'", re.S).match(v.read()).group(1) v.close() readme = os.path.join(os.path.dirname(__file__), 'README.rst') setup( name='zzzeeksphinx', version=VERSION, description="Zzzeek's Sphinx Layout and Utilities.", long_description=open(readme).read(), classifiers=[ 'Development Status :: 3 - Alpha', 'Environment :: Console', 'Intended Audience :: Developers', 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Documentation', ], keywords='Sphinx', author='Mike Bayer', author_email='mike@zzzcomputing.com', url='http://bitbucket.org/zzzeek/zzzeeksphinx', license='MIT', packages=['zzzeeksphinx'], install_requires=['pyscss', 'mako'], include_package_data=True, zip_safe=False, entry_points={ 'sphinx_themes': [ 'zzzeeksphinx = zzzeeksphinx.theme:get_path', ] }, ) zzzeeksphinx-1.0.17/zzzeeksphinx/0000755000076500000240000000000012530636260017677 5ustar classicstaff00000000000000zzzeeksphinx-1.0.17/zzzeeksphinx/__init__.py0000664000076500000240000000043512530636126022015 0ustar classicstaff00000000000000__version__ = '1.0.17' def setup(app): from . import autodoc_mods, dialect_info, mako, \ sqlformatter, viewsource, scss autodoc_mods.setup(app) dialect_info.setup(app) mako.setup(app) sqlformatter.setup(app) viewsource.setup(app) scss.setup(app) zzzeeksphinx-1.0.17/zzzeeksphinx/autodoc_mods.py0000644000076500000240000000730312447634224022741 0ustar classicstaff00000000000000import re def autodoc_skip_member(app, what, name, obj, skip, options): if what == 'class' and skip and \ name in ('__init__', '__eq__', '__ne__', '__lt__', '__le__', '__call__') and \ obj.__doc__: return False else: return skip def _adjust_rendered_mod_name(config, modname, objname): if (modname, objname) in config.autodocmods_convert_modname_w_class: return config.autodocmods_convert_modname_w_class[(modname, objname)] elif modname in config.autodocmods_convert_modname: return config.autodocmods_convert_modname[modname] else: return modname # im sure this is in the app somewhere, but I don't really # know where, so we're doing it here. _track_autodoced = {} _inherited_names = set() def autodoc_process_docstring(app, what, name, obj, options, lines): if what == "class": _track_autodoced[name] = obj # need to translate module names for bases, others # as we document lots of symbols in namespace modules # outside of their source bases = [] for base in obj.__bases__: if base is not object: adjusted_mod = _adjust_rendered_mod_name( app.env.config, base.__module__, base.__name__) bases.append( ":class:`%s.%s`" % ( adjusted_mod, base.__name__)) _inherited_names.add( "%s.%s" % (adjusted_mod, base.__name__)) if bases: lines[:0] = [ "Bases: %s" % (", ".join(bases)), "" ] elif what in ("attribute", "method") and options.get("inherited-members"): m = re.match(r'(.*?)\.([\w_]+)$', name) if m: clsname, attrname = m.group(1, 2) if clsname in _track_autodoced: cls = _track_autodoced[clsname] for supercls in cls.__mro__: if attrname in supercls.__dict__: break if supercls is not cls: adjusted_mod = _adjust_rendered_mod_name( app.env.config, supercls.__module__, supercls.__name__ ) _inherited_names.add( "%s.%s" % (adjusted_mod, supercls.__name__)) _inherited_names.add( "%s.%s.%s" % (adjusted_mod, supercls.__name__, attrname)) lines[:0] = [ ".. container:: inherited_member", "", " *inherited from the* " ":%s:`~%s.%s.%s` *%s of* :class:`~%s.%s`" % ( "attr" if what == "attribute" else "meth", adjusted_mod, supercls.__name__, attrname, what, adjusted_mod, supercls.__name__ ), "" ] def missing_reference(app, env, node, contnode): if node.attributes['reftarget'] in _inherited_names: return node.children[0] else: return None def setup(app): app.connect('autodoc-skip-member', autodoc_skip_member) app.connect('autodoc-process-docstring', autodoc_process_docstring) app.add_config_value("autodocmods_convert_modname", {}, 'env') app.add_config_value("autodocmods_convert_modname_w_class", {}, 'env') app.connect('missing-reference', missing_reference) zzzeeksphinx-1.0.17/zzzeeksphinx/dialect_info.py0000644000076500000240000001440312444067065022700 0ustar classicstaff00000000000000import re from sphinx.util.compat import Directive from docutils import nodes class DialectDirective(Directive): has_content = True _dialects = {} def _parse_content(self): d = {} d['default'] = self.content[0] d['text'] = [] idx = 0 for line in self.content[1:]: idx += 1 m = re.match(r'\:(.+?)\: +(.+)', line) if m: attrname, value = m.group(1, 2) d[attrname] = value else: break d["text"] = self.content[idx + 1:] return d def _dbapi_node(self): dialect_name, dbapi_name = self.dialect_name.split("+") try: dialect_directive = self._dialects[dialect_name] except KeyError: raise Exception( "No .. dialect:: %s " "directive has been established" % dialect_name) output = [] content = self._parse_content() parent_section_ref = self.state.parent.children[0]['ids'][0] self._append_dbapi_bullet( dialect_name, dbapi_name, content['name'], parent_section_ref) p = nodes.paragraph( '', '', nodes.Text( "Support for the %s database via the %s driver." % ( dialect_directive.database_name, content['name'] ), "Support for the %s database via the %s driver." % ( dialect_directive.database_name, content['name'] ) ), ) self.state.nested_parse(content['text'], 0, p) output.append(p) if "url" in content or "driverurl" in content: sec = nodes.section( '', nodes.title("DBAPI", "DBAPI"), ids=["dialect-%s-%s-url" % (dialect_name, dbapi_name)] ) if "url" in content: text = "Documentation and download information "\ "(if applicable) "\ "for %s is available at:\n" % content["name"] uri = content['url'] sec.append( nodes.paragraph( '', '', nodes.Text(text, text), nodes.reference('', '', nodes.Text(uri, uri), refuri=uri, ) ) ) if "driverurl" in content: text = "Drivers for this database are available at:\n" sec.append( nodes.paragraph( '', '', nodes.Text(text, text), nodes.reference('', '', nodes.Text( content['driverurl'], content['driverurl']), refuri=content['driverurl'] ) ) ) output.append(sec) if "connectstring" in content: sec = nodes.section( '', nodes.title("Connecting", "Connecting"), nodes.paragraph( '', '', nodes.Text("Connect String:", "Connect String:"), nodes.literal_block( content['connectstring'], content['connectstring']) ), ids=["dialect-%s-%s-connect" % (dialect_name, dbapi_name)] ) output.append(sec) return output def _dialect_node(self): self._dialects[self.dialect_name] = self content = self._parse_content() self.database_name = content['name'] self.bullets = nodes.bullet_list() text = "The following dialect/DBAPI options are available. "\ "Please refer to individual DBAPI sections "\ "for connect information." sec = nodes.section( '', nodes.paragraph( '', '', nodes.Text( "Support for the %s database." % content['name'], "Support for the %s database." % content['name'] ), ), nodes.title("DBAPI Support", "DBAPI Support"), nodes.paragraph( '', '', nodes.Text(text, text), self.bullets ), ids=["dialect-%s" % self.dialect_name] ) return [sec] def _append_dbapi_bullet(self, dialect_name, dbapi_name, name, idname): env = self.state.document.settings.env dialect_directive = self._dialects[dialect_name] try: relative_uri = env.app.builder.get_relative_uri( dialect_directive.docname, self.docname) except: relative_uri = "" list_node = nodes.list_item( '', nodes.paragraph( '', '', nodes.reference( '', '', nodes.Text(name, name), refdocname=self.docname, refuri=relative_uri + "#" + idname ), #nodes.Text(" ", " "), #nodes.reference('', '', # nodes.Text("(connectstring)", "(connectstring)"), # refdocname=self.docname, # refuri=env.app.builder.get_relative_uri( # dialect_directive.docname, self.docname) + ## "#" + ("dialect-%s-%s-connect" % # (dialect_name, dbapi_name)) # ) ) ) dialect_directive.bullets.append(list_node) def run(self): env = self.state.document.settings.env self.docname = env.docname self.dialect_name = dialect_name = self.content[0] has_dbapi = "+" in dialect_name if has_dbapi: return self._dbapi_node() else: return self._dialect_node() def setup(app): app.add_directive('dialect', DialectDirective) zzzeeksphinx-1.0.17/zzzeeksphinx/mako.py0000644000076500000240000000665512504303206021204 0ustar classicstaff00000000000000from __future__ import absolute_import from sphinx.application import TemplateBridge from sphinx.jinja2glue import BuiltinTemplateLoader from mako.lookup import TemplateLookup from .toc import TOCMixin import os rtd = os.environ.get('READTHEDOCS', None) == 'True' class MakoBridge(TOCMixin, TemplateBridge): def init(self, builder, *args, **kw): self.jinja2_fallback = BuiltinTemplateLoader() self.jinja2_fallback.init(builder, *args, **kw) builder.config.html_context['release_date'] = \ builder.config['release_date'] builder.config.html_context['site_base'] = builder.config['site_base'] self.app = builder.app package_dir = os.path.abspath(os.path.dirname(__file__)) template_path = os.path.join( package_dir, 'themes', builder.config.html_theme) self.lookup = TemplateLookup( strict_undefined=True, directories=builder.config.templates_path + [ template_path ], #format_exceptions=True, imports=[ "from zzzeeksphinx import util" ] ) if rtd and builder.config['site_base']: import urllib2 if builder.config['site_adapter_template']: # remote site layout / startup files template_name = builder.config['site_adapter_template'] template = urllib2.urlopen( builder.config['site_base'] + "/" + template_name).read() self.lookup.put_string(template_name, template) py_name = builder.config['site_adapter_py'] if py_name: setup_ctx = urllib2.urlopen( builder.config['site_base'] + "/" + py_name).read() lcls = {} exec(setup_ctx, lcls) self.setup_ctx = lcls['setup_context'] def setup_ctx(self, context): pass def render(self, template, context): template = template.replace(".html", ".mako") context['prevtopic'] = context.pop('prev', None) context['nexttopic'] = context.pop('next', None) context['app'] = self.app # local docs layout context['rtd'] = False context['toolbar'] = False context['base'] = "static_base.mako" context['parent_toc'] = self.get_current_subtoc context['bridge'] = self context.setdefault('toc', None) context.setdefault('pdf_url', None) context.setdefault('metatags', None) context.setdefault("canonical_url", None) context.setdefault("single_version", None) context.setdefault("rtd_language", "en") # override context attributes self.setup_ctx(context) context.setdefault('_', lambda x: x) return self.lookup.get_template(template).render_unicode(**context) def render_string(self, template, context): # this is used for .js, .css etc. and we don't have # local copies of that stuff here so use the jinja render. return self.jinja2_fallback.render_string(template, context) def setup(app): app.config['template_bridge'] = "zzzeeksphinx.mako.MakoBridge" app.add_config_value('release_date', "", 'env') app.add_config_value('site_base', "", 'env') app.add_config_value('site_adapter_template', "", 'env') app.add_config_value('site_adapter_py', "", 'env') app.add_config_value('build_number', "", 'env') zzzeeksphinx-1.0.17/zzzeeksphinx/scss.py0000644000076500000240000000322212516534732021230 0ustar classicstaff00000000000000from __future__ import absolute_import import os from scss import Scss # these docs aren't super accurate # http://pyscss.readthedocs.org/en/latest/ def add_stylesheet(app): # TODO: make this inclusive of HTML builders # instead, or something if app.builder.name == 'latex': return to_gen = [] package_dir = os.path.abspath(os.path.dirname(__file__)) static_path = os.path.join( package_dir, 'themes', app.builder.config.html_theme, 'static') for fname in os.listdir(static_path): name, ext = os.path.splitext(fname) if ext != ".scss": continue to_gen.append((static_path, name)) # sphinx doesn't really have a "temp" area that will persist # down into build-finished (env.temp_data gets emptied). # So make our own! app._builder_scss = to_gen for path, name in to_gen: app.add_stylesheet('%s.css' % name) def generate_stylesheet(app, exception): # TODO: make this inclusive of HTML builders # instead, or something if app.builder.name == 'latex': return to_gen = app._builder_scss compiler = Scss(scss_opts={"style": "expanded"}) if exception: return for static_path, name in to_gen: css = compiler.compile( open(os.path.join(static_path, "%s.scss" % name)).read()) dest = os.path.join(app.builder.outdir, '_static', '%s.css' % name) #copyfile(os.path.join(source, "%s.css" % name), dest) with open(dest, "w") as out: out.write(css) def setup(app): app.connect('builder-inited', add_stylesheet) app.connect('build-finished', generate_stylesheet) zzzeeksphinx-1.0.17/zzzeeksphinx/sqlformatter.py0000644000076500000240000001017312451607666023010 0ustar classicstaff00000000000000from pygments.lexer import RegexLexer, bygroups, using from pygments.token import Token from pygments.filter import Filter from pygments.filter import apply_filters from pygments.lexers import PythonLexer, PythonConsoleLexer from sphinx.highlighting import PygmentsBridge from pygments.formatters import HtmlFormatter, LatexFormatter import re def _strip_trailing_whitespace(iter_): buf = list(iter_) if buf: buf[-1] = (buf[-1][0], buf[-1][1].rstrip()) for t, v in buf: yield t, v class StripDocTestFilter(Filter): def filter(self, lexer, stream): for ttype, value in stream: if ttype is Token.Comment and re.match(r'#\s*doctest:', value): continue yield ttype, value class PyConWithSQLLexer(RegexLexer): name = 'PyCon+SQL' aliases = ['pycon+sql'] flags = re.IGNORECASE | re.DOTALL tokens = { 'root': [ (r'{sql}', Token.Sql.Link, 'sqlpopup'), (r'{opensql}', Token.Sql.Open, 'opensqlpopup'), (r'.*?\n', using(PythonConsoleLexer)) ], 'sqlpopup': [ ( r'(.*?\n)((?:PRAGMA|BEGIN|SELECT|INSERT|DELETE|ROLLBACK|' 'COMMIT|ALTER|UPDATE|CREATE|DROP|PRAGMA' '|DESCRIBE).*?(?:{stop}\n?|$))', bygroups(using(PythonConsoleLexer), Token.Sql.Popup), "#pop" ) ], 'opensqlpopup': [ ( r'.*?(?:{stop}\n*|$)', Token.Sql, "#pop" ) ] } class PythonWithSQLLexer(RegexLexer): name = 'Python+SQL' aliases = ['python+sql'] flags = re.IGNORECASE | re.DOTALL tokens = { 'root': [ (r'{sql}', Token.Sql.Link, 'sqlpopup'), (r'{opensql}', Token.Sql.Open, 'opensqlpopup'), (r'.*?\n', using(PythonLexer)) ], 'sqlpopup': [ ( r'(.*?\n)((?:PRAGMA|BEGIN|SELECT|INSERT|DELETE|ROLLBACK' '|COMMIT|ALTER|UPDATE|CREATE|DROP' '|PRAGMA|DESCRIBE).*?(?:{stop}\n?|$))', bygroups(using(PythonLexer), Token.Sql.Popup), "#pop" ) ], 'opensqlpopup': [ ( r'.*?(?:{stop}\n*|$)', Token.Sql, "#pop" ) ] } class PopupSQLFormatter(HtmlFormatter): def _format_lines(self, tokensource): buf = [] for ttype, value in apply_filters(tokensource, [StripDocTestFilter()]): if ttype in Token.Sql: for t, v in HtmlFormatter._format_lines(self, iter(buf)): yield t, v buf = [] if ttype is Token.Sql: yield 1, "
%s
" % \ re.sub(r'(?:{stop}|\n+)$', '', value) elif ttype is Token.Sql.Link: yield 1, "sql" elif ttype is Token.Sql.Popup: yield 1, "" % \ re.sub(r'(?:{stop}|\n+)$', '', value) else: buf.append((ttype, value)) for t, v in _strip_trailing_whitespace( HtmlFormatter._format_lines(self, iter(buf))): yield t, v class PopupLatexFormatter(LatexFormatter): def _filter_tokens(self, tokensource): for ttype, value in apply_filters(tokensource, [StripDocTestFilter()]): if ttype in Token.Sql: if ttype is not Token.Sql.Link and ttype is not Token.Sql.Open: yield Token.Literal, re.sub(r'{stop}', '', value) else: continue else: yield ttype, value def format(self, tokensource, outfile): LatexFormatter.format(self, self._filter_tokens(tokensource), outfile) def setup(app): app.add_lexer('pycon+sql', PyConWithSQLLexer()) app.add_lexer('python+sql', PythonWithSQLLexer()) PygmentsBridge.html_formatter = PopupSQLFormatter PygmentsBridge.latex_formatter = PopupLatexFormatter zzzeeksphinx-1.0.17/zzzeeksphinx/theme.py0000664000076500000240000000024312444066250021354 0ustar classicstaff00000000000000from os import path package_dir = path.abspath(path.dirname(__file__)) template_path = path.join(package_dir, 'themes') def get_path(): return template_path zzzeeksphinx-1.0.17/zzzeeksphinx/themes/0000755000076500000240000000000012530636260021164 5ustar classicstaff00000000000000zzzeeksphinx-1.0.17/zzzeeksphinx/themes/zzzeeksphinx/0000755000076500000240000000000012530636260023740 5ustar classicstaff00000000000000zzzeeksphinx-1.0.17/zzzeeksphinx/themes/zzzeeksphinx/genindex.mako0000644000076500000240000000350412444066361026417 0ustar classicstaff00000000000000<%inherit file="layout.mako"/> <%block name="show_title" filter="util.striptags"> ${_('Index')}

${_('Index')}

% for i, (key, dummy) in enumerate(genindexentries): ${i != 0 and '| ' or ''}${key} % endfor
% for i, (key, entries) in enumerate(genindexentries):

${key}

<% breakat = genindexcounts[i] // 2 numcols = 1 numitems = 0 %> % for entryname, (links, subitems) in entries:
% if links: ${entryname|h} % for unknown, link in links[1:]: , [${i}] % endfor % else: ${entryname|h} % endif
% if subitems:
% for subentryname, subentrylinks in subitems:
${subentryname|h} % for j, (unknown, link) in enumerate(subentrylinks[1:]): [${j}] % endfor
% endfor
% endif <% numitems = numitems + 1 + len(subitems) %> % if numcols <2 and numitems > breakat: <% numcols = numcols + 1 %>
% endif % endfor
% endfor <%def name="sidebarrel()"> % if split_index:

${_('Index')}

% for i, (key, dummy) in enumerate(genindexentries): ${i > 0 and '| ' or ''} ${key} % endfor

${_('Full index on one page')}

% endif ${parent.sidebarrel()} zzzeeksphinx-1.0.17/zzzeeksphinx/themes/zzzeeksphinx/layout.mako0000644000076500000240000001602312450075727026136 0ustar classicstaff00000000000000## coding: utf-8 <%! local_script_files = [] default_css_files = [ '_static/pygments.css', ] %> <%doc> Structural elements are all prefixed with "docs-" to prevent conflicts when the structure is integrated into the main site. docs-container -> docs-top-navigation-container -> docs-header -> docs-version-header docs-top-navigation docs-top-page-control docs-navigation-banner docs-body-container -> docs-sidebar docs-body docs-bottom-navigation docs-copyright <%inherit file="${context['base']}"/> <% if builder == 'epub': next.body() return %> <% withsidebar = bool(toc) and current_page_name != 'index' %> <%block name="head_title"> % if current_page_name != 'index': ${capture(self.show_title) | util.striptags} — % endif ${docstitle|h} <%def name="show_title()"> ${title}
<%block name="headers"> ${parent.headers()} % if hasdoc('about'): % endif % if hasdoc('copyright'): % endif % if parents: % endif % if nexttopic: % endif % if prevtopic: % endif
Release: ${release} | Release Date: ${release_date}

${docstitle|h}

% if not withsidebar:

Contents | Index % if pdf_url: | Download as PDF % endif

% endif % if withsidebar:

${docstitle|h}

<% breadcrumb = parents[:] if not breadcrumb or breadcrumb[0]['link'] != pathto('index'): breadcrumb = [{'link': pathto('index'), 'title': docstitle}] + breadcrumb if len(breadcrumb) > 1: breadcrumb = breadcrumb[1:] h3_toc_item = breadcrumb[0] if len(breadcrumb) > 1: outermost_link_item = breadcrumb[1]['link'] elif not parents: outermost_link_item = None else: outermost_link_item = '' %>

${h3_toc_item['title']}

${parent_toc( current_page_name, outermost_link_item)} % if rtd:

Project Versions

% endif
% endif
<%doc>
${docstitle|h} % if parents: % for parent in parents: » ${parent['title']} % endfor % endif % if current_page_name != 'index': » ${self.show_title()} % endif

<%block name="show_title"> ${title}

${next.body()}
<%block name="lower_scripts"> % for scriptfile in script_files + self.attr.local_script_files: % endfor zzzeeksphinx-1.0.17/zzzeeksphinx/themes/zzzeeksphinx/page.mako0000644000076500000240000000010312444066361025522 0ustar classicstaff00000000000000<%inherit file="layout.mako"/> ${body| util.strip_toplevel_anchors}zzzeeksphinx-1.0.17/zzzeeksphinx/themes/zzzeeksphinx/search.mako0000644000076500000240000000064612447642331026067 0ustar classicstaff00000000000000<%inherit file="layout.mako"/> <%! local_script_files = ['_static/searchtools.js'] %> <%block name="show_title"> ${_('Search')}
<%block name="footer"> ${parent.footer()} <%block name="lower_scripts"> ${parent.lower_scripts()} zzzeeksphinx-1.0.17/zzzeeksphinx/themes/zzzeeksphinx/static/0000755000076500000240000000000012530636260025227 5ustar classicstaff00000000000000zzzeeksphinx-1.0.17/zzzeeksphinx/themes/zzzeeksphinx/static/detectmobile.js0000644000076500000240000000425312444066400030226 0ustar classicstaff00000000000000/** * jQuery.browser.mobile (http://detectmobilebrowser.com/) * * jQuery.browser.mobile will be true if the browser is a mobile device * **/ (function(a){(jQuery.browser=jQuery.browser||{}).mobile=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))})(navigator.userAgent||navigator.vendor||window.opera);zzzeeksphinx-1.0.17/zzzeeksphinx/themes/zzzeeksphinx/static/docs.scss0000644000076500000240000002456312530636112027062 0ustar classicstaff00000000000000$primary-font-family: Verdana, sans-serif; $header-font-family: Helvetica, Arial, sans-serif; $top-header-font-family: Tahoma,Geneva,sans-serif; $primary-background-color: #FDFBFC; $topmost-header-color: #EBEBEE; $popout-color: #FBFBEE; $sidebar-color: #EFEFEF; $sidebar-header-background-color: #DDDDDD; $sidebar-header-color: #222222; $notebox-background-color: #EEFFEF; $border-style: 1px solid #CCC; $highlighted-nav-link-background-color: #DDD; /* global */ .body-background { background-color: $primary-background-color; } body { background-color: $primary-background-color; margin:0 38px; color:#333333; } a { font-weight:normal; text-decoration:none; } form { display:inline; } /* hyperlinks */ a:link, a:visited, a:active { color: #990000; } a:hover { color: #FF0000; text-decoration:underline; } /* paragraph links after sections. These aren't visible until hovering over the tag, then have a "reverse video" effect over the actual link */ a.headerlink { font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; visibility: hidden; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink, li:hover > a.headerlink { visibility: visible; } a.headerlink:hover { background-color: #990000; color: white; } /* Container setup */ #docs-container { max-width:1000px; margin: 0 auto; position: relative; } /* header/footer elements */ #docs-header { font-family: $primary-font-family; font-size:.9em; position: relative; h1 { font-size: 20px; color: #222222; margin: 4px 0px; padding: 5px 5px; background-color: $topmost-header-color; border: $border-style; } } #docs-sidebar-popout, #docs-bottom-navigation, #index-nav { font-family: $primary-font-family; background-color: $popout-color; border: $border-style; font-size:.8em; } #docs-bottom-navigation, #index-nav { padding:10px; } #docs-version-header { position: absolute; right: 8px; bottom: 8px; } .docs-navigation-links { font-family: $primary-font-family; } #docs-bottom-navigation { float:right; margin: 1em 0 1em 5px; } #docs-copyright { font-size:.85em; padding:5px 0px; } #docs-header h1, #docs-top-navigation h1, #docs-top-navigation h2 { font-family: $top-header-font-family; font-weight:normal; } #docs-top-navigation h2 { margin:16px 4px 7px 5px; font-size:1.6em; } #docs-top-page-control { position: absolute; right: 20px; bottom: 14px; ul { padding:0; margin:0; } li { font-size:.9em; list-style-type:none; padding:1px 8px; } } #docs-container .version-num { font-weight: bold; } /* content container, sidebar */ #docs-body-container { position: relative; } #docs-body, #docs-sidebar, #index-nav { font-family: $primary-font-family; font-size:.85em; line-height:1.5em; } #docs-body { min-height: 700px; } #index-nav { position: relative; margin-top:10px; padding:0 10px; } #index-nav form { padding-top:10px; float:right; } #sidebar-paginate { position: absolute; bottom: 4.5em; left: 10px; } #sidebar-topnav { position: absolute; bottom: 3em; left: 10px; } #sidebar-search { position: absolute; bottom: 1em; left: 10px; } #docs-sidebar { top: 118px; bottom: 0; min-height: 0; overflow-y: auto; overflow-x: hidden; margin-top:5px; width:212px; padding-left:10px; font-size:.85em; border: $border-style; z-index: 3; background-color: $sidebar-color; > ul { font-size:.85em; } span.link-container { display: block; margin-left: -100px; padding-left: 100px; } li.current > span.link-container { background-color: $highlighted-nav-link-background-color; } h3, h4 { background-color: $sidebar-header-background-color; color: $sidebar-header-color; font-family: $primary-font-family; font-size: 1.1em; font-weight: normal; margin: 10px 0 0 -15px; padding: 5px 10px 5px 15px; text-shadow: 1px 1px 0 white; a { color: $sidebar-header-color; } } h3:first-child { margin-top: 0px; } ul { margin: 10px 0px 10px 0px; padding: 0; list-style: none outside none; ul { margin-bottom: 0; margin-top: 0; list-style: square outside none; margin-left: 20px; } } } #docs-sidebar-popout { height:105px; max-height: 105px; width:212px; padding-left:10px; padding-top:10px; position: relative; font-size:.75em; p, form { margin:5px 0 5px 0px; } h3 { margin:0 0 10px 0; } } #fixed-sidebar { position: relative; box-sizing: border-box; } #fixed-sidebar.withsidebar { float: left; width:224px; } #fixed-sidebar.preautomated { position: fixed; float: none; top:0; bottom: 0; } #fixed-sidebar.preautomated #docs-sidebar, #fixed-sidebar.preautomated #docs-sidebar-popout { position:absolute; } #fixed-sidebar.preautomated #docs-sidebar:after { content: " "; display:block; height: 150px; } #docs-sidebar.preautomated { position: fixed; } #docs-body { background-color:#FFFFFF; padding:1px 10px 10px 10px; border: $border-style; margin-top:10px; } #docs-body.withsidebar { margin-left: 230px; } #docs-body h1, #docs-body h2, #docs-body h3, #docs-body h4 { font-family: $header-font-family; } #docs-body #sqlalchemy-documentation h1 { /* hide the

for each content section. */ display:none; font-size:2.0em; } #docs-body h2 { font-size:1.8em; border-top:1px solid; /*border-bottom:1px solid;*/ padding-top:20px; } #sqlalchemy-documentation h2 { border-top:none; padding-top:0; } #docs-body h3 { font-size:1.4em; } /* SQL popup, code styles */ .highlight { background:none; } #docs-container { pre { font-size:1.2em; background-color: #f0f0f0; border: $border-style; box-shadow: 2px 2px 3px #DFDFDF; padding:10px; margin: 5px 0px 5px 0px; overflow:auto; line-height:1.3em; } /* the [SQL] links used to display SQL */ .sql_link { font-weight:normal; font-family: helvetica, arial, sans-serif; font-size:.9em; text-transform: uppercase; color:#990000; border:1px solid; padding:1px 2px 1px 2px; margin:0px 10px 0px 15px; float:right; line-height:1.2em; } a.sql_link, .sql_link { text-decoration: none; padding:1px 2px; } a.sql_link:hover { text-decoration: none; color:#fff; border:1px solid #900; background-color: #900; } a.changeset-link { font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; } } .popup_sql, .show_sql { background-color: $popout-color; padding:5px 10px; margin:10px -5px; border:1px dashed; } /* docutils-specific elements */ th.field-name { text-align:right; } div.section { } div.note, div.warning, p.deprecated, div.topic, div.admonition { background-color:$notebox-background-color; } .footnote { font-size: .95em; } div.faq { background-color: #EFEFEF; } div.faq ul { list-style: square outside none; } div.admonition, div.topic, .deprecated, .versionadded, .versionchanged { border: $border-style; padding:5px 10px; font-size:.9em; margin-top:5px; box-shadow: 2px 2px 3px #DFDFDF; } div.sidebar { background-color: #FFFFEE; border: 1px solid #DDDDBB; float: right; margin: 10px 0 10px 1em; padding: 7px 7px 0; width: 40%; font-size:.9em; } p.sidebar-title { font-weight: bold; } /* grrr sphinx changing your document structures, removing classes.... */ .versionadded .versionmodified, .versionchanged .versionmodified, .deprecated .versionmodified, .versionadded > p:first-child > span:first-child, .versionchanged > p:first-child > span:first-child, .deprecated > p:first-child > span:first-child { background-color: #ECF0F3; color: #990000; font-style: italic; } div.inherited-member { border: $border-style; padding:5px 5px; font-size:.9em; box-shadow: 2px 2px 3px #DFDFDF; } div.warning .admonition-title { color:#FF0000; } div.admonition .admonition-title, div.topic .topic-title { font-weight:bold; } .viewcode-back, .viewcode-link { float:right; } dl.function > dt, dl.attribute > dt, dl.classmethod > dt, dl.method > dt, dl.class > dt, dl.exception > dt { background-color: #EFEFEF; margin:25px -10px 10px 10px; padding: 0px 10px; } dl.glossary > dt { font-weight:bold; font-size:1.1em; padding-top:10px; } dt:target, span.highlight { background-color:#FBE54E; } a.headerlink { font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; visibility: hidden; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink, li:hover > a.headerlink, li:hover > span > a.headerlink { visibility: visible; } a.headerlink:hover { background-color: #00f; color: white; } .clearboth { clear:both; } /* sphinx 1.3 now using 'code' and not 'tt' for code / docstring elements */ code.descname, tt.descname { background-color:transparent; font-size:1.2em; font-weight:bold; } code.descclassname, tt.descclassname { background-color:transparent; } code, tt { background-color:#ECF0F3; padding:0 1px; } /* syntax highlighting overrides */ .k, .kn {color:#0908CE;} .o {color:#BF0005;} .go {color:#804049;} /* special "index page" sections with specific formatting */ div#sqlalchemy-documentation { font-size:.95em; } div#sqlalchemy-documentation em { font-style:normal; } div#sqlalchemy-documentation .rubric{ font-size:14px; background-color:#EEFFEF; padding:5px; border:1px solid #BFBFBF; } div#sqlalchemy-documentation a, div#sqlalchemy-documentation li { padding:5px 0px; } div#getting-started { border-bottom:1px solid; } div#sqlalchemy-documentation div#sqlalchemy-orm { float:left; width:48%; } div#sqlalchemy-documentation div#sqlalchemy-core { float:left; width:48%; margin:0; padding-left:10px; border-left:1px solid; } div#dialect-documentation { border-top:1px solid; /*clear:left;*/ } div .versionwarning, div .version-warning { font-size:12px; font-color:red; border:1px solid; padding:4px 4px; margin:8px 0px 2px 0px; background:#FFBBBB; } zzzeeksphinx-1.0.17/zzzeeksphinx/themes/zzzeeksphinx/static/init.js0000644000076500000240000000612612450565145026541 0ustar classicstaff00000000000000 function initSQLPopups() { $('div.popup_sql').hide(); $('a.sql_link').click(function() { $(this).nextAll('div.popup_sql:first').toggle(); return false; }); } function initFloatyThings() { if (!$("#fixed-sidebar.withsidebar")) { return; } var docsBodyOffset = $("#docs-body").offset().top; var padding = docsBodyOffset - ($("#docs-top-navigation-container").offset().top + $("#docs-top-navigation-container").height()); var automatedBreakpoint = $("#docs-container").position().top + $("#docs-top-navigation-container").height(); // this turns on the whole thing, without this // we are in graceful degradation assuming no JS $("#fixed-sidebar.withsidebar").addClass("preautomated"); function setScroll() { var scrolltop = $(window).scrollTop(); var fix = scrolltop >= automatedBreakpoint; if (fix) { $("#fixed-sidebar.withsidebar").css("top", padding); $("#fixed-sidebar.withsidebar").css("position", "fixed"); $("#fixed-sidebar.withsidebar").css("height", ''); } else { $("#fixed-sidebar.withsidebar").css("top", 0); $("#fixed-sidebar.withsidebar").css( "height", $(window).height() - docsBodyOffset + scrolltop); $("#fixed-sidebar.withsidebar").css("position", "absolute"); } } $(window).scroll(setScroll); $(window).resize(setScroll); setScroll(); } function highlightLinks() { function bisection(x){ var low = 0; var high = divCollection.length; var mid; while (low < high) { mid = (low + high) >> 1; if (x < divCollection[mid]['active']) { high = mid; } else { low = mid + 1; } } return low; } var divCollection = []; var currentIdx = -1; var docHeight = $(document).height(); $("div.section").each(function(index) { var active = $(this).offset().top - 20; divCollection.push({ 'id': this.id, 'active': active, }); }); function setLink() { var windowPos = $(window).scrollTop(); var windowHeight = $(window).height(); var idx; if (windowPos + windowHeight == docHeight) { idx = divCollection.length; } else { idx = bisection(windowPos); } if (idx != currentIdx) { var effectiveIdx = Math.max(0, idx - 1); currentIdx = idx; var ref; if (effectiveIdx == 0) { ref = ''; } else { ref = divCollection[effectiveIdx]['id']; } $("#docs-sidebar li.current").removeClass('current'); $("#docs-sidebar li a.reference[href='#" + ref + "']").parents("li").first().addClass('current'); } } $(window).scroll(setLink); setLink(); } $(document).ready(function() { initSQLPopups(); if (!$.browser.mobile) { initFloatyThings(); highlightLinks(); } }); zzzeeksphinx-1.0.17/zzzeeksphinx/themes/zzzeeksphinx/static_base.mako0000644000076500000240000000166112447641715027106 0ustar classicstaff00000000000000 ${metatags and metatags or ''} <%block name="head_title"> </%block> <%block name="css"> % for cssfile in self.attr.default_css_files + css_files: % endfor <%block name="headers"/> ${next.body()} <%block name="footer"/> <%block name="lower_scripts"/> zzzeeksphinx-1.0.17/zzzeeksphinx/themes/zzzeeksphinx/theme.conf0000664000076500000240000000012112444073063025705 0ustar classicstaff00000000000000[theme] inherit = basic stylesheet = docs.css pygments_style = sphinx [options] zzzeeksphinx-1.0.17/zzzeeksphinx/toc.py0000644000076500000240000002155612450431343021043 0ustar classicstaff00000000000000#!coding: utf-8 from docutils import nodes as docutils_nodes from sphinx import addnodes class TOCMixin(object): def get_current_subtoc(self, current_page_name, start_from=None): """Return a TOC for sub-files and sub-elements of the current file. This is to provide a "contextual" navbar that shows the current page in context of all of its siblings, not just the immediate "previous" and "next". This allows a very long page with many sections to be broken into smaller pages while not losing the navigation of the overall section, with the added bonus that only the page-level bullets for the current subsection are expanded, thus making for a much shorter, "drill-down" style navigation. """ raw_tree = self.app.env.get_toctree_for( current_page_name, self.app.builder, True, maxdepth=-1) local_tree = self.app.env.get_toc_for( current_page_name, self.app.builder) # start with the bullets inside the doc's toc, # not the top level bullet, as we get that from the other tree if not local_tree.children or len(local_tree.children[0].children) < 2: local_tree = None else: local_tree = local_tree.children[0].children[1] def _locate_nodes(nodes, level, outer=True): # this is a lazy way of getting at all the info in a # series of docutils nodes, with an absolute mimimal # reliance on the actual structure of the nodes. # we just look for refuris and the fact that a node # is dependent on another somehow, that's it, then we # flatten it out into a clean "tree" later. # An official Sphinx feature/extension # here would probably make much more use of direct # knowledge of the structure for elem in nodes: if hasattr(elem, 'attributes'): refuri = elem.attributes.get('refuri', None) else: refuri = None name = None if refuri is not None: for index, sub_elem in enumerate(elem.children, 1): if isinstance( sub_elem, (docutils_nodes.Text, docutils_nodes.literal)): continue else: break local_text = elem.children[0:index] name = local_text[0].rawsource remainders = elem.children[index:] # a little bit of extra filtering of when/where # we want internal nodes vs. page-level nodes, # this is usually not needed except in a certain # edge case if ( not outer and refuri.startswith("#") ) or ( outer and "#" not in refuri ): yield level, refuri, name, local_text else: remainders = elem.children # try to embed the item-level get_toc_for() inside # the file-level get_toctree_for(), otherwise if we # just get the full get_toctree_for(), it's enormous. if outer and refuri == '': if local_tree is not None: for ent in _locate_nodes( [local_tree], level + 1, False): yield ent else: for ent in _locate_nodes( remainders, level + 1, outer): yield ent def _organize_nodes(nodes): """organize the nodes that we've grabbed with non-contiguous 'level' numbers into a clean hierarchy""" stack = [] levels = [] for level, refuri, name, text_nodes in nodes: if not levels or levels[-1] < level: levels.append(level) new_collection = [] if stack: stack[-1].append(new_collection) stack.append(new_collection) elif level < levels[-1]: while levels and level < levels[-1]: levels.pop(-1) if level > levels[-1]: levels.append(level) else: stack.pop(-1) stack[-1].append((refuri, name, text_nodes)) return stack def _render_nodes( stack, level=0, start_from=None, nested_element=False, parent_element=None): printing = False if stack: printing = nested_element or start_from is None or \ start_from in [ elem[0] for elem in stack if isinstance(elem, tuple) ] if printing: if not isinstance( parent_element, docutils_nodes.bullet_list): new_list = docutils_nodes.bullet_list() parent_element.append(new_list) parent_element = new_list while stack: elem = stack.pop(0) as_links = not isinstance(elem, tuple) or \ elem[0] != '' if isinstance(elem, tuple): refuri, name, text_nodes = elem if not stack or isinstance(stack[0], tuple): if printing: list_item = docutils_nodes.list_item( classes=['selected'] if not as_links else []) list_item.append( self._link_node(refuri, text_nodes) if as_links else self._strong_node(refuri, text_nodes) ) parent_element.append(list_item) elif isinstance(stack[0], list): if printing: list_item = docutils_nodes.list_item( classes=['selected'] if not as_links else []) list_item.append( self._link_node(refuri, text_nodes) if as_links else self._strong_node(refuri, text_nodes) ) parent_element.append(list_item) else: list_item = None _render_nodes( stack[0], level=level + 1, start_from=start_from, nested_element=nested_element or printing or elem[0] == '', parent_element=list_item or parent_element) elif isinstance(elem, list): _render_nodes( elem, level=level + 1, start_from=start_from, nested_element=nested_element, parent_element=parent_element) element = docutils_nodes.bullet_list() nodes = _organize_nodes(_locate_nodes([raw_tree], 0)) _render_nodes( nodes, start_from=start_from, parent_element=element ) return self.app.builder.render_partial(element)['fragment'] def _link_node(self, refuri, text_nodes): link = docutils_nodes.reference( '', '', text_nodes[0], refuri=refuri) link.extend(text_nodes[1:]) cp = docutils_nodes.inline(classes=['link-container']) cp.append(link) return cp def _strong_node(self, refuri, text_nodes): cp = docutils_nodes.inline(classes=['link-container']) n1 = docutils_nodes.strong() n1.extend(text_nodes) cp.append(n1) paramlink = docutils_nodes.reference( '', '', docutils_nodes.Text(u"¶", u"¶"), refid="", # paramlink is our own CSS class, headerlink # is theirs. Trying to get everything we can for existing # symbols... classes=['paramlink', 'headerlink'] ) cp.append(paramlink) return cp zzzeeksphinx-1.0.17/zzzeeksphinx/util.py0000644000076500000240000000061712522717573021242 0ustar classicstaff00000000000000import sphinx import re SPHINX_VERSION = tuple( int(dig) for dig in re.findall("\d+", sphinx.__version__) ) def striptags(text): return re.compile(r'<[^>]*>').sub('', text) def go(m): # .html with no anchor if present, otherwise "#" for top of page return m.group(1) or '#' def strip_toplevel_anchors(text): return re.compile(r'(\.html)?#[-\w]+-toplevel').sub(go, text) zzzeeksphinx-1.0.17/zzzeeksphinx/viewsource.py0000644000076500000240000001541312522720617022451 0ustar classicstaff00000000000000from docutils import nodes from sphinx.ext.viewcode import collect_pages from sphinx.pycode import ModuleAnalyzer import imp import re from sphinx.util.compat import Directive import os from docutils.statemachine import StringList from sphinx.environment import NoUri from sphinx.pycode.pgen2 import token import warnings from . import util import sys py2k = sys.version_info < (3, 0) if py2k: text_type = unicode else: text_type = str def view_source( name, rawtext, text, lineno, inliner, options={}, content=[]): env = inliner.document.settings.env node = _view_source_node(env, text, None) return [node], [] def _get_sphinx_py_module(env): base_name = env.temp_data.get('autodoc:module', None) if base_name is not None: return base_name if util.SPHINX_VERSION >= (1, 3): base_name = env.ref_context.get('py:module', None) if base_name is not None: return base_name else: base_name = env.temp_data.get('py:module', None) if base_name is not None: return base_name return None def _view_source_node(env, text, state): # pretend we're using viewcode fully, # install the context it looks for if not hasattr(env, '_viewcode_modules'): env._viewcode_modules = {} modname = text text = modname.split(".")[-1] + ".py" # imitate sphinx . syntax if modname.startswith("."): # see if the modname needs to be corrected in terms # of current module context base_module = _get_sphinx_py_module(env) if base_module: modname = base_module + modname else: warnings.warn( "Could not get base module for relative module: %s; " "not generating node" % modname) return None urito = env.app.builder.get_relative_uri # we're showing code examples which may have dependencies # which we really don't want to have required so load the # module by file, not import (though we are importing) # the top level module here... pathname = None for tok in modname.split("."): try: file_, pathname, desc = imp.find_module( tok, [pathname] if pathname else None) except ImportError as ie: raise ImportError("Error trying to import %s: %s" % (modname, ie)) else: if file_: file_.close() # unlike viewcode which silently traps exceptions, # I want this to totally barf if the file can't be loaded. # a failed build better than a complete build missing # key content analyzer = ModuleAnalyzer.for_file(pathname, modname) # copied from viewcode analyzer.find_tags() if not isinstance(analyzer.code, text_type): code = analyzer.code.decode(analyzer.encoding) else: code = analyzer.code if state is not None: docstring = _find_mod_docstring(analyzer) if docstring: # get rid of "foo.py" at the top docstring = re.sub(r"^[a-zA-Z_0-9]+\.py", "", docstring) # strip docstring = docstring.strip() # yank only first paragraph docstring = docstring.split("\n\n")[0].strip() else: docstring = None pagename = '_modules/' + modname.replace('.', '/') try: refuri = urito(env.docname, pagename) except NoUri: # if we're in the latex builder etc., this seems # to be what we get refuri = None if util.SPHINX_VERSION >= (1, 3): entry = code, analyzer.tags, {}, refuri else: entry = code, analyzer.tags, {} env._viewcode_modules[modname] = entry if docstring: # embed the ref with the doc text so that it isn't # a separate paragraph if refuri: docstring = "`%s <%s>`_ - %s" % (text, refuri, docstring) else: docstring = "``%s`` - %s" % (text, docstring) para = nodes.paragraph('', '') state.nested_parse(StringList([docstring]), 0, para) return_node = para else: if refuri: refnode = nodes.reference( '', '', nodes.Text(text, text), refuri=urito(env.docname, pagename) ) else: refnode = nodes.Text(text, text) if state: return_node = nodes.paragraph('', '', refnode) else: return_node = refnode return return_node def _find_mod_docstring(analyzer): """attempt to locate the module-level docstring. Note that sphinx autodoc just uses ``__doc__``. But we don't want to import the module, so we need to parse for it. """ analyzer.tokenize() for type_, parsed_line, start_pos, end_pos, raw_line in analyzer.tokens: if type_ == token.COMMENT: continue elif type_ == token.STRING: return eval(parsed_line) else: return None def _parse_content(content): d = {} d['text'] = [] idx = 0 for line in content: idx += 1 m = re.match(r' *\:(.+?)\:(?: +(.+))?', line) if m: attrname, value = m.group(1, 2) d[attrname] = value or '' else: break d["text"] = content[idx:] return d def _comma_list(text): return re.split(r"\s*,\s*", text.strip()) class AutoSourceDirective(Directive): has_content = True def run(self): content = _parse_content(self.content) env = self.state.document.settings.env self.docname = env.docname sourcefile = self.state.document.current_source.split(os.pathsep)[0] dir_ = os.path.dirname(sourcefile) files = [ f for f in os.listdir(dir_) if f.endswith(".py") and f != "__init__.py" ] if "files" in content: # ordered listing of files to include files = [ fname for fname in _comma_list(content["files"]) if fname in set(files)] node = nodes.paragraph( '', '', nodes.Text("Listing of files:", "Listing of files:") ) bullets = nodes.bullet_list() for fname in files: modname, ext = os.path.splitext(fname) # relative lookup modname = "." + modname link = _view_source_node(env, modname, self.state) if link is not None: list_node = nodes.list_item( '', link ) bullets += list_node node += bullets return [node] def setup(app): app.add_role('viewsource', view_source) app.add_directive('autosource', AutoSourceDirective) # from sphinx.ext.viewcode app.connect('html-collect-pages', collect_pages) zzzeeksphinx-1.0.17/zzzeeksphinx.egg-info/0000755000076500000240000000000012530636260021371 5ustar classicstaff00000000000000zzzeeksphinx-1.0.17/zzzeeksphinx.egg-info/dependency_links.txt0000644000076500000240000000000112530636260025437 0ustar classicstaff00000000000000 zzzeeksphinx-1.0.17/zzzeeksphinx.egg-info/entry_points.txt0000644000076500000240000000007412530636260024670 0ustar classicstaff00000000000000[sphinx_themes] zzzeeksphinx = zzzeeksphinx.theme:get_path zzzeeksphinx-1.0.17/zzzeeksphinx.egg-info/not-zip-safe0000644000076500000240000000000112444070077023621 0ustar classicstaff00000000000000 zzzeeksphinx-1.0.17/zzzeeksphinx.egg-info/pbr.json0000644000076500000240000000005712530636260023051 0ustar classicstaff00000000000000{"is_release": false, "git_version": "b1b4e9a"}zzzeeksphinx-1.0.17/zzzeeksphinx.egg-info/PKG-INFO0000644000076500000240000001100012530636260022456 0ustar classicstaff00000000000000Metadata-Version: 1.1 Name: zzzeeksphinx Version: 1.0.17 Summary: Zzzeek's Sphinx Layout and Utilities. Home-page: http://bitbucket.org/zzzeek/zzzeeksphinx Author: Mike Bayer Author-email: mike@zzzcomputing.com License: MIT Description: ============= zzzeeksphinx ============= This is zzzeek's own Sphinx layout, used by SQLAlchemy. This layout is first and foremost pulled in for the SQLAlchemy documentation builds (and possibly other related projects), but is also usable as a standalone theme / utility set for any project. Feel free to fork off features from it as needed, the project here first and foremost has to work with SQLAlchemy. Features include: * Uses Mako templates instead of Jinja, for more programmatic capabilities inside of templates. * Layout includes an independently scrollable sidebar * A unique (to Sphinx) "contextual" sidebar contents that shows the current page in context with all sibling pages (like that of MySQL's docs). This is a form of TOC that Sphinx doesn't typically have a lot of capability to do (well it could, with some simple feature adds), but IMO this kind of navigation is critical for very large and nested documentation sets, so that the navbar stays relatively small yet provides context as to where you are in the docs and what else is locally available. * Modifications to autodoc which illustrate inherited classes, bases, method documentation illustrates if a method is only inherited from the base or overridden. * A "dynamic base" feature that will, under ReadTheDocs, pull in optional ``.mako`` and ``.py`` files from the website of your choice that will serve as an alternate base template and a source of extra config setup, respectively, allowing the layout to be integrated into the layout of an external site when viewing on the web. * A "viewsource" extension that can provide highlighted sourcecode to any Python file arbitrarily. * SQLAlchemy-specific stuff, like the [SQL] popups, the dialect info directives. * scss support using pyscss. Config ====== in conf.py, the extension is:: extensions = [ 'zzzeeksphinx', ] The theme is:: html_theme = 'zzzeeksphinx' Other configs that SQLAlchemy has set up; these two are probably needed:: # The short X.Y version. version = "1.0" # The full version, including alpha/beta/rc tags. release = "1.0.0" release_date = "Not released" Additional configs for the "dynamic site thing" look like:: site_base = os.environ.get("RTD_SITE_BASE", "http://www.sqlalchemy.org") site_adapter_template = "docs_adapter.mako" site_adapter_py = "docs_adapter.py" Configs which do some last-minute translation of module names when running autodoc to display API documentation:: autodocmods_convert_modname = { "sqlalchemy.sql.sqltypes": "sqlalchemy.types", "sqlalchemy.sql.type_api": "sqlalchemy.types", "sqlalchemy.sql.schema": "sqlalchemy.schema", "sqlalchemy.sql.elements": "sqlalchemy.sql.expression", "sqlalchemy.sql.selectable": "sqlalchemy.sql.expression", "sqlalchemy.sql.dml": "sqlalchemy.sql.expression", "sqlalchemy.sql.ddl": "sqlalchemy.schema", "sqlalchemy.sql.base": "sqlalchemy.sql.expression" } autodocmods_convert_modname_w_class = { ("sqlalchemy.engine.interfaces", "Connectable"): "sqlalchemy.engine", ("sqlalchemy.sql.base", "DialectKWArgs"): "sqlalchemy.sql.base", } Keywords: Sphinx Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha Classifier: Environment :: Console Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Documentation zzzeeksphinx-1.0.17/zzzeeksphinx.egg-info/requires.txt0000644000076500000240000000001412530636260023764 0ustar classicstaff00000000000000pyscss mako zzzeeksphinx-1.0.17/zzzeeksphinx.egg-info/SOURCES.txt0000644000076500000240000000174312530636260023262 0ustar classicstaff00000000000000LICENSE MANIFEST.in README.rst setup.py zzzeeksphinx/__init__.py zzzeeksphinx/autodoc_mods.py zzzeeksphinx/dialect_info.py zzzeeksphinx/mako.py zzzeeksphinx/scss.py zzzeeksphinx/sqlformatter.py zzzeeksphinx/theme.py zzzeeksphinx/toc.py zzzeeksphinx/util.py zzzeeksphinx/viewsource.py zzzeeksphinx.egg-info/PKG-INFO zzzeeksphinx.egg-info/SOURCES.txt zzzeeksphinx.egg-info/dependency_links.txt zzzeeksphinx.egg-info/entry_points.txt zzzeeksphinx.egg-info/not-zip-safe zzzeeksphinx.egg-info/pbr.json zzzeeksphinx.egg-info/requires.txt zzzeeksphinx.egg-info/top_level.txt zzzeeksphinx/themes/zzzeeksphinx/genindex.mako zzzeeksphinx/themes/zzzeeksphinx/layout.mako zzzeeksphinx/themes/zzzeeksphinx/page.mako zzzeeksphinx/themes/zzzeeksphinx/search.mako zzzeeksphinx/themes/zzzeeksphinx/static_base.mako zzzeeksphinx/themes/zzzeeksphinx/theme.conf zzzeeksphinx/themes/zzzeeksphinx/static/detectmobile.js zzzeeksphinx/themes/zzzeeksphinx/static/docs.scss zzzeeksphinx/themes/zzzeeksphinx/static/init.jszzzeeksphinx-1.0.17/zzzeeksphinx.egg-info/top_level.txt0000644000076500000240000000001512530636260024117 0ustar classicstaff00000000000000zzzeeksphinx