From: Mike Bayer Date: Sat, 17 Mar 2007 15:14:53 +0000 (+0000) Subject: merged mako doc generation branch X-Git-Tag: rel_0_3_6~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f63e40616635ba2dae49c3a416d9e288a9a0860;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git merged mako doc generation branch --- diff --git a/doc/build/components/autohandler b/doc/build/components/autohandler deleted file mode 100644 index 223b7ff615..0000000000 --- a/doc/build/components/autohandler +++ /dev/null @@ -1,25 +0,0 @@ -<%flags>inherit =None - - - <& REQUEST:title &> - - - - - - - - -% m.call_next() - -
-
- - - - -<%method title> -Documentation - - - diff --git a/doc/build/components/base.myt b/doc/build/components/base.myt deleted file mode 100644 index a9ab69e1b8..0000000000 --- a/doc/build/components/base.myt +++ /dev/null @@ -1,45 +0,0 @@ -<%doc>base.myt - common to all documentation pages. intentionally separate from autohandler, which can be swapped -out for a different one -<%args> - extension="myt" - -<%python scope="init"> - if m.cache_self(key=m.request_component.file): - return - # bootstrap TOC structure from request args, or pickled file if not present. - import cPickle as pickle - import os, time - m.log("base.myt generating from table of contents for file %s" % m.request_component.file) - toc = m.request_args.get('toc') - if toc is None: - filename = os.path.join(os.path.dirname(m.request_component.file), 'table_of_contents.pickle') - toc = pickle.load(file(filename)) - version = toc.version - last_updated = toc.last_updated - -<%method title> - <% m.request_component.attributes.get('title') %> - - -
 
- -
- -
- - -

<% toc.root.doctitle %>

- - - -
Version: <% version %> Last Updated: <% time.strftime('%x %X', time.localtime(last_updated)) %>
-
- -% m.call_next(toc=toc, extension=extension) - -
- - diff --git a/doc/build/components/content_layout.myt b/doc/build/components/content_layout.myt deleted file mode 100644 index 22656c5c99..0000000000 --- a/doc/build/components/content_layout.myt +++ /dev/null @@ -1,15 +0,0 @@ -<%doc>defines the default layout for normal documentation pages (not including the index) -<%args> - extension="myt" - toc - -<%flags>inherit="base.myt" -<%init> - current = toc.get_by_file(m.request_component.attributes['filename']) - - - -<& nav.myt:topnav, item=current, extension=extension, onepage=True &> -
-% m.call_next(toc=toc, extension=extension) -
diff --git a/doc/build/components/formatting.myt b/doc/build/components/formatting.myt deleted file mode 100644 index 6b6cf8032b..0000000000 --- a/doc/build/components/formatting.myt +++ /dev/null @@ -1,167 +0,0 @@ -<%doc>formatting.myt - Provides section formatting elements, syntax-highlighted code blocks, and other special filters. - -<%global> - import string, re - import highlight - - -<%method section> -<%doc>Main section formatting element. -<%args> - toc - path - description=None - onepage=False - -<%init> - item = toc.get_by_path(path) - if item is None: - raise "path: " + path - - - - -
- -<%python> - content = m.content() - re2 = re.compile(r"'''PYESC(.+?)PYESC'''", re.S) - content = re2.sub(lambda m: m.group(1), content) - - -% if item.depth > 1: -

<% description or item.description %>

-% - -
- <% content %> -
- -% if onepage or item.depth > 1: -% if (item.next and item.next.depth >= item.depth): - back to section top -% -% else: - back to section top - <& nav.myt:pagenav, item=item, onepage=onepage &> -% -
- - - - -<%method formatplain> - <%filter> - import re -# f = re.sub(r'\n[\s\t]*\n[\s\t]*', '

\n

', f) - f = re.sub(r'\n[\s\t]*', '

\n

', f) - f = "

" + f + "

" - return f - -<% m.content() | h%> - - - - - -<%method codeline trim="both"> -<% m.content() %> - - -<%method code autoflush=False> -<%args> - title = None - syntaxtype = 'python' - html_escape = False - use_sliders = False - - -<%init> - def fix_indent(f): - f =string.expandtabs(f, 4) - g = '' - lines = string.split(f, "\n") - whitespace = None - for line in lines: - if whitespace is None: - match = re.match(r"^([ ]*).+", line) - if match is not None: - whitespace = match.group(1) - - if whitespace is not None: - line = re.sub(r"^%s" % whitespace, "", line) - - if whitespace is not None or re.search(r"\w", line) is not None: - g += (line + "\n") - - - return g.rstrip() - - p = re.compile(r'
(.*?)
', re.S) - def hlight(match): - return "
" + highlight.highlight(fix_indent(match.group(1)), html_escape = html_escape, syntaxtype = syntaxtype) + "
" - content = p.sub(hlight, "
" + m.content() + "
") - -
"> -% if title is not None: -
<% title %>
-% -<% content %>
- - - - - -<%method popboxlink trim="both"> - <%args> - name=None - show='show' - hide='hide' - - <%init> - if name is None: - name = m.attributes.setdefault('popbox_name', 0) - name += 1 - m.attributes['popbox_name'] = name - name = "popbox_" + repr(name) - -javascript:togglePopbox('<% name %>', '<% show %>', '<% hide %>') - - -<%method popbox trim="both"> -<%args> - name = None - class_ = None - -<%init> - if name is None: - name = 'popbox_' + repr(m.attributes['popbox_name']) - - - - -<%method poplink trim="both"> - <%args> - link='sql' - - <%init> - href = m.scomp('SELF:popboxlink') - - '''PYESC<& nav.myt:link, href=href, text=link, class_="codepoplink" &>PYESC''' - - -<%method codepopper trim="both"> - <%init> - c = m.content() - c = re.sub(r'\n', '
\n', c.strip()) - - <&|SELF:popbox, class_="codepop" &><% c %>
-
-
-<%method poppedcode trim="both">
-	<%init>
-		c = m.content()
-		c = re.sub(r'\n', '
\n', c.strip()) - -
<% c %>
-
diff --git a/doc/build/components/nav.myt b/doc/build/components/nav.myt
deleted file mode 100644
index cdf372028f..0000000000
--- a/doc/build/components/nav.myt
+++ /dev/null
@@ -1,110 +0,0 @@
-<%doc>nav.myt - Provides page navigation elements that are derived from toc.TOCElement structures, including
-individual hyperlinks as well as navigational toolbars and table-of-content listings.
-
-<%method itemlink trim="both">
-    <%args>
-    item
-    anchor=True
-    usefilename=True
-    
-    <%args scope="request">
-        extension='myt'
-    
-    <% item.description %>
-
-
-<%method toclink trim="both">
-    <%args>
-        toc 
-        path
-        description=None
-        extension
-        usefilename=True
-    
-    <%init>
-        item = toc.get_by_path(path)
-        if description is None:
-            if item:
-                description = item.description
-            else:
-                description = path
-    
-% if item:
-    <% description %>
-% else:
-    <% description %>
-%
-
-
-
-<%method link trim="both">
-    <%args>
-        href
-        text
-        class_
-    
-    ><% text %>
-
-
-<%method topnav>
-	<%args>
-		item
-		extension
-		onepage=False
-	
-
- - - -
-
<% item.description %>
-
- <& toc.myt:printtoc, root=item, current=None, full=True, extension=extension, anchor_toplevel=True, onepage=False &> -
-
- -
- - -<%method pagenav> -<%args> - item - onepage=False - -
-
- -% if item.previous is not None: - Previous: <& itemlink, item=item.previous, usefilename=not onepage &> -% # end if - -% if item.next is not None: -% if item.previous is not None: - | -% # end if - - Next: <& itemlink, item=item.next, usefilename=not onepage &> -% # end if - -
-
- diff --git a/doc/build/components/pydoc.myt b/doc/build/components/pydoc.myt deleted file mode 100644 index 48d06ff897..0000000000 --- a/doc/build/components/pydoc.myt +++ /dev/null @@ -1,111 +0,0 @@ -<%doc>pydoc.myt - provides formatting functions for printing docstring.AbstractDoc generated python documentation objects. - -<%global> -import docstring -import sys - -def trim(docstring): - if not docstring: - return '' - # Convert tabs to spaces (following the normal Python rules) - # and split into a list of lines: - lines = docstring.expandtabs().splitlines() - # Determine minimum indentation (first line doesn't count): - indent = sys.maxint - for line in lines[1:]: - stripped = line.lstrip() - if stripped: - indent = min(indent, len(line) - len(stripped)) - # Remove indentation (first line is special): - trimmed = [lines[0].strip()] - if indent < sys.maxint: - for line in lines[1:]: - trimmed.append(line[indent:].rstrip()) - # Strip off trailing and leading blank lines: - while trimmed and not trimmed[-1]: - trimmed.pop() - while trimmed and not trimmed[0]: - trimmed.pop(0) - # Return a single string: - return '\n'.join(trimmed) - - - -<%method obj_doc> - <%args> - obj - toc - extension - -<%init> -if obj.isclass: - links = [] - for elem in obj.inherits: - if isinstance(elem, docstring.ObjectDoc): - links.append(m.scomp("nav.myt:toclink", toc=toc, path=elem.toc_path, extension=extension, description=elem.name)) - else: - links.append(str(elem)) - htmldescription = "class " + obj.classname + "(%s)" % (','.join(links)) -else: - htmldescription = obj.description - - - -<&|formatting.myt:section, toc=toc, path=obj.toc_path, description=htmldescription &> -
<% trim(obj.doc) |h %>
- -% if not obj.isclass and obj.functions: - -<&|formatting.myt:section, toc=toc, path=obj.mod_path &> -% for func in obj.functions: - <& SELF:function_doc, func=func &> -% - - -% else: - -% if obj.functions: -% for func in obj.functions: -% if isinstance(func, docstring.FunctionDoc): - <& SELF:function_doc, func=func &> -% elif isinstance(func, docstring.PropertyDoc): - <& SELF:property_doc, prop=func &> -% -% -% -% - -% if obj.classes: -% for class_ in obj.classes: - <& SELF:obj_doc, obj=class_, toc=toc, extension=extension &> -% -% - - - -<%method function_doc> - <%args>func -
- - <% func.name %>(<% ", ".join(map(lambda k: "%s" % k, func.arglist))%>) -
-
<% trim(func.doc) |h %>
-
-
- - - -<%method property_doc> - <%args> - prop - -
- - <% prop.name %> -
-
<% trim(prop.doc) |h%>
-
-
- - - diff --git a/doc/build/components/toc.myt b/doc/build/components/toc.myt deleted file mode 100644 index ac45140b12..0000000000 --- a/doc/build/components/toc.myt +++ /dev/null @@ -1,99 +0,0 @@ -<%doc>toc.myt - prints full table of contents listings given toc.TOCElement strucures - -<%method toc> - <%args> - toc - extension - onepage=False - - - -
- - -

Table of Contents

-    - (view full table) -

- -
- <& printtoc, root = toc, current = None, full = False, children=False, extension=extension, anchor_toplevel=False, onepage=onepage &> -
- -
- - -
- -

Table of Contents: Full

-    - (view brief table) -

- -
- <& printtoc, root = toc, current = None, full = True, children=True, extension=extension, anchor_toplevel=False, onepage=onepage &> -
- -
- - - -<%method printtoc> -<%args> - root - current = None - full = False - children = True - extension - anchor_toplevel=False - onepage=False - - - - - -<%def printtocelement> -<%doc>prints a TOCElement as a table of contents item and prints its immediate child items - <%args> - item - bold = False - full = False - children = True - extension - anchor_toplevel - onepage=False - - -
  • " href="<% item.get_link(extension=extension, anchor=anchor_toplevel, usefilename=not onepage) %>"><% item.description %>
  • - -% if children: - -% - - -<%def printsmtocelem> - <%args> - item - children = False - extension - onepage=False - -
  • <% item.description %>
  • - -% if children: - -% - - diff --git a/doc/build/content/datamapping.txt b/doc/build/content/datamapping.txt index ba70e05a08..db26fa0306 100644 --- a/doc/build/content/datamapping.txt +++ b/doc/build/content/datamapping.txt @@ -130,6 +130,8 @@ Some of the above examples above illustrate the usage of the mapper's Table obje {python} userlist = session.query(User).select(User.c.user_id==12) +Full documentation for Query's API : [Query](rel:docstrings_sqlalchemy.orm.query_Query). + ### Saving Objects {@name=saving} When objects corresponding to mapped classes are created or manipulated, all changes are logged by the `Session` object. The changes are then written to the database when an application calls `flush()`. This pattern is known as a *Unit of Work*, and has many advantages over saving individual objects or attributes on those objects with individual method invocations. Domain models can be built with far greater complexity with no concern over the order of saves and deletes, excessive database round-trips and write operations, or deadlocking issues. The `flush()` operation batches its SQL statements into a transaction, and can also perform optimistic concurrency checks (using a version id column) to ensure the proper number of rows were in fact affected (not supported with the current MySQL drivers). diff --git a/doc/build/content/docstrings.html b/doc/build/content/docstrings.html new file mode 100644 index 0000000000..e8b480f29b --- /dev/null +++ b/doc/build/content/docstrings.html @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +<%inherit file="content_layout.html"/> +<%page args="toc, extension, paged"/> +<%namespace name="formatting" file="formatting.html"/> +<%namespace name="nav" file="nav.html"/> +<%namespace name="pydoc" file="pydoc.html"/> +<%def name="title()">SQLAlchemy 0.3 Documentation - Modules and Classes +<%! + filename = 'docstrings' +%> diff --git a/doc/build/content/docstrings.myt b/doc/build/content/docstrings.myt deleted file mode 100644 index 685c0314fa..0000000000 --- a/doc/build/content/docstrings.myt +++ /dev/null @@ -1,19 +0,0 @@ -<%flags>inherit='content_layout.myt' -<%attr> - title='Modules and Classes' - filename='docstrings' - -<%args> - toc - extension - -<%init> - import cPickle as pickle - import os - filename = os.path.join(os.path.dirname(self.file), 'compiled_docstrings.pickle') - data = pickle.load(file(filename)) - - -% for obj in data: -<& pydoc.myt:obj_doc, obj=obj, toc=toc, extension=extension &> -% diff --git a/doc/build/content/documentation.html b/doc/build/content/documentation.html new file mode 100644 index 0000000000..c850749b3b --- /dev/null +++ b/doc/build/content/documentation.html @@ -0,0 +1,25 @@ +<%inherit file="base.html"/> +<%namespace name="tocns" file="toc.html"/> +<%namespace name="nav" file="nav.html"/> +<%page args="toc, extension"/> + +${tocns.toc(toc, extension=extension, paged=False)} + +<%def name="title()"> + SQLAlchemy Documentation + + +% for file in toc.filenames: + <% + item = toc.get_by_file(file) + %> + + + + % if not item.requires_paged: + ${nav.pagenav(item=item, paged=False, extension=extension)} + + ${self.get_namespace(file + '.html').body(toc=toc, extension=extension, paged=False)} + % endif +% endfor + diff --git a/doc/build/content/documentation.myt b/doc/build/content/documentation.myt deleted file mode 100644 index af73c2a610..0000000000 --- a/doc/build/content/documentation.myt +++ /dev/null @@ -1,20 +0,0 @@ -<%flags>inherit='base.myt' -<%args> - extension - toc - -<%method title> - SQLAlchemy Documentation - -<& index.myt, toc=toc, extension=extension, onepage=True &> -% for file in toc.filenames: -% current = toc.get_by_file(file) - -<& nav.myt:pagenav, item=current, extension=extension, onepage=True &> -
    -
    <% current.description %>
    -
    -
    -% m.comp(file + ".myt", toc=toc, extension=extension, onepage=True) -
    -% diff --git a/doc/build/content/index.html b/doc/build/content/index.html new file mode 100644 index 0000000000..e4f3518cf0 --- /dev/null +++ b/doc/build/content/index.html @@ -0,0 +1,6 @@ +<%inherit file="base.html"/> +<%page args="toc, extension"/> + +<%namespace name="tocns" file="toc.html"/> + +${tocns.toc(toc, paged=True, extension=extension)} diff --git a/doc/build/content/index.myt b/doc/build/content/index.myt deleted file mode 100644 index 275d61f318..0000000000 --- a/doc/build/content/index.myt +++ /dev/null @@ -1,8 +0,0 @@ -<%flags>inherit='base.myt' -<%args> - extension - toc - onepage=False - - -<& toc.myt:toc, toc=toc, extension=extension, onepage=onepage &> diff --git a/doc/build/gen_docstrings.py b/doc/build/gen_docstrings.py index b3fc13e943..2cef463d4e 100644 --- a/doc/build/gen_docstrings.py +++ b/doc/build/gen_docstrings.py @@ -1,5 +1,6 @@ from toc import TOCElement import docstring +import re import sqlalchemy.schema as schema import sqlalchemy.types as types @@ -16,10 +17,12 @@ import sqlalchemy.ext.selectresults as selectresults def make_doc(obj, classes=None, functions=None): """generate a docstring.ObjectDoc structure for an individual module, list of classes, and list of functions.""" - return docstring.ObjectDoc(obj, classes=classes, functions=functions) + obj = docstring.ObjectDoc(obj, classes=classes, functions=functions) + return (obj.name, obj) def make_all_docs(): """generate a docstring.AbstractDoc structure.""" + print "generating docstrings" objects = [ make_doc(obj=sql), make_doc(obj=schema), @@ -42,7 +45,8 @@ def make_all_docs(): def create_docstring_toc(data, root): """given a docstring.AbstractDoc structure, create new TOCElement nodes corresponding to the elements and cross-reference them back to the doc structure.""" - root = TOCElement("docstrings", name="docstrings", description="Generated Documentation", parent=root) + root = TOCElement("docstrings", name="docstrings", description="Generated Documentation", parent=root, requires_paged=True) + files = [] def create_obj_toc(obj, toc): if obj.isclass: s = [] @@ -52,21 +56,47 @@ def create_docstring_toc(data, root): else: s.append(str(elem)) description = "class " + obj.classname + "(%s)" % (','.join(s)) + filename = toc.filename else: description = obj.description - - toc = TOCElement("docstrings", obj.name, description, parent=toc) + filename = re.sub(r'\W', '_', obj.name) + + toc = TOCElement(filename, obj.name, description, parent=toc, requires_paged=True) obj.toc_path = toc.path - + if not obj.isclass: + create_module_file(obj, toc) + files.append(filename) + if not obj.isclass and obj.functions: - functoc = TOCElement("docstrings", name="modfunc", description="Module Functions", parent=toc) + functoc = TOCElement(toc.filename, name="modfunc", description="Module Functions", parent=toc) obj.mod_path = functoc.path + for func in obj.functions: + t = TOCElement(toc.filename, name=func.name, description=func.name + "()", parent=functoc) + func.toc_path = t.path + #elif obj.functions: + # for func in obj.functions: + # t = TOCElement(toc.filename, name=func.name, description=func.name, parent=toc) + # func.toc_path = t.path if obj.classes: for class_ in obj.classes: create_obj_toc(class_, toc) - for obj in data: + for key, obj in data: create_obj_toc(obj, root) - return data + return files +def create_module_file(obj, toc): + outname = 'output/%s.html' % toc.filename + print "->", outname + header = """# -*- coding: utf-8 -*- + <%%inherit file="module.html"/> + <%%def name="title()">%s - %s + ## This file is generated. Edit the .txt files instead of this one. + <%%! + filename = '%s' + docstring = '%s' + %%> + """ % (toc.root.doctitle, obj.description, toc.filename, obj.name) + file(outname, 'w').write(header) + return outname \ No newline at end of file diff --git a/doc/build/genhtml.py b/doc/build/genhtml.py index 4b6a0e4c59..ab5f911d5e 100644 --- a/doc/build/genhtml.py +++ b/doc/build/genhtml.py @@ -1,15 +1,17 @@ #!/usr/bin/env python import sys,re,os,shutil -import myghty.interp -import myghty.exception as exception import cPickle as pickle sys.path = ['../../lib', './lib/'] + sys.path import gen_docstrings, read_markdown, toc +from mako.lookup import TemplateLookup +from mako import exceptions, runtime +import time files = [ 'index', + 'documentation', 'tutorial', 'dbengine', 'metadata', @@ -28,38 +30,42 @@ version = '0.3.5' root = toc.TOCElement('', 'root', '', version=version, doctitle=title) -shutil.copy('./content/index.myt', './output/index.myt') -shutil.copy('./content/docstrings.myt', './output/docstrings.myt') -shutil.copy('./content/documentation.myt', './output/documentation.myt') +shutil.copy('./content/index.html', './output/index.html') +shutil.copy('./content/docstrings.html', './output/docstrings.html') +shutil.copy('./content/documentation.html', './output/documentation.html') read_markdown.parse_markdown_files(root, files) docstrings = gen_docstrings.make_all_docs() -gen_docstrings.create_docstring_toc(docstrings, root) +doc_files = gen_docstrings.create_docstring_toc(docstrings, root) pickle.dump(docstrings, file('./output/compiled_docstrings.pickle', 'w')) pickle.dump(root, file('./output/table_of_contents.pickle', 'w')) -component_root = [ - {'components': './components'}, - {'output' :'./output'} -] +template_dirs = ['./templates', './output'] output = os.path.dirname(os.getcwd()) -interp = myghty.interp.Interpreter(component_root = component_root, output_encoding='utf-8') +lookup = TemplateLookup(template_dirs, output_encoding='utf-8') -def genfile(name, toc): - infile = name + ".myt" - outname = os.path.join(os.getcwd(), '../', name + ".html") +def genfile(name, outname): + infile = name + ".html" outfile = file(outname, 'w') print infile, '->', outname - interp.execute(infile, out_buffer=outfile, request_args={'toc':toc,'extension':'html'}, raise_error=True) - -try: - for filename in files: - genfile(filename, root) - genfile("documentation", root) -except exception.Error, e: - sys.stderr.write(e.textformat()) + t = lookup.get_template(infile) + outfile.write(t.render(attributes={})) + +for filename in files: + try: + genfile(filename, os.path.join(os.getcwd(), '../', filename + ".html")) + except: + print exceptions.text_error_template().render() + +for filename in doc_files: + try: + genfile(filename, os.path.join(os.getcwd(), '../', os.path.basename(filename) + ".html")) + except: + print exceptions.text_error_template().render() + + diff --git a/doc/build/lib/docstring.py b/doc/build/lib/docstring.py index b4ddcff4ef..d234414bda 100644 --- a/doc/build/lib/docstring.py +++ b/doc/build/lib/docstring.py @@ -128,7 +128,7 @@ class FunctionDoc(AbstractDoc): if varkw is not None: argstrings.append("**%s" % varkw) self.argstrings = self.arglist = argstrings - self.name = "def " + func.__name__ + self.name = func.__name__ self.link = func.__name__ self.doc = func.__doc__ def accept_visitor(self, visitor): @@ -138,7 +138,7 @@ class PropertyDoc(AbstractDoc): def __init__(self, name, prop): super(PropertyDoc, self).__init__(prop) self.doc = prop.__doc__ - self.name = name + " = property()" + self.name = name self.link = name def accept_visitor(self, visitor): visitor.visit_property(self) diff --git a/doc/build/lib/toc.py b/doc/build/lib/toc.py index 91cfb0d50e..dcad5d5c63 100644 --- a/doc/build/lib/toc.py +++ b/doc/build/lib/toc.py @@ -4,25 +4,26 @@ defines a pickleable, recursive "table of contents" datastructure. TOCElements define a name, a description, and also a uniquely-identifying "path" which is used to generate hyperlinks between document sections. """ -import time +import time, re toc_by_file = {} toc_by_path = {} filenames = [] class TOCElement(object): - def __init__(self, filename, name, description, parent=None, version=None, last_updated=None, doctitle=None, **kwargs): + def __init__(self, filename, name, description, parent=None, version=None, last_updated=None, doctitle=None, requires_paged=False, **kwargs): self.filename = filename - self.name = name + self.name = re.sub(r'[<>&;%]', '', name) self.description = description self.parent = parent self.content = None + self.filenames = filenames self.toc_by_path = toc_by_path self.toc_by_file = toc_by_file - self.filenames = filenames self.last_updated = time.time() self.version = version self.doctitle = doctitle + self.requires_paged = requires_paged (self.path, self.depth) = self._create_path() #print "NEW TOC:", self.path for key, value in kwargs.iteritems(): @@ -35,7 +36,8 @@ class TOCElement(object): toc_by_file[self.filename] = self if self.filename: filenames.append(self.filename) - self.root = self.parent or self + + self.root = self.parent and self.parent.root or self self.content = None self.previous = None @@ -46,7 +48,11 @@ class TOCElement(object): self.previous = parent.children[-1] parent.children[-1].next = self parent.children.append(self) - + if parent is not parent.root: + self.up = parent + else: + self.up = None + def get_page_root(self): return self.toc_by_file[self.filename] @@ -57,14 +63,15 @@ class TOCElement(object): return self.toc_by_file[filename] def get_link(self, extension='html', anchor=True, usefilename=True): - if usefilename: + if usefilename or self.requires_paged: if anchor: return "%s.%s#%s" % (self.filename, extension, self.path) else: return "%s.%s" % (self.filename, extension) else: return "#%s" % (self.path) - + + def _create_path(self): elem = self tokens = [] diff --git a/doc/build/read_markdown.py b/doc/build/read_markdown.py index 0b4c8b3eb6..de3386be2b 100644 --- a/doc/build/read_markdown.py +++ b/doc/build/read_markdown.py @@ -16,13 +16,14 @@ except: import markdown def dump_tree(elem, stream): - if elem.tag.startswith('MYGHTY:'): - dump_myghty_tag(elem, stream) + if elem.tag.startswith('MAKO:'): + dump_mako_tag(elem, stream) else: - if len(elem.attrib): - stream.write("<%s %s>" % (elem.tag, " ".join(["%s=%s" % (key, repr(val)) for key, val in elem.attrib.iteritems()]))) - else: - stream.write("<%s>" % elem.tag) + if elem.tag != 'html': + if len(elem.attrib): + stream.write("<%s %s>" % (elem.tag, " ".join(["%s=%s" % (key, repr(val)) for key, val in elem.attrib.iteritems()]))) + else: + stream.write("<%s>" % elem.tag) if elem.text: stream.write(elem.text) for child in elem: @@ -31,24 +32,17 @@ def dump_tree(elem, stream): stream.write(child.tail) stream.write("" % elem.tag) -def dump_myghty_tag(elem, stream): - tag = elem.tag[7:] - params = ', '.join(['%s=%s' % i for i in elem.items()]) - pipe = '' - if elem.text or len(elem): - pipe = '|' - comma = '' - if params: - comma = ', ' - stream.write('<&%s%s%s%s&>' % (pipe, tag, comma, params)) - if pipe: - if elem.text: - stream.write(elem.text) - for n in elem: - dump_tree(n, stream) - if n.tail: - stream.write(n.tail) - stream.write("") +def dump_mako_tag(elem, stream): + tag = elem.tag[5:] + params = ','.join(['%s=%s' % i for i in elem.items()]) + stream.write('<%%call expr="%s(%s)">' % (tag, params)) + if elem.text: + stream.write(elem.text) + for n in elem: + dump_tree(n, stream) + if n.tail: + stream.write(n.tail) + stream.write("") def create_toc(filename, tree, tocroot): title = [None] @@ -80,7 +74,7 @@ def create_toc(filename, tree, tocroot): level[0] = taglevel - tag = et.Element("MYGHTY:formatting.myt:section", path=literal(current[0].path), toc="toc", onepage="onepage") + tag = et.Element("MAKO:formatting.section", path=repr(current[0].path), paged='paged', extension='extension', toc='toc') tag.text = (node.tail or "") + '\n' tag.tail = '\n' tag[:] = content @@ -123,9 +117,9 @@ def process_rel_href(tree): (bold, path) = m.group(1,2) text = a.text if text == path: - tag = et.Element("MYGHTY:nav.myt:toclink", path=literal(path), toc="toc", extension="extension", onepage="onepage") + tag = et.Element("MAKO:nav.toclink", path=repr(path), extension='extension', paged='paged', toc='toc') else: - tag = et.Element("MYGHTY:nav.myt:toclink", path=literal(path), description=literal(text), toc="toc", extension="extension", onepage="onepage") + tag = et.Element("MAKO:nav.toclink", path=repr(path), description=repr(text), extension='extension', paged='paged', toc='toc') a_parent = parent[a] if bold: bold = et.Element('strong') @@ -136,42 +130,32 @@ def process_rel_href(tree): tag.tail = a.tail a_parent[index(a_parent, a)] = tag -def replace_pre_with_myt(tree): - def splice_code_tag(pre, text, type=None, title=None): +def replace_pre_with_mako(tree): + def splice_code_tag(pre, text, code=None, title=None): doctest_directives = re.compile(r'#\s*doctest:\s*[+-]\w+(,[+-]\w+)*\s*$', re.M) text = re.sub(doctest_directives, '', text) - # process '>>>' to have quotes around it, to work with the myghty python + # process '>>>' to have quotes around it, to work with the pygments # syntax highlighter which uses the tokenize module text = re.sub(r'>>> ', r'">>>" ', text) - # indent two spaces. among other things, this helps comment lines "# " from being - # consumed as Myghty comments. - text = re.compile(r'^(?!<&)', re.M).sub(' ', text) - sqlre = re.compile(r'{sql}(.*?)((?:SELECT|INSERT|DELETE|UPDATE|CREATE|DROP|PRAGMA|DESCRIBE).*?)\n\s*(\n|$)', re.S) if sqlre.search(text) is not None: use_sliders = False else: use_sliders = True - text = sqlre.sub(r"<&formatting.myt:poplink&>\1\n<&|formatting.myt:codepopper, link='sql'&>\2\n\n", text) + text = sqlre.sub(r"""${formatting.poplink()}\1\n<%call expr="formatting.codepopper()">\2\n\n""", text) sqlre2 = re.compile(r'{opensql}(.*?)((?:SELECT|INSERT|DELETE|UPDATE|CREATE|DROP).*?)\n\s*(\n|$)', re.S) - text = sqlre2.sub(r"<&|formatting.myt:poppedcode &>\1\n\2\n\n", text) + text = sqlre2.sub(r"<%call expr='formatting.poppedcode()' >\1\n\2\n\n", text) - opts = {} - if type == 'python': - opts['syntaxtype'] = literal('python') - else: - opts['syntaxtype'] = None - - if title is not None: - opts['title'] = literal(title) - + tag = et.Element("MAKO:formatting.code") + if code: + tag.attrib["syntaxtype"] = repr(code) + if title: + tag.attrib["title"] = repr(title) if use_sliders: - opts['use_sliders'] = True - - tag = et.Element("MYGHTY:formatting.myt:code", **opts) + tag.attrib['use_sliders'] = True tag.text = text pre_parent = parents[pre] @@ -181,16 +165,27 @@ def replace_pre_with_myt(tree): parents = get_parent_map(tree) for precode in tree.findall('.//pre/code'): - m = re.match(r'\{(python|code)(?: title="(.*?)"){0,1}\}', precode.text.lstrip()) + reg = re.compile(r'\{(python|code)(?: title="(.*?)"){0,1}\}(.*)', re.S) + m = reg.match(precode[0].text.lstrip()) if m: code = m.group(1) title = m.group(2) - text = precode.text.lstrip() + text = m.group(3) text = re.sub(r'{(python|code).*?}(\n\s*)?', '', text) - splice_code_tag(parents[precode], text, type=code, title=title) + splice_code_tag(parents[precode], text, code=code, title=title) elif precode.text.lstrip().startswith('>>> '): splice_code_tag(parents[precode], precode.text) +def safety_code(tree): + parents = get_parent_map(tree) + for code in tree.findall('.//code'): + tag = et.Element('%text') + if parents[code].tag != 'pre': + tag.attrib["filter"] = "h" + tag.text = code.text + code.append(tag) + code.text = "" + def reverse_parent(parent, item): for n, i in enumerate(parent): if i is item: @@ -200,20 +195,17 @@ def get_parent_map(tree): return dict([(c, p) for p in tree.getiterator() for c in p]) def header(toc, title, filename): - return """#encoding: utf-8 -<%%flags> - inherit='content_layout.myt' - -<%%args> - toc - extension - onepage=False - -<%%attr> - title='%s - %s' + return \ +"""# -*- coding: utf-8 -*- +<%%inherit file="content_layout.html"/> +<%%page args="toc, extension, paged"/> +<%%namespace name="formatting" file="formatting.html"/> +<%%namespace name="nav" file="nav.html"/> +<%%def name="title()">%s - %s +<%%! filename = '%s' - -<%%doc>This file is generated. Edit the .txt files instead of this one. +%%> +## This file is generated. Edit the .txt files instead of this one. """ % (toc.root.doctitle, title, filename) class utf8stream(object): @@ -230,9 +222,10 @@ def parse_markdown_files(toc, files): html = markdown.markdown(file(infile).read()) tree = et.fromstring("" + html + "") (title, toc_element) = create_toc(inname, tree, toc) - replace_pre_with_myt(tree) + safety_code(tree) + replace_pre_with_mako(tree) process_rel_href(tree) - outname = 'output/%s.myt' % inname + outname = 'output/%s.html' % inname print infile, '->', outname outfile = utf8stream(file(outname, 'w')) outfile.write(header(toc, title, inname)) diff --git a/doc/build/templates/autohandler b/doc/build/templates/autohandler new file mode 100644 index 0000000000..4d5aaf0f9c --- /dev/null +++ b/doc/build/templates/autohandler @@ -0,0 +1,30 @@ + + + + ${self.title()} + ${self.style()} +<%def name="style()"> + + + + +${next.body()} + + + + +<%def name="style()"> + + + + + % if parent: + ${parent.style()} + % endif + + +<%def name="title()"> +Documentation + + + diff --git a/doc/build/templates/base.html b/doc/build/templates/base.html new file mode 100644 index 0000000000..76a2d8a45b --- /dev/null +++ b/doc/build/templates/base.html @@ -0,0 +1,41 @@ +<%! + from mako.ext.autohandler import autohandler +%> +<%inherit file="${autohandler(template, context)}"/> +<%page cached="False" cache_key="${self.filename}"/> + +<%doc> + base.html - common to all documentation pages. intentionally separate + from autohandler, which can be swapped out for a different one + + +<% + # bootstrap TOC structure from request args, or pickled file if not present. + import cPickle as pickle + import os, time + #print "%s generating from table of contents for file %s" % (local.filename, self.filename) + filename = os.path.join(os.path.dirname(self.filename), 'table_of_contents.pickle') + toc = pickle.load(file(filename)) + version = toc.version + last_updated = toc.last_updated + + kwargs = context.kwargs + kwargs.setdefault('extension', 'html') + extension = kwargs['extension'] + kwargs.setdefault('paged', True) + kwargs.setdefault('toc', toc) +%> + + + + +

    ${toc.root.doctitle}

    + + + +
    Version: ${version} Last Updated: ${time.strftime('%x %X', time.localtime(last_updated))}
    + +${next.body(**kwargs)} + + + diff --git a/doc/build/templates/content_layout.html b/doc/build/templates/content_layout.html new file mode 100644 index 0000000000..e1cf6f4443 --- /dev/null +++ b/doc/build/templates/content_layout.html @@ -0,0 +1,16 @@ +## defines the default layout for normal documentation pages (not including the index) +<%inherit file="base.html"/> +<%page args="toc, extension, paged"/> +<%namespace file="nav.html" import="topnav, pagenav, bottomnav"/> + +<% + current = toc.get_by_file(self.template.module.filename) +%> + + + +${topnav(item=current, toc=toc, extension=extension, paged=paged)} + +${next.body(toc=toc, extension=extension, paged=paged)} + +${bottomnav(item=current, extension=extension, paged=paged)} \ No newline at end of file diff --git a/doc/build/templates/formatting.html b/doc/build/templates/formatting.html new file mode 100644 index 0000000000..e0983983e3 --- /dev/null +++ b/doc/build/templates/formatting.html @@ -0,0 +1,138 @@ +## formatting.myt - Provides section formatting elements, syntax-highlighted code blocks, and other special filters. +<%! + import string, re, cgi + from mako import filters + import highlight + + def plainfilter(f): + f = re.sub(r'\n[\s\t]*\n[\s\t]*', '

    \n

    ', f) + f = "

    " + f + "

    " + return f + +%> + +<%namespace name="nav" file="nav.html"/> + +<%def name="section(toc, path, paged, extension, description=None)"> + ## Main section formatting element. + <% + content = capture(caller.body) + re2 = re.compile(r"'''PYESC(.+?)PYESC'''", re.S) + content = re2.sub(lambda m: m.group(1), content) + + item = toc.get_by_path(path) + subsection = item.depth > 1 + %> + + +
    + + % if (subsection): +

    ${description or item.description}

    + % endif + + ${content} + + % if (subsection and item.next and item.next.depth >= item.depth) or not subsection: + % if paged: + back to section top + % else: + back to section top + % endif + % endif +
    + + + + +<%def name="formatplain()" filter="plainfilter"> + ${ caller.body() | h} + + + +<%def name="codeline()" filter="trim,h"> + ${ caller.body() } + + +<%def name="code(title=None, syntaxtype='mako', html_escape=False, use_sliders=False)"> + <% + def fix_indent(f): + f =string.expandtabs(f, 4) + g = '' + lines = string.split(f, "\n") + whitespace = None + for line in lines: + if whitespace is None: + match = re.match(r"^([ ]*).+", line) + if match is not None: + whitespace = match.group(1) + + if whitespace is not None: + line = re.sub(r"^%s" % whitespace, "", line) + + if whitespace is not None or re.search(r"\w", line) is not None: + g += (line + "\n") + + + return g.rstrip() + + p = re.compile(r'
    (.*?)
    ', re.S) + def hlight(match): + return "
    " + highlight.highlight(fix_indent(match.group(1)), html_escape = html_escape, syntaxtype = syntaxtype) + "
    " + content = p.sub(hlight, "
    " + capture(caller.body) + "
    ") + %> + +
    + % if title is not None: +
    ${title}
    + % endif + ${ content } +
    + + + +<%def name="popboxlink(name=None, show='show', hide='hide')" filter="trim"> + <% + if name is None: + name = attributes.setdefault('popbox_name', 0) + name += 1 + attributes['popbox_name'] = name + name = "popbox_" + repr(name) + %> +javascript:togglePopbox('${name}', '${show}', '${hide}') + + +<%def name="popbox(name=None, class_=None)" filter="trim"> +<% + if name is None: + name = 'popbox_' + repr(attributes['popbox_name']) +%> + + + +<%def name="poplink(link='sql')" filter="trim"> + <% + href = capture(popboxlink) + %> + '''PYESC${nav.link(href=href, text=link, class_="codepoplink")}PYESC''' + + +<%def name="codepopper()" filter="trim"> + <% + c = capture(caller.body) + c = re.sub(r'\n', '
    \n', c.strip()) + %> +
    <%call expr="popbox(class_='codepop')">${c}
    +
    +
    +<%def name="poppedcode()" filter="trim">
    +    <%
    +		c = capture(caller.body)
    +		c = re.sub(r'\n', '
    \n', c.strip()) + %> +
    ${c}
    +
    +
    +
    +
    +
    diff --git a/doc/build/templates/module.html b/doc/build/templates/module.html
    new file mode 100644
    index 0000000000..bcab68cfdd
    --- /dev/null
    +++ b/doc/build/templates/module.html
    @@ -0,0 +1,22 @@
    +<%inherit file="base.html"/>
    +<%page args="toc, extension, paged"/>
    +<%namespace  name="formatting" file="formatting.html"/>
    +<%namespace  name="nav" file="nav.html"/>
    +<%namespace name="pydoc" file="pydoc.html"/>
    +<%!
    +    import cPickle as pickle
    +    import os
    +%>
    +<%
    +    current = toc.get_by_file(self.template.module.filename)
    +    docfile = os.path.join(os.path.dirname(self.filename), 'compiled_docstrings.pickle')
    +    data = dict(pickle.load(file(docfile)))
    +    data = data[self.template.module.docstring]
    +%>
    +
    +${nav.topnav(item=current, toc=toc, extension=extension, paged=True)}
    +
    +${pydoc.obj_doc(obj=data, toc=toc, extension=extension, paged=True)}
    +
    +${nav.bottomnav(item=current, extension=extension, paged=True)}
    +
    diff --git a/doc/build/templates/nav.html b/doc/build/templates/nav.html
    new file mode 100644
    index 0000000000..38147d89de
    --- /dev/null
    +++ b/doc/build/templates/nav.html
    @@ -0,0 +1,73 @@
    +## nav.myt - Provides page navigation elements that are derived from toc.TOCElement structures, including
    +## individual hyperlinks as well as navigational toolbars and table-of-content listings.
    +<%namespace name="tocns" file="toc.html"/>
    +
    +<%def name="itemlink(item, paged, extension, anchor=True)" filter="trim">
    +    ${ item.description }
    +
    +
    +<%def name="toclink(toc, path, extension, paged, description=None)" filter="trim">
    +    <%
    +        item = toc.get_by_path(path)
    +        if description is None:
    +            if item:
    +                description = item.description
    +            else:
    +                description = path
    +        if item:
    +            anchor = not paged or item.depth > 1
    +        else: 
    +            anchor = False
    +    %>
    +    % if item:
    +        ${ description }
    +    % else:
    +        ${ description }
    +    % endif
    +
    +
    +
    +<%def name="link(href, text, class_)" filter="trim">
    +    ${ text }
    +
    +
    +<%def name="topnav(item, toc, extension, paged)">
    +    
    + + ${pagenav(item, extension=extension, paged=paged)} + + ${tocns.printtoc(root=item, current=None, anchor_toplevel=True, paged=paged, extension=extension)} +
    + + +<%def name="pagenav(item, paged, extension)"> + + + +<%def name="bottomnav(item, paged, extension)"> +
    + ${prevnext(item, paged, extension)} +
    + + +<%def name="prevnext(item, paged, extension)"> +
    + % if item.up: + Up: ${itemlink(item=item.up, paged=paged, anchor=not paged, extension=extension)} + % endif + + % if item.previous is not None: + ${item.up is not None and " | " or ""} + Previous: ${itemlink(item=item.previous, paged=paged, anchor=not paged, extension=extension)} + % endif + + % if item.next is not None: + ${item.previous is not None and " | " or ""} + Next: ${itemlink(item=item.next, paged=paged, anchor=not paged, extension=extension)} + % endif +
    + \ No newline at end of file diff --git a/doc/build/templates/pydoc.html b/doc/build/templates/pydoc.html new file mode 100644 index 0000000000..72e31e0d99 --- /dev/null +++ b/doc/build/templates/pydoc.html @@ -0,0 +1,114 @@ +<%doc>pydoc.myt - provides formatting functions for printing docstring.AbstractDoc generated python documentation objects. +<%! +import docstring +import sys, re + +def whitespace(docstring): + if not docstring: + return '' + + # Convert tabs to spaces (following the normal Python rules) + # and split into a list of lines: + lines = docstring.expandtabs().splitlines() + # Determine minimum indentation (first line doesn't count): + indent = sys.maxint + for line in lines[1:]: + stripped = line.lstrip() + if stripped: + indent = min(indent, len(line) - len(stripped)) + # Remove indentation (first line is special): + trimmed = [lines[0].strip()] + if indent < sys.maxint: + for line in lines[1:]: + trimmed.append(line[indent:].rstrip()) + # Strip off trailing and leading blank lines: + while trimmed and not trimmed[-1]: + trimmed.pop() + while trimmed and not trimmed[0]: + trimmed.pop(0) + # Return a single string: + return '\n'.join(trimmed) + +def convquotes(text): + return re.sub(r'``(.*?)``', lambda m: "%s" % m.group(1), text) + +%> +<%namespace name="formatting" file="formatting.html"/> +<%namespace name="nav" file="nav.html"/> + +<%def name="obj_doc(obj, toc, extension, paged)"> + <% + if obj.isclass: + links = [] + for elem in obj.inherits: + if isinstance(elem, docstring.ObjectDoc): + links.append(capture(nav.toclink, toc=toc, path=elem.toc_path, extension=extension, description=elem.name, paged=paged)) + else: + links.append(str(elem)) + htmldescription = "class " + obj.classname + "(%s)" % (','.join(links)) + else: + htmldescription = obj.description + + %> + + <%call expr="formatting.section(toc=toc, path=obj.toc_path, description=htmldescription, paged=paged, extension=extension)"> + % if obj.doc: +
    ${obj.doc or '' |whitespace, h,convquotes}
    + % endif + + % if not obj.isclass and obj.functions: + + <%call expr="formatting.section(toc=toc, path=obj.mod_path, paged=paged, extension=extension)"> + % for func in obj.functions: + ${function_doc(func=func,toc=toc)} + % endfor + + + % else: + + % if obj.functions: + % for func in obj.functions: + % if isinstance(func, docstring.FunctionDoc): + ${function_doc(func=func, toc=toc)} + % elif isinstance(func, docstring.PropertyDoc): + ${property_doc(prop=func)} + % endif + % endfor + % endif + % endif + + % if obj.classes: + % for class_ in obj.classes: + ${obj_doc(obj=class_, toc=toc, extension=extension, paged=paged)} + % endfor + % endif + + + +<%def name="function_doc(func, toc)"> +
    + <% + if hasattr(func, 'toc_path'): + item = toc.get_by_path(func.toc_path) + else: + item = None + %> + + def ${func.name}(${", ".join(map(lambda k: "%s" % k, func.arglist))}) +
    +
    ${func.doc or '' | whitespace, h, convquotes}
    +
    +
    + + +<%def name="property_doc(prop)"> +
    + + ${prop.name} = property() +
    +
    ${prop.doc or '' | whitespace, h, convquotes}
    +
    +
    + + + diff --git a/doc/build/templates/toc.html b/doc/build/templates/toc.html new file mode 100644 index 0000000000..d164d867dd --- /dev/null +++ b/doc/build/templates/toc.html @@ -0,0 +1,35 @@ +## toc.myt - prints table of contents listings given toc.TOCElement strucures + +<%def name="toc(toc, paged, extension)"> +
    + + +

    Table of Contents

    +    + (view full table) +

    + ${printtoc(root=toc,paged=paged, extension=extension, current=None,children=False,anchor_toplevel=False)} + + +

    Table of Contents: Full

    +    + (view brief table) + + ${printtoc(root=toc,paged=paged, extension=extension, current=None,children=True,anchor_toplevel=False)} + +
    + + + +<%def name="printtoc(root, paged, extension, current=None, children=True, anchor_toplevel=False)"> + + + diff --git a/doc/docs.css b/doc/docs.css index 25fa1624b2..59f0ef4d7b 100644 --- a/doc/docs.css +++ b/doc/docs.css @@ -1,84 +1,19 @@ /* documentation section styles */ -.doccontainer { -} - -.panecontainer { -} - -.sidebar { - background-color: #fbfbee; - border: solid 1px #ccc; - padding: 5px 5px 5px 5px; - margin: 0px 5px 5px 0px; - width:120px; - float:left; -} - - -.sectionnavblock { -} - -.sectionnav { - background-color: #fbfbee; - border: solid 1px #ccc; - padding: 10px 10px 10px 10px; - margin: 35px 0px 15px 5px; - float:right; -} - +#topanchor {position:absolute;left:0px;top:0px;width:0px;height:0px;} +#pagecontrol {float:right;} .topnav { background-color: #fbfbee; border: solid 1px #ccc; padding:10px 10px 0px 10px; - margin:0px 0px 10px 0px; -} - -.tipbox { - background-color: #fbfbee; - border:1px solid; - padding:10px; - margin: 5px; -} - -.multipage { - float:right; -} - -/* optional margin to add to topnav */ -.topnavmargin { - margin:10px; -} - -.topnavsectionlink { - padding: 0px 0px 0px 0px; - margin: 0px 0px 0px 0px; -} - -.topnavcontrol { - float:right; -} - -.topnavmain { - margin: 25px 5px 15px 5px; -} - -.topnavheader { - font: normal 20px/24px arial,helvetica,sans-serif; - margin: 0px 0px 0px 0px; - padding:0px 0px 15px 0px; -} - -.topnavitems { - margin: 0px 0px 0px 40px; + margin:10px 0px 10px 0px; } .prevnext { padding: 5px 0px 0px 0px; } - .codetitle { font-family: verdana, sans-serif; font-size: 12px; @@ -93,24 +28,11 @@ color: #960; } - -.content { - border: solid 1px #ccc; - padding: 0px 10px 20px 0px; -} - -.sectioncontent { - border: solid 1px #fff; - padding: 0px 10px 20px 0px; - line-height: 1.5em; +h1, h2, h3 { + font-family:arial,helvetica,sans-serif; } -.onepagecontent { - border: solid 1px #ccc; - margin: 0px 0px 0px 0px; -} - -h1, .docheadertext { +h1 { font: normal 20px/22px arial,helvetica,sans-serif; color: #222; padding:0px; @@ -118,82 +40,65 @@ h1, .docheadertext { } h2 { - font-size:16px; - font-weight:bold; - display:inline; - padding:0px; + font-family:arial,helvetica,sans-serif; + font-size:20px; + font-weight:normal; + line-height:24px; margin:0px; } -.docheader { - margin: 0px 0px 10px 0px; - line-height: 1.2em; -} - -.docheaderversion { - margin: 0.8em 0; -} - -.subsection { - /* this style is dynamically modified by the indentation */ - margin:15px 0px 0px 0px; - clear:right; -} - -.section { - padding: 20px 0px 0px 0px; +h3 { + font-family: arial, sans-serif; + font-size:16px; + font-weight:bold; } -h3, .sectionheadertext { - font-family: arial, sans-serif; +.topnav h3 { font-weight: bold; font-size: 16px; + margin:0px; + display:inline; + font-family:verdana,sans-serif; } -.sectiontext { - font-size: 12px; - margin: 5px 0px 0px 0px; -} - -.maintoc { - /*background-color: #fbfbee;*/ - background-color: #fbfbee; - border: solid 1px #ccc; - padding: 10px 10px 10px 10px; - margin: 0px 0px 10px 0px; +.topnav h2 { + margin:26px 4px 0px 5px; } -.toclinkcontainer { - padding:0px 0px 0px 8px; - /*border:1px solid;*/ +.section { + line-height: 1.5em; + padding:8px 10px 20px 10px; + margin:10px 0px 0px; } -.tocsection { - padding:2px 2px 2px 8px; +.subsection { + margin:0px 0px 0px 20px; + line-height: 1.5em; } -.toc_list { - padding:0px; - margin:0px; -} -.toc_list li { +.topnav li { font-size:12px; list-style-type:none; padding:0px 0px 3px 8px; margin:0px; } -.small_toc_list { +.topnav ul ul { padding:0px 0px 0px 8px; } -.small_toc_list li { +.topnav ul ul li { font-size: 11px; - list-style-type:none; } - +.bottomnav { + background-color:#FBFBEE; + border:1px solid #CCCCCC; + float:right; + margin:0px 0px 15px 5px; + padding:10px; +} .toclink { font-weight: bold; @@ -254,7 +159,6 @@ h3, .sectionheadertext { /*clear:right;*/ } - .codepoplink, #docs a.codepoplink { @@ -278,6 +182,3 @@ h3, .sectionheadertext { background-color: #900; } -.popup { - margin:10px; -} diff --git a/lib/sqlalchemy/engine/__init__.py b/lib/sqlalchemy/engine/__init__.py index c3651c88b9..e72c375537 100644 --- a/lib/sqlalchemy/engine/__init__.py +++ b/lib/sqlalchemy/engine/__init__.py @@ -41,44 +41,30 @@ default_strategy = 'plain' def create_engine(*args, **kwargs): """Create a new Engine instance. - Using the given strategy name, locates that strategy and invokes - its create() method to produce the Engine. The strategies - themselves are instances of EngineStrategy, and the built in ones - are present in the sqlalchemy.engine.strategies module. Current - implementations include *plain* and *threadlocal*. The default - used by this function is *plain*. - - *plain* provides support for a Connection object which can be used - to execute SQL queries with a specific underlying DBAPI connection. - - *threadlocal* is similar to *plain* except that it adds support - for a thread-local connection and transaction context, which - allows a group of engine operations to participate using the same - connection and transaction without the need for explicit passing - of a Connection object. - The standard method of specifying the engine is via URL as the first positional argument, to indicate the appropriate database dialect and connection arguments, with additional keyword arguments sent as options to the dialect and resulting Engine. - The URL is in the form ``://opt1=val1&opt2=val2``, where - ```` is a name such as *mysql*, *oracle*, *postgres*, and the - options indicate username, password, database, etc. Supported - keynames include `username`, `user`, `password`, `pw`, `db`, - `database`, `host`, `filename`. + The URL is in the form + ``dialect://user:password@host/dbname[?key=value..]``, where + ``dialect`` is a name such as ``mysql``, ``oracle``, ``postgres``, + etc. `**kwargs` represents options to be sent to the Engine itself as well as the components of the Engine, including the Dialect, the ConnectionProvider, and the Pool. A list of common options is as follows: + poolclass + a subclass of ``sqlalchemy.pool.Pool`` which will be used to + instantiate a connection pool. + pool - Defaults to None: an instance of ``sqlalchemy.pool.DBProxy`` or + an instance of ``sqlalchemy.pool.DBProxy`` or ``sqlalchemy.pool.Pool`` to be used as the underlying source for connections (DBProxy/Pool is described in the previous - section). If None, a default DBProxy will be created using the - engine's own database module with the given arguments. + section). This argument supercedes "poolclass". echo Defaults to False: if True, the Engine will log all statements @@ -102,21 +88,25 @@ def create_engine(*args, **kwargs): to all str types. module - Defaults to None: used by Oracle and Postgres, this is a + Defaults to None: this is a reference to a DBAPI2 module to be used instead of the engine's default module. For Postgres, the default is psycopg2, or psycopg1 if 2 cannot be found. For Oracle, its cx_Oracle. For mysql, MySQLdb. - use_ansi - Defaults to True: used only by Oracle; when False, the Oracle - driver attempts to support a particular *quirk* of some Oracle - databases, that the ``LEFT OUTER JOIN`` SQL syntax is not - supported, and the *Oracle join* syntax of using - ``(+)=`` must be used in order to achieve a - ``LEFT OUTER JOIN``. Its advised that the Oracle database be - configured to have full ANSI support instead of using this - feature. + strategy + allows alternate Engine implementations to take effect. + Current implementations include ``plain`` and ``threadlocal``. + The default used by this function is ``plain``. + + ``plain`` provides support for a Connection object which can be used + to execute SQL queries with a specific underlying DBAPI connection. + + ``threadlocal`` is similar to ``plain`` except that it adds support + for a thread-local connection and transaction context, which + allows a group of engine operations to participate using the same + underlying connection and transaction without the need for explicitly + passing a single Connection. """ strategy = kwargs.pop('strategy', default_strategy)