summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-12-16 12:16:46 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2014-12-16 12:16:46 -0500
commit3e55a0bf107143031fd183aef1028aef842c7d3f (patch)
tree75fb2f46b86df2b6ed51097cd5e58aad07dd3a96
parent91eb1b41e3a629b8f666f80142502ae88cba73f2 (diff)
downloadsqlalchemy-3e55a0bf107143031fd183aef1028aef842c7d3f.tar.gz
- add scss support
- start modularizing things
-rw-r--r--doc/build/builder/autodoc_mods.py50
-rw-r--r--doc/build/builder/dialect_info.py15
-rw-r--r--doc/build/builder/mako.py25
-rw-r--r--doc/build/builder/scss.py46
-rw-r--r--doc/build/builder/toc.py56
-rw-r--r--doc/build/conf.py18
-rw-r--r--doc/build/static/docs.scss (renamed from doc/build/static/docs.css)102
-rw-r--r--doc/build/templates/layout.mako7
8 files changed, 204 insertions, 115 deletions
diff --git a/doc/build/builder/autodoc_mods.py b/doc/build/builder/autodoc_mods.py
index 5a6e991bd..78c94b615 100644
--- a/doc/build/builder/autodoc_mods.py
+++ b/doc/build/builder/autodoc_mods.py
@@ -10,27 +10,11 @@ def autodoc_skip_member(app, what, name, obj, skip, options):
return skip
-_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"
-}
-
-_convert_modname_w_class = {
- ("sqlalchemy.engine.interfaces", "Connectable"): "sqlalchemy.engine",
- ("sqlalchemy.sql.base", "DialectKWArgs"): "sqlalchemy.sql.base",
-}
-
-def _adjust_rendered_mod_name(modname, objname):
- if (modname, objname) in _convert_modname_w_class:
- return _convert_modname_w_class[(modname, objname)]
- elif modname in _convert_modname:
- return _convert_modname[modname]
+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
@@ -49,7 +33,8 @@ def autodoc_process_docstring(app, what, name, obj, options, lines):
for base in obj.__bases__:
if base is not object:
bases.append(":class:`%s.%s`" % (
- _adjust_rendered_mod_name(base.__module__, base.__name__),
+ _adjust_rendered_mod_name(
+ app.env.config, base.__module__, base.__name__),
base.__name__))
if bases:
@@ -70,19 +55,28 @@ def autodoc_process_docstring(app, what, name, obj, options, lines):
if attrname in supercls.__dict__:
break
if supercls is not cls:
- _inherited_names.add("%s.%s" % (supercls.__module__, supercls.__name__))
- _inherited_names.add("%s.%s.%s" % (supercls.__module__, supercls.__name__, attrname))
+ _inherited_names.add(
+ "%s.%s" % (supercls.__module__, supercls.__name__))
+ _inherited_names.add(
+ "%s.%s.%s" %
+ (supercls.__module__, supercls.__name__, attrname))
lines[:0] = [
".. container:: inherited_member",
"",
- " *inherited from the* :%s:`~%s.%s.%s` *%s of* :class:`~%s.%s`" % (
+ " *inherited from the* "
+ ":%s:`~%s.%s.%s` *%s of* :class:`~%s.%s`" % (
"attr" if what == "attribute"
else "meth",
- _adjust_rendered_mod_name(supercls.__module__, supercls.__name__),
+ _adjust_rendered_mod_name(
+ app.env.config,
+ supercls.__module__,
+ supercls.__name__),
supercls.__name__,
attrname,
what,
- _adjust_rendered_mod_name(supercls.__module__, supercls.__name__),
+ _adjust_rendered_mod_name(app.env.config,
+ supercls.__module__,
+ supercls.__name__),
supercls.__name__
),
""
@@ -98,5 +92,7 @@ def missing_reference(app, env, node, contnode):
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)
diff --git a/doc/build/builder/dialect_info.py b/doc/build/builder/dialect_info.py
index 48626393d..eec4cb6dc 100644
--- a/doc/build/builder/dialect_info.py
+++ b/doc/build/builder/dialect_info.py
@@ -30,7 +30,8 @@ class DialectDirective(Directive):
try:
dialect_directive = self._dialects[dialect_name]
except KeyError:
- raise Exception("No .. dialect:: %s directive has been established"
+ raise Exception(
+ "No .. dialect:: %s directive has been established"
% dialect_name)
output = []
@@ -64,7 +65,8 @@ class DialectDirective(Directive):
ids=["dialect-%s-%s-url" % (dialect_name, dbapi_name)]
)
if "url" in content:
- text = "Documentation and download information (if applicable) "\
+ text = "Documentation and download information "\
+ "(if applicable) "\
"for %s is available at:\n" % content["name"]
uri = content['url']
sec.append(
@@ -82,7 +84,8 @@ class DialectDirective(Directive):
nodes.paragraph('', '',
nodes.Text(text, text),
nodes.reference('', '',
- nodes.Text(content['driverurl'], content['driverurl']),
+ nodes.Text(content['driverurl'],
+ content['driverurl']),
refuri=content['driverurl']
)
)
@@ -113,7 +116,8 @@ class DialectDirective(Directive):
self.bullets = nodes.bullet_list()
text = "The following dialect/DBAPI options are available. "\
- "Please refer to individual DBAPI sections for connect information."
+ "Please refer to individual DBAPI sections "\
+ "for connect information."
sec = nodes.section('',
nodes.paragraph('', '',
nodes.Text(
@@ -135,7 +139,8 @@ class DialectDirective(Directive):
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)
+ relative_uri = env.app.builder.get_relative_uri(
+ dialect_directive.docname, self.docname)
except:
relative_uri = ""
list_node = nodes.list_item('',
diff --git a/doc/build/builder/mako.py b/doc/build/builder/mako.py
index 8d2c1ac3e..770fcae55 100644
--- a/doc/build/builder/mako.py
+++ b/doc/build/builder/mako.py
@@ -25,16 +25,23 @@ class MakoBridge(TOCMixin, TemplateBridge):
]
)
- if rtd:
- # RTD layout, imported from sqlalchemy.org
+ if rtd and builder.config['site_base']:
import urllib2
- template = urllib2.urlopen(builder.config['site_base'] + "/docs_adapter.mako").read()
- self.lookup.put_string("docs_adapter.mako", template)
+ if builder_config['site_adapter_file']:
+ # remote site layout / startup files
+ template_name = builder_config['site_adapter_template']
- setup_ctx = urllib2.urlopen(builder.config['site_base'] + "/docs_adapter.py").read()
- lcls = {}
- exec(setup_ctx, lcls)
- self.setup_ctx = lcls['setup_context']
+ 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
@@ -64,5 +71,7 @@ def setup(app):
app.config['template_bridge'] = "builder.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')
diff --git a/doc/build/builder/scss.py b/doc/build/builder/scss.py
new file mode 100644
index 000000000..ea7247096
--- /dev/null
+++ b/doc/build/builder/scss.py
@@ -0,0 +1,46 @@
+from __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):
+ to_gen = []
+ for static_path in app.env.config.html_static_path:
+ path = os.path.join(app.env.srcdir, static_path)
+ for fname in os.listdir(path):
+ name, ext = os.path.splitext(fname)
+ if ext != ".scss":
+ continue
+ to_gen.append((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):
+ to_gen = app._builder_scss
+
+ compiler = Scss(scss_opts={"style": "expanded"})
+ 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)
+
diff --git a/doc/build/builder/toc.py b/doc/build/builder/toc.py
index 6ac75209a..89b6dec51 100644
--- a/doc/build/builder/toc.py
+++ b/doc/build/builder/toc.py
@@ -1,6 +1,16 @@
class TOCMixin(object):
def get_current_subtoc(self, current_page_name, current_page_title):
- """Return a TOC for sub-files of the current file.
+ """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.
"""
@@ -11,6 +21,15 @@ class TOCMixin(object):
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'):
@@ -22,10 +41,10 @@ class TOCMixin(object):
if refuri is not None:
name = elem.children[0].rawsource
remainders = elem.children[1:]
-
- # not really sure what get_toc_for() does, seems
- # to keep returning nodes past what is local,
- # so just do a brute force filter here
+ # 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 (
@@ -37,8 +56,7 @@ class TOCMixin(object):
# 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,
- # why bother.
+ # just get the full get_toctree_for(), it's enormous.
if outer and name == current_page_title:
for ent in _locate_nodes([local_tree], level + 1, False):
yield ent
@@ -59,13 +77,20 @@ class TOCMixin(object):
stack.append(new_collection)
elif level < levels[-1]:
while levels and level < levels[-1]:
- stack.pop(-1)
levels.pop(-1)
+ if level > levels[-1]:
+ levels.append(level)
+ else:
+ stack.pop(-1)
stack[-1].append((refuri, name))
return stack
def _render_nodes(stack, searchfor, level=0, nested_element=False):
+ # this is me being lazy about dealing with docutils renderers,
+ # and just programmatically rendering out. A real Sphinx
+ # extension / feature would obviously need to use the idiomatic
+ # docutils renderers.
if stack:
indent = " " * level
printing = nested_element or searchfor in stack
@@ -78,15 +103,19 @@ class TOCMixin(object):
if not stack or isinstance(stack[0], tuple):
if printing:
if as_links:
- yield "%s<li><a href='%s'>%s</a></li>" % ((indent,) + elem)
+ yield "%s<li><a href='%s'>%s</a></li>" % (
+ (indent,) + elem)
else:
- yield "%s<li><strong>%s</strong></li>" % (indent, elem[1])
+ yield "%s<li><strong>%s</strong></li>" % (
+ indent, elem[1])
elif isinstance(stack[0], list):
if printing:
if as_links:
- yield "%s<li><a href='%s'>%s</a>" % ((indent,) + elem)
+ yield "%s<li><a href='%s'>%s</a>" % (
+ (indent,) + elem)
else:
- yield "%s<li><strong>%s</strong>" % (indent, elem[1])
+ yield "%s<li><strong>%s</strong>" % (
+ indent, elem[1])
for sub in _render_nodes(
stack[0], searchfor,
level=level + 1,
@@ -98,7 +127,8 @@ class TOCMixin(object):
elif isinstance(elem, list):
for sub in _render_nodes(
elem, searchfor,
- level=level + 1, nested_element=nested_element):
+ level=level + 1,
+ nested_element=nested_element):
yield sub
if printing:
yield (" " * level) + "</ul>"
diff --git a/doc/build/conf.py b/doc/build/conf.py
index 5277134e7..32955f68a 100644
--- a/doc/build/conf.py
+++ b/doc/build/conf.py
@@ -41,6 +41,7 @@ extensions = [
'builder.mako',
'builder.sqlformatter',
'builder.viewsource',
+ 'builder.scss'
]
# Add any paths that contain templates here, relative to this directory.
@@ -74,6 +75,21 @@ changelog_render_pullreq = {
changelog_render_changeset = "http://www.sqlalchemy.org/trac/changeset/%s"
+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",
+}
# The encoding of source files.
#source_encoding = 'utf-8-sig'
@@ -97,6 +113,8 @@ release = "1.0.0"
release_date = "Not released"
site_base = os.environ.get("RTD_SITE_BASE", "http://www.sqlalchemy.org")
+site_adapter_template = "docs_adapter.mako"
+site_adapter_py = "docs_adapter.py"
# arbitrary number recognized by builders.py, incrementing this
# will force a rebuild
diff --git a/doc/build/static/docs.css b/doc/build/static/docs.scss
index e854d34c2..8597a993f 100644
--- a/doc/build/static/docs.css
+++ b/doc/build/static/docs.scss
@@ -1,11 +1,23 @@
+$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;
+
/* global */
.body-background {
- background-color: #FDFBFC;
+ background-color: $primary-background-color;
}
body {
- background-color: #FDFBFC;
+ background-color: $primary-background-color;
margin:0 38px;
color:#333333;
}
@@ -22,12 +34,10 @@ form {
/* hyperlinks */
a:link, a:visited, a:active {
- /*color:#0000FF;*/
color: #990000;
}
a:hover {
color: #FF0000;
- /*color:#700000;*/
text-decoration:underline;
}
@@ -72,26 +82,28 @@ a.headerlink:hover {
/* header/footer elements */
-#docs-header h1 {
- font-size:20px;
- color: #222222;
- margin: 0;
- padding: 0;
-}
-
#docs-header {
- font-family:Verdana,sans-serif;
+ 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: Verdana, sans-serif;
- background-color: #FBFBEE;
- border: solid 1px #CCC;
+ font-family: $primary-font-family;
+ background-color: $popout-color;
+ border: $border-style;
font-size:.8em;
}
@@ -116,12 +128,12 @@ a.headerlink:hover {
#docs-version-header {
position: absolute;
- right: 0;
- bottom: 0;
+ right: 8px;
+ bottom: 8px;
}
.docs-navigation-links {
- font-family:Verdana,sans-serif;
+ font-family: $primary-font-family;
}
#docs-bottom-navigation {
@@ -137,7 +149,7 @@ a.headerlink:hover {
#docs-header h1,
#docs-top-navigation h1,
#docs-top-navigation h2 {
- font-family:Tahoma,Geneva,sans-serif;
+ font-family: $top-header-font-family;
font-weight:normal;
}
@@ -178,10 +190,7 @@ a.headerlink:hover {
#docs-sidebar,
#index-nav
{
- /*font-family: helvetica, arial, sans-serif;
- font-size:.9em;*/
-
- font-family: Verdana, sans-serif;
+ font-family: $primary-font-family;
font-size:.85em;
line-height:1.5em;
@@ -222,10 +231,10 @@ a.headerlink:hover {
#docs-sidebar {
font-size:.85em;
- border: solid 1px #CCC;
+ border: $border-style;
z-index: 3;
- background-color: #EFEFEF;
+ background-color: $sidebar-color;
}
#index-nav {
@@ -302,9 +311,9 @@ a.headerlink:hover {
#docs-sidebar h3, #docs-sidebar h4 {
- background-color: #DDDDDD;
- color: #222222;
- font-family: Verdana,sans-serif;
+ 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;
@@ -318,7 +327,7 @@ a.headerlink:hover {
}
#docs-sidebar h3 a, #docs-sidebar h4 a {
- color: #222222;
+ color: $sidebar-header-color;
}
#docs-sidebar ul {
margin: 10px 10px 10px 0px;
@@ -341,7 +350,7 @@ a.headerlink:hover {
background-color:#FFFFFF;
padding:1px 10px 10px 10px;
- border: solid 1px #CCC;
+ border: $border-style;
margin-top:10px;
}
@@ -354,7 +363,7 @@ a.headerlink:hover {
#docs-body h2,
#docs-body h3,
#docs-body h4 {
- font-family:Helvetica, Arial, sans-serif;
+ font-family: $header-font-family;
}
#docs-body #sqlalchemy-documentation h1 {
@@ -395,7 +404,7 @@ a.headerlink:hover {
#docs-container pre {
background-color: #f0f0f0;
- border: solid 1px #ccc;
+ border: $border-style;
box-shadow: 2px 2px 3px #DFDFDF;
padding:10px;
margin: 5px 0px 5px 0px;
@@ -405,7 +414,7 @@ a.headerlink:hover {
.popup_sql, .show_sql
{
- background-color: #FBFBEE;
+ background-color: $popout-color;
padding:5px 10px;
margin:10px -5px;
border:1px dashed;
@@ -415,7 +424,7 @@ a.headerlink:hover {
#docs-container .sql_link
{
font-weight:normal;
- font-family: arial, sans-serif;
+ font-family: helvetica, arial, sans-serif;
font-size:.9em;
text-transform: uppercase;
color:#990000;
@@ -458,7 +467,7 @@ div.section {
}
div.note, div.warning, p.deprecated, div.topic, div.admonition {
- background-color:#EEFFEF;
+ background-color:$notebox-background-color;
}
.footnote {
@@ -474,7 +483,7 @@ div.faq ul {
}
div.admonition, div.topic, .deprecated, .versionadded, .versionchanged {
- border:1px solid #CCCCCC;
+ border: $border-style;
padding:5px 10px;
font-size:.9em;
margin-top:5px;
@@ -511,7 +520,7 @@ p.sidebar-title {
div.inherited-member {
- border:1px solid #CCCCCC;
+ border: $border-style;
padding:5px 5px;
font-size:.9em;
box-shadow: 2px 2px 3px #DFDFDF;
@@ -652,22 +661,3 @@ div .version-warning {
background:#FFBBBB;
}
-/*div .event-signatures {
- background-color:#F0F0FD;
- padding:0 10px;
- border:1px solid #BFBFBF;
-}*/
-
-/*dl div.floatything {
- display:none;
- position:fixed;
- top:25px;
- left:40px;
- font-size:.95em;
- font-weight: bold;
- border:1px solid;
- background-color: #FFF;
-}
-dl:hover div.floatything {
- display:block;
-}*/
diff --git a/doc/build/templates/layout.mako b/doc/build/templates/layout.mako
index c0bf2bf9f..4520a43cc 100644
--- a/doc/build/templates/layout.mako
+++ b/doc/build/templates/layout.mako
@@ -172,7 +172,7 @@ withsidebar = bool(toc) and current_page_name != 'index'
<div id="docs-sidebar">
- <h3><a href="#">\
+ <h3><a href="${parents[-1]['link'] if parents else '#'}">\
<%block name="show_title">
% if parents:
${parents[-1]['title']}
@@ -182,11 +182,6 @@ withsidebar = bool(toc) and current_page_name != 'index'
</%block>
</a></h3>
- <%
- #if title == 'Schema Definition Language':
- # import pdb
- # pdb.set_trace()
- %>
% if parents:
${parent_toc(current_page_name, title)}
% else: