better documentation through automation: creating docutils & sphinx extensions
DESCRIPTION
Sphinx is an incredibly useful tool for creating attractive documentation for your project, but if all you ever use it for is converting reStructuredText files to HTML you are barely scratching the surface of its power. This presentation shows how easy it is to extend Sphinx by defining new markup processors, allowing you to take your documentation to the next level. PyCon 2013TRANSCRIPT
![Page 1: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/1.jpg)
Better Documentation Through Automation:Creating docutils & Sphinx Extensions
Doug Hellmann@doughellmannPyCon 2013
Saturday, March 16, 13
![Page 2: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/2.jpg)
Markup Language
Saturday, March 16, 13
![Page 3: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/3.jpg)
Markup LanguageExtensible
Saturday, March 16, 13
![Page 4: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/4.jpg)
Saturday, March 16, 13
![Page 5: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/5.jpg)
SphinxApplication
Saturday, March 16, 13
![Page 6: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/6.jpg)
BuildEnvironment
SphinxApplication
.rst
Saturday, March 16, 13
![Page 7: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/7.jpg)
BuildEnvironment
docutilsparser
SphinxApplication
.rst
Saturday, March 16, 13
![Page 8: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/8.jpg)
BuildEnvironment
docutilsparser
SphinxBuilder
SphinxApplication
.rst .pdf .html
Saturday, March 16, 13
![Page 9: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/9.jpg)
section
title paragraph
#text emphasis #text literal
#text#text
#text
Saturday, March 16, 13
![Page 10: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/10.jpg)
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vulputate elementum lectus a viverra. Vivamus hendrerit egestas lacinia. Proin tellus lectus, scelerisque vitae rutrum eget, ultrices vel metus. Quisque :ref:`target-name` pharetra lorem vehicula lorem posuere molestie cursus ipsum ornare. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Maecenas eu sapien at tellus suscipit aliquet :pep:`8` ut non tellus. Nulla facilisis bibendum dolor, quis mattis urna posuere eget. Nulla quis dui id augue faucibus varius. Nam eu leo quam. Fusce :term:`condimentum` placerat nisi nec vestibulum. Duis tortor sapien, commodo ac faucibus nec :rfc:`1822`, rutrum quis urna. Pellentesque cursus facilisis odio, id aliquam sem commodo vestibulum. Proin eget velit sed justo ultricies vulputate.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vulputate elementum lectus a viverra. Vivamus hendrerit egestas lacinia. Proin tellus lectus, scelerisque vitae rutrum eget, ultrices vel metus. Quisque :ref:`target-name` pharetra lorem vehicula lorem posuere molestie cursus ipsum ornare. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Maecenas eu sapien at tellus suscipit aliquet :pep:`8` ut non tellus. Nulla facilisis bibendum dolor, quis mattis urna posuere eget. Nulla quis dui id augue faucibus varius. Nam eu leo quam. Fusce :term:`condimentum` placerat nisi nec vestibulum. Duis tortor sapien, commodo ac faucibus nec :rfc:`1822`, rutrum quis urna. Pellentesque cursus facilisis odio, id aliquam sem commodo vestibulum. Proin eget velit sed justo ultricies vulputate.
Saturday, March 16, 13
![Page 11: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/11.jpg)
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vulputate elementum lectus a viverra. Vivamus hendrerit egestas lacinia. Proin tellus lectus, scelerisque vitae rutrum eget, ultrices vel metus. Quisque :ref:`target-name` pharetra lorem vehicula lorem posuere molestie cursus ipsum ornare. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Maecenas eu sapien at tellus suscipit aliquet :pep:`8` ut non tellus. Nulla facilisis bibendum dolor, quis mattis urna posuere eget. Nulla quis dui id augue faucibus varius. Nam eu leo quam. Fusce :term:`condimentum` placerat nisi nec vestibulum. Duis tortor sapien, commodo ac faucibus nec :rfc:`1822`, rutrum quis urna. Pellentesque cursus facilisis odio, id aliquam sem commodo vestibulum. Proin eget velit sed justo ultricies vulputate.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vulputate elementum lectus a viverra. Vivamus hendrerit egestas lacinia. Proin tellus lectus, scelerisque vitae rutrum eget, ultrices vel metus. Quisque :ref:`target-name` pharetra lorem vehicula lorem posuere molestie cursus ipsum ornare. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Maecenas eu sapien at tellus suscipit aliquet :pep:`8` ut non tellus. Nulla facilisis bibendum dolor, quis mattis urna posuere eget. Nulla quis dui id augue faucibus varius. Nam eu leo quam. Fusce :term:`condimentum` placerat nisi nec vestibulum. Duis tortor sapien, commodo ac faucibus nec :rfc:`1822`, rutrum quis urna. Pellentesque cursus facilisis odio, id aliquam sem commodo vestibulum. Proin eget velit sed justo ultricies vulputate.
Saturday, March 16, 13
![Page 12: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/12.jpg)
.. seealso::
PyEnchant_ Python interface to enchant_.
:ref:`project-sphinxcontrib-spelling` Project home page for the spelling checker.
sphinxcontrib_ BitBucket repository for sphinxcontrib-spelling and several other Sphinx extensions.
.. include:: example.py :literal: :start-after: # end-of-header-comment
.. image:: figure.png
Saturday, March 16, 13
![Page 13: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/13.jpg)
2.6
- Fixed a problem with hook script line endings under Cygwin (`Issue 68 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/68>`_). - Updated documentation to include a list of the compatible shells (:ref:`supported-shells`) and Python versions (:ref:`supported-versions`) (`Issue 70 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/70>`_). - Fixed installation dependency on virtualenv (`Issue 60 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/60>`_). - Fixed the method for determining the Python version so it works under Python 2.4 (`Issue 61 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/60>`_). - Converted the test infrastructure to use `tox <http://codespeak.net/tox/index.html>`_ instead of home-grown scripts in the Makefile.
Saturday, March 16, 13
![Page 14: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/14.jpg)
2.6
- Fixed a problem with hook script line endings under Cygwin (`Issue 68 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/68>`_). - Updated documentation to include a list of the compatible shells (:ref:`supported-shells`) and Python versions (:ref:`supported-versions`) (`Issue 70 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/70>`_). - Fixed installation dependency on virtualenv (`Issue 60 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/60>`_). - Fixed the method for determining the Python version so it works under Python 2.4 (`Issue 61 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/60>`_). - Converted the test infrastructure to use `tox <http://codespeak.net/tox/index.html>`_ instead of home-grown scripts in the Makefile.
Saturday, March 16, 13
![Page 15: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/15.jpg)
2.6
- Fixed a problem with hook script line endings under Cygwin (`Issue 68 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/68>`_). - Updated documentation to include a list of the compatible shells (:ref:`supported-shells`) and Python versions (:ref:`supported-versions`) (`Issue 70 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/70>`_). - Fixed installation dependency on virtualenv (`Issue 60 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/60>`_). - Fixed the method for determining the Python version so it works under Python 2.4 (`Issue 61 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/60>`_). - Converted the test infrastructure to use `tox <http://codespeak.net/tox/index.html>`_ instead of home-grown scripts in the Makefile.
Saturday, March 16, 13
![Page 16: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/16.jpg)
`Issue 68 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/68>`_
Saturday, March 16, 13
![Page 17: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/17.jpg)
`Issue 68 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/68>`_
Saturday, March 16, 13
![Page 18: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/18.jpg)
`Issue 68 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/68>`_
Saturday, March 16, 13
![Page 19: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/19.jpg)
`68`
`Issue 68 <https://bitbucket.org/dhellmann/virtualenvwrapper/issue/68>`_
:bbissue:
Saturday, March 16, 13
![Page 20: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/20.jpg)
from docutils import nodes, utilsfrom docutils.parsers.rst.roles import set_classes
def bbissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): "Link to a BitBucket issue." try: issue_num = int(text) if issue_num <= 0: raise ValueError except ValueError: msg = inliner.reporter.error( '"%s" is an invalid bug id.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app node = make_link_node(rawtext, app, 'issue', text, options) return [node], []
def make_link_node(rawtext, app, type, slug, options): "Create a link to a BitBucket resource." try: base = app.config.bitbucket_project_url if not base: raise AttributeError except AttributeError, err: raise ValueError('bitbucket_project_url not set (%s)' % str(err))
slash = '/' if base[-1] != '/' else '' ref = base + slash + type + '/' + slug + '/' set_classes(options) node = nodes.reference(rawtext, type + ' ' + utils.unescape(slug), refuri=ref, **options) return node
def setup(app): "Install the plugin." app.info('Initializing BitBucket plugin') app.add_role('bbissue', bbissue_role) app.add_config_value('bitbucket_project_url', None, 'env') return
Saturday, March 16, 13
![Page 21: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/21.jpg)
from docutils import nodes, utilsfrom docutils.parsers.rst.roles import set_classes
def bbissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): "Link to a BitBucket issue." try: issue_num = int(text) if issue_num <= 0: raise ValueError except ValueError: msg = inliner.reporter.error( '"%s" is an invalid bug id.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app node = make_link_node(rawtext, app, 'issue', text, options) return [node], []
def make_link_node(rawtext, app, type, slug, options): "Create a link to a BitBucket resource." try: base = app.config.bitbucket_project_url if not base: raise AttributeError except AttributeError, err: raise ValueError('bitbucket_project_url not set (%s)' % str(err))
slash = '/' if base[-1] != '/' else '' ref = base + slash + type + '/' + slug + '/' set_classes(options) node = nodes.reference(rawtext, type + ' ' + utils.unescape(slug), refuri=ref, **options) return node
def setup(app): "Install the plugin." app.info('Initializing BitBucket plugin') app.add_role('bbissue', bbissue_role) app.add_config_value('bitbucket_project_url', None, 'env') return
Saturday, March 16, 13
![Page 22: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/22.jpg)
from docutils import nodes, utilsfrom docutils.parsers.rst.roles import set_classes
def bbissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): "Link to a BitBucket issue." try: issue_num = int(text) if issue_num <= 0: raise ValueError except ValueError: msg = inliner.reporter.error( '"%s" is an invalid bug id.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app node = make_link_node(rawtext, app, 'issue', text, options) return [node], []
def make_link_node(rawtext, app, type, slug, options): "Create a link to a BitBucket resource." try: base = app.config.bitbucket_project_url if not base: raise AttributeError except AttributeError, err: raise ValueError('bitbucket_project_url not set (%s)' % str(err))
slash = '/' if base[-1] != '/' else '' ref = base + slash + type + '/' + slug + '/' set_classes(options) node = nodes.reference(rawtext, type + ' ' + utils.unescape(slug), refuri=ref, **options) return node
def setup(app): "Install the plugin." app.info('Initializing BitBucket plugin') app.add_role('bbissue', bbissue_role) app.add_config_value('bitbucket_project_url', None, 'env') return
Saturday, March 16, 13
![Page 23: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/23.jpg)
from docutils import nodes, utilsfrom docutils.parsers.rst.roles import set_classes
def bbissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): "Link to a BitBucket issue." try: issue_num = int(text) if issue_num <= 0: raise ValueError except ValueError: msg = inliner.reporter.error( '"%s" is an invalid bug id.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app node = make_link_node(rawtext, app, 'issue', text, options) return [node], []
def make_link_node(rawtext, app, type, slug, options): "Create a link to a BitBucket resource." try: base = app.config.bitbucket_project_url if not base: raise AttributeError except AttributeError, err: raise ValueError('bitbucket_project_url not set (%s)' % str(err))
slash = '/' if base[-1] != '/' else '' ref = base + slash + type + '/' + slug + '/' set_classes(options) node = nodes.reference(rawtext, type + ' ' + utils.unescape(slug), refuri=ref, **options) return node
def setup(app): "Install the plugin." app.info('Initializing BitBucket plugin') app.add_role('bbissue', bbissue_role) app.add_config_value('bitbucket_project_url', None, 'env') return
Saturday, March 16, 13
![Page 24: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/24.jpg)
from docutils import nodes, utilsfrom docutils.parsers.rst.roles import set_classes
def bbissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): "Link to a BitBucket issue." try: issue_num = int(text) if issue_num <= 0: raise ValueError except ValueError: msg = inliner.reporter.error( '"%s" is an invalid bug id.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app node = make_link_node(rawtext, app, 'issue', text, options) return [node], []
def make_link_node(rawtext, app, type, slug, options): "Create a link to a BitBucket resource." try: base = app.config.bitbucket_project_url if not base: raise AttributeError except AttributeError, err: raise ValueError('bitbucket_project_url not set (%s)' % str(err))
slash = '/' if base[-1] != '/' else '' ref = base + slash + type + '/' + slug + '/' set_classes(options) node = nodes.reference(rawtext, type + ' ' + utils.unescape(slug), refuri=ref, **options) return node
def setup(app): "Install the plugin." app.info('Initializing BitBucket plugin') app.add_role('bbissue', bbissue_role) app.add_config_value('bitbucket_project_url', None, 'env') return
Saturday, March 16, 13
![Page 25: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/25.jpg)
from docutils import nodes, utilsfrom docutils.parsers.rst.roles import set_classes
def bbissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): "Link to a BitBucket issue." try: issue_num = int(text) if issue_num <= 0: raise ValueError except ValueError: msg = inliner.reporter.error( '"%s" is an invalid bug id.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app node = make_link_node(rawtext, app, 'issue', text, options) return [node], []
def make_link_node(rawtext, app, type, slug, options): "Create a link to a BitBucket resource." try: base = app.config.bitbucket_project_url if not base: raise AttributeError except AttributeError, err: raise ValueError('bitbucket_project_url not set (%s)' % str(err))
slash = '/' if base[-1] != '/' else '' ref = base + slash + type + '/' + slug + '/' set_classes(options) node = nodes.reference(rawtext, type + ' ' + utils.unescape(slug), refuri=ref, **options) return node
def setup(app): "Install the plugin." app.info('Initializing BitBucket plugin') app.add_role('bbissue', bbissue_role) app.add_config_value('bitbucket_project_url', None, 'env') return
Saturday, March 16, 13
![Page 26: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/26.jpg)
from docutils import nodes, utilsfrom docutils.parsers.rst.roles import set_classes
def bbissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): "Link to a BitBucket issue." try: issue_num = int(text) if issue_num <= 0: raise ValueError except ValueError: msg = inliner.reporter.error( '"%s" is an invalid bug id.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app node = make_link_node(rawtext, app, 'issue', text, options) return [node], []
def make_link_node(rawtext, app, type, slug, options): "Create a link to a BitBucket resource." try: base = app.config.bitbucket_project_url if not base: raise AttributeError except AttributeError, err: raise ValueError('bitbucket_project_url not set (%s)' % str(err))
slash = '/' if base[-1] != '/' else '' ref = base + slash + type + '/' + slug + '/' set_classes(options) node = nodes.reference(rawtext, type + ' ' + utils.unescape(slug), refuri=ref, **options) return node
def setup(app): "Install the plugin." app.info('Initializing BitBucket plugin') app.add_role('bbissue', bbissue_role) app.add_config_value('bitbucket_project_url', None, 'env') return
Saturday, March 16, 13
![Page 27: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/27.jpg)
from docutils import nodes, utilsfrom docutils.parsers.rst.roles import set_classes
def bbissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): "Link to a BitBucket issue." try: issue_num = int(text) if issue_num <= 0: raise ValueError except ValueError: msg = inliner.reporter.error( '"%s" is an invalid bug id.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app node = make_link_node(rawtext, app, 'issue', text, options) return [node], []
def make_link_node(rawtext, app, type, slug, options): "Create a link to a BitBucket resource." try: base = app.config.bitbucket_project_url if not base: raise AttributeError except AttributeError, err: raise ValueError('bitbucket_project_url not set (%s)' % str(err))
slash = '/' if base[-1] != '/' else '' ref = base + slash + type + '/' + slug + '/' set_classes(options) node = nodes.reference(rawtext, type + ' ' + utils.unescape(slug), refuri=ref, **options) return node
def setup(app): "Install the plugin." app.info('Initializing BitBucket plugin') app.add_role('bbissue', bbissue_role) app.add_config_value('bitbucket_project_url', None, 'env') return
Saturday, March 16, 13
![Page 28: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/28.jpg)
from docutils import nodes, utilsfrom docutils.parsers.rst.roles import set_classes
def bbissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): "Link to a BitBucket issue." try: issue_num = int(text) if issue_num <= 0: raise ValueError except ValueError: msg = inliner.reporter.error( '"%s" is an invalid bug id.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app node = make_link_node(rawtext, app, 'issue', text, options) return [node], []
def make_link_node(rawtext, app, type, slug, options): "Create a link to a BitBucket resource." try: base = app.config.bitbucket_project_url if not base: raise AttributeError except AttributeError, err: raise ValueError('bitbucket_project_url not set (%s)' % str(err))
slash = '/' if base[-1] != '/' else '' ref = base + slash + type + '/' + slug + '/' set_classes(options) node = nodes.reference(rawtext, type + ' ' + utils.unescape(slug), refuri=ref, **options) return node
def setup(app): "Install the plugin." app.info('Initializing BitBucket plugin') app.add_role('bbissue', bbissue_role) app.add_config_value('bitbucket_project_url', None, 'env') return
Saturday, March 16, 13
![Page 29: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/29.jpg)
from docutils import nodes, utilsfrom docutils.parsers.rst.roles import set_classes
def bbissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): "Link to a BitBucket issue." try: issue_num = int(text) if issue_num <= 0: raise ValueError except ValueError: msg = inliner.reporter.error( '"%s" is an invalid bug id.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app node = make_link_node(rawtext, app, 'issue', text, options) return [node], []
def make_link_node(rawtext, app, type, slug, options): "Create a link to a BitBucket resource." try: base = app.config.bitbucket_project_url if not base: raise AttributeError except AttributeError, err: raise ValueError('bitbucket_project_url not set (%s)' % str(err))
slash = '/' if base[-1] != '/' else '' ref = base + slash + type + '/' + slug + '/' set_classes(options) node = nodes.reference(rawtext, type + ' ' + utils.unescape(slug), refuri=ref, **options) return node
def setup(app): "Install the plugin." app.info('Initializing BitBucket plugin') app.add_role('bbissue', bbissue_role) app.add_config_value('bitbucket_project_url', None, 'env') return
Saturday, March 16, 13
![Page 30: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/30.jpg)
from docutils import nodes, utilsfrom docutils.parsers.rst.roles import set_classes
def bbissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): "Link to a BitBucket issue." try: issue_num = int(text) if issue_num <= 0: raise ValueError except ValueError: msg = inliner.reporter.error( '"%s" is an invalid bug id.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app node = make_link_node(rawtext, app, 'issue', text, options) return [node], []
def make_link_node(rawtext, app, type, slug, options): "Create a link to a BitBucket resource." try: base = app.config.bitbucket_project_url if not base: raise AttributeError except AttributeError, err: raise ValueError('bitbucket_project_url not set (%s)' % str(err))
slash = '/' if base[-1] != '/' else '' ref = base + slash + type + '/' + slug + '/' set_classes(options) node = nodes.reference(rawtext, type + ' ' + utils.unescape(slug), refuri=ref, **options) return node
def setup(app): "Install the plugin." app.info('Initializing BitBucket plugin') app.add_role('bbissue', bbissue_role) app.add_config_value('bitbucket_project_url', None, 'env') return
Saturday, March 16, 13
![Page 31: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/31.jpg)
from docutils import nodes, utilsfrom docutils.parsers.rst.roles import set_classes
def bbissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): "Link to a BitBucket issue." try: issue_num = int(text) if issue_num <= 0: raise ValueError except ValueError: msg = inliner.reporter.error( '"%s" is an invalid bug id.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app node = make_link_node(rawtext, app, 'issue', text, options) return [node], []
def make_link_node(rawtext, app, type, slug, options): "Create a link to a BitBucket resource." try: base = app.config.bitbucket_project_url if not base: raise AttributeError except AttributeError, err: raise ValueError('bitbucket_project_url not set (%s)' % str(err))
slash = '/' if base[-1] != '/' else '' ref = base + slash + type + '/' + slug + '/' set_classes(options) node = nodes.reference(rawtext, type + ' ' + utils.unescape(slug), refuri=ref, **options) return node
def setup(app): "Install the plugin." app.info('Initializing BitBucket plugin') app.add_role('bbissue', bbissue_role) app.add_config_value('bitbucket_project_url', None, 'env') return
Saturday, March 16, 13
![Page 32: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/32.jpg)
from docutils import nodes, utilsfrom docutils.parsers.rst.roles import set_classes
def bbissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): "Link to a BitBucket issue." try: issue_num = int(text) if issue_num <= 0: raise ValueError except ValueError: msg = inliner.reporter.error( '"%s" is an invalid bug id.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app node = make_link_node(rawtext, app, 'issue', text, options) return [node], []
def make_link_node(rawtext, app, type, slug, options): "Create a link to a BitBucket resource." try: base = app.config.bitbucket_project_url if not base: raise AttributeError except AttributeError, err: raise ValueError('bitbucket_project_url not set (%s)' % str(err))
slash = '/' if base[-1] != '/' else '' ref = base + slash + type + '/' + slug + '/' set_classes(options) node = nodes.reference(rawtext, type + ' ' + utils.unescape(slug), refuri=ref, **options) return node
def setup(app): "Install the plugin." app.info('Initializing BitBucket plugin') app.add_role('bbissue', bbissue_role) app.add_config_value('bitbucket_project_url', None, 'env') return
Saturday, March 16, 13
![Page 33: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/33.jpg)
from docutils import nodes, utilsfrom docutils.parsers.rst.roles import set_classes
def bbissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): "Link to a BitBucket issue." try: issue_num = int(text) if issue_num <= 0: raise ValueError except ValueError: msg = inliner.reporter.error( '"%s" is an invalid bug id.' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] app = inliner.document.settings.env.app node = make_link_node(rawtext, app, 'issue', text, options) return [node], []
def make_link_node(rawtext, app, type, slug, options): "Create a link to a BitBucket resource." try: base = app.config.bitbucket_project_url if not base: raise AttributeError except AttributeError, err: raise ValueError('bitbucket_project_url not set (%s)' % str(err))
slash = '/' if base[-1] != '/' else '' ref = base + slash + type + '/' + slug + '/' set_classes(options) node = nodes.reference(rawtext, type + ' ' + utils.unescape(slug), refuri=ref, **options) return node
def setup(app): "Install the plugin." app.info('Initializing BitBucket plugin') app.add_role('bbissue', bbissue_role) app.add_config_value('bitbucket_project_url', None, 'env') return
Saturday, March 16, 13
![Page 34: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/34.jpg)
2.6
- Fixed a problem with hook script line endings under Cygwin (:bbissue:`68`). - Updated documentation to include a list of the compatible shells (:ref:`supported-shells`) and Python versions (:ref:`supported-versions`) (:bbissue:`70`). - Fixed installation dependency on virtualenv (:bbissue:`60`). - Fixed the method for determining the Python version so it works under Python 2.4 (:bbissue:`61`). - Converted the test infrastructure to use `tox <http://codespeak.net/tox/index.html>`_ instead of home-grown scripts in the Makefile.
Saturday, March 16, 13
![Page 35: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/35.jpg)
2.6
- Fixed a problem with hook script line endings under Cygwin (:bbissue:`68`). - Updated documentation to include a list of the compatible shells (:ref:`supported-shells`) and Python versions (:ref:`supported-versions`) (:bbissue:`70`). - Fixed installation dependency on virtualenv (:bbissue:`60`). - Fixed the method for determining the Python version so it works under Python 2.4 (:bbissue:`61`). - Converted the test infrastructure to use `tox <http://codespeak.net/tox/index.html>`_ instead of home-grown scripts in the Makefile.
Saturday, March 16, 13
![Page 36: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/36.jpg)
2.6
• Fixed a problem with hook script line endings under Cygwin (issue 68).
• Updated documentation to include a list of the compatible shells (Supported Shells) and Python versions (Python Versions) (issue 70).
• Fixed installation dependency on virtualenv (issue 60).• Fixed the method for determining the Python version so
it works under Python 2.4 (issue 61).• Converted the test infrastructure to use tox instead of
home-grown scripts in the Makefile.
Saturday, March 16, 13
![Page 37: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/37.jpg)
.. name:: arguments :option: value :option: another-value
body line body line
Saturday, March 16, 13
![Page 38: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/38.jpg)
.. name:: arguments :option: value :option: another-value
body line body line
Saturday, March 16, 13
![Page 39: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/39.jpg)
.. name:: arguments :option: value :option: another-value
body line body line
Saturday, March 16, 13
![Page 40: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/40.jpg)
.. name:: arguments :option: value :option: another-value
body line body line
Saturday, March 16, 13
![Page 41: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/41.jpg)
.. sqltable:: List of Users :connection_string: sqlite:///sampledata.db
select name as 'Name', email as 'E-mail' from users order by Name asc
Saturday, March 16, 13
![Page 42: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/42.jpg)
.. sqltable:: List of Users :connection_string: sqlite:///sampledata.db
select name as 'Name', email as 'E-mail' from users order by Name asc
Saturday, March 16, 13
![Page 43: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/43.jpg)
.. sqltable:: List of Users :connection_string: sqlite:///sampledata.db
select name as 'Name', email as 'E-mail' from users order by Name asc
Saturday, March 16, 13
![Page 44: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/44.jpg)
.. sqltable:: List of Users :connection_string: sqlite:///sampledata.db
select name as 'Name', email as 'E-mail' from users order by Name asc
Saturday, March 16, 13
![Page 45: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/45.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 46: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/46.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 47: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/47.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 48: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/48.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 49: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/49.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 50: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/50.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 51: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/51.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 52: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/52.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 53: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/53.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 54: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/54.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 55: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/55.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 56: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/56.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 57: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/57.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 58: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/58.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 59: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/59.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 60: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/60.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 61: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/61.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 62: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/62.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 63: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/63.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 64: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/64.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 65: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/65.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
Saturday, March 16, 13
![Page 66: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/66.jpg)
Table Node Hierarchy
Saturday, March 16, 13
![Page 67: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/67.jpg)
Table Node Hierarchy
table
Saturday, March 16, 13
![Page 68: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/68.jpg)
Table Node Hierarchy
tgroup
table
Saturday, March 16, 13
![Page 69: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/69.jpg)
Table Node Hierarchy
tgroup
colspec
table
Saturday, March 16, 13
![Page 70: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/70.jpg)
Table Node Hierarchy
tgroup
colspec thead
table
Saturday, March 16, 13
![Page 71: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/71.jpg)
Table Node Hierarchy
tgroup
colspec thead
row
table
Saturday, March 16, 13
![Page 72: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/72.jpg)
Table Node Hierarchy
tgroup
colspec thead
row
entry
table
Saturday, March 16, 13
![Page 73: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/73.jpg)
Table Node Hierarchy
tgroup
colspec thead
row
entry
paragraph
table
Saturday, March 16, 13
![Page 74: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/74.jpg)
Table Node Hierarchy
tgroup
colspec tbodythead
row
entry
paragraph
table
Saturday, March 16, 13
![Page 75: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/75.jpg)
Table Node Hierarchy
tgroup
colspec tbodythead
row
entry
paragraph
row
entry
paragraph
table
Saturday, March 16, 13
![Page 76: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/76.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
tgroup
colspec
table
Saturday, March 16, 13
![Page 77: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/77.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
tgroup
colspec
table
Saturday, March 16, 13
![Page 78: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/78.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
tgroup
colspec
table
Saturday, March 16, 13
![Page 79: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/79.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
tgroup
colspec
table
Saturday, March 16, 13
![Page 80: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/80.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
thead
row
entry
paragraph
Saturday, March 16, 13
![Page 81: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/81.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
thead
row
entry
paragraph
Saturday, March 16, 13
![Page 82: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/82.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
thead
row
entry
paragraph
Saturday, March 16, 13
![Page 83: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/83.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
thead
row
entry
paragraph
Saturday, March 16, 13
![Page 84: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/84.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
tbody
row
entry
paragraph
Saturday, March 16, 13
![Page 85: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/85.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
tbody
row
entry
paragraph
Saturday, March 16, 13
![Page 86: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/86.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
tbody
row
entry
paragraph
Saturday, March 16, 13
![Page 87: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/87.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
tbody
row
entry
paragraph
Saturday, March 16, 13
![Page 88: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/88.jpg)
from docutils.parsers.rst.directives.tables import Table
class SQLTable(Table):
option_spec = {'widths': directives.positive_int_list, 'class': directives.class_option, 'name': directives.unchanged, 'connection_string':directives.unchanged, }
def run(self): env = self.state.document.settings.env app = env.app config = app.config
# Make sure we have some content, which for now we # assume is a query. if not self.content: error = self.state_machine.reporter.error( 'No query in sqltable directive', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [error]
# Connect to the database connection_string = self.options.get( 'connection_string', config.sqltable_connection_string, ) app.info('Connecting to %s' % connection_string) engine = sqlalchemy.create_engine(connection_string)
# Run the query query = '\n'.join(self.content) app.info('Running query %r' % query) results = engine.execute(query)
# Extract some values we need for building the table. table_headers = results.keys() table_body = results max_cols = len(table_headers) max_header_cols = max_cols
# Handle the width settings and title col_widths = self.get_column_widths(max_cols) title, messages = self.make_title()
# Build the node containing the table content table_node = self.build_table(table_body, col_widths, table_headers) table_node['classes'] += self.options.get('class', []) self.add_name(table_node) if title: table_node.insert(0, title) return [table_node] + messages
def build_table(self, table_data, col_widths, headers): table = nodes.table()
# Set up the column specifications # based on the widths. tgroup = nodes.tgroup(cols=len(col_widths)) table += tgroup tgroup.extend(nodes.colspec(colwidth=col_width) for col_width in col_widths)
# Set the headers thead = nodes.thead() tgroup += thead row_node = nodes.row() thead += row_node row_node.extend( nodes.entry(h, nodes.paragraph(text=h)) for h in headers )
# The body of the table is made up of rows. # Each row contains a series of entries, # and each entry contains a paragraph of text. tbody = nodes.tbody() tgroup += tbody rows = [] for row in table_data: trow = nodes.row() for cell in row: entry = nodes.entry() para = nodes.paragraph( text=unicode(cell)) entry += para trow += entry rows.append(trow) tbody.extend(rows)
#print table return table
def setup(app): app.info('Initializing SQLTable') app.add_config_value('sqltable_connection_string', '', 'env') app.add_directive('sqltable', SQLTable)
tbody
row
entry
paragraph
Saturday, March 16, 13
![Page 89: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/89.jpg)
.. sqltable:: List of Users :connection_string: sqlite:///sampledata.db
select name as 'Name', email as 'E-mail' from users order by Name asc
Saturday, March 16, 13
![Page 90: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/90.jpg)
.. sqltable:: List of Users :connection_string: sqlite:///sampledata.db
select name as 'Name', email as 'E-mail' from users order by Name asc
Saturday, March 16, 13
![Page 91: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/91.jpg)
.. sqltable:: List of Users :connection_string: sqlite:///sampledata.db
select name as 'Name', email as 'E-mail' from users order by Name asc
Saturday, March 16, 13
![Page 92: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/92.jpg)
.. sqltable:: List of Users :connection_string: sqlite:///sampledata.db
select name as 'Name', email as 'E-mail' from users order by Name asc
Saturday, March 16, 13
![Page 93: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/93.jpg)
BuildEnvironment
docutilsparser
SphinxBuilder
SphinxApplication
.rst .pdf .html
Saturday, March 16, 13
![Page 94: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/94.jpg)
Saturday, March 16, 13
![Page 95: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/95.jpg)
.rst
Saturday, March 16, 13
![Page 96: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/96.jpg)
.rst
Saturday, March 16, 13
![Page 97: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/97.jpg)
.rst
wordlist
check
Saturday, March 16, 13
![Page 98: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/98.jpg)
.rst
wordlist
check
Saturday, March 16, 13
![Page 99: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/99.jpg)
section
title paragraph
#text emphasis #text literal
#text#text
#text
Saturday, March 16, 13
![Page 100: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/100.jpg)
section
title paragraph
#text emphasis #text literal
#text#text
#text
Saturday, March 16, 13
![Page 101: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/101.jpg)
from sphinx.builders import Builder
class SpellingBuilder(Builder):
name = 'spelling'
def init(self): self.docnames = [] self.document_data = []
project_words = os.path.join(self.srcdir, self.config.spelling_word_list_filename)
self.checker = SpellingChecker( lang=self.config.spelling_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=project_words, ) self.output_filename = os.path.join(self.outdir, 'output.txt') self.output = codecs.open(self.output_filename, 'wt', encoding='UTF-8')
def write_doc(self, docname, doctree):
filename = self.env.doc2path(docname, base=None)
for node in doctree.traverse(docutils.nodes.Text): if (node.tagname == '#text' and node.parent and node.parent.tagname in TEXT_NODES):
# Determine the line number for this node lineno = get_line_number(node)
# Check the text of the node. for word, suggestions in self.checker.check(node.astext()):
msg_parts = [ docname ] if lineno: msg_parts.append( darkgreen('(line %3d)' % lineno) ) msg_parts.append(red(word)) msg_parts.append( self.format_suggestions(suggestions) ) msg = ' '.join(msg_parts) self.info(msg) self.output.write(u"%s:%s: (%s) %s\n" % ( self.env.doc2path(docname, None), lineno, word, self.format_suggestions(suggestions), ))
# Found at least one bad spelling self.app.statuscode = 1
return
def finish(self): self.output.close() self.info('Output written to %s' % self.output_filename) return
def setup(app): app.info('Initializing Spelling Checker') app.add_builder(SpellingBuilder) return
Saturday, March 16, 13
![Page 102: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/102.jpg)
from sphinx.builders import Builder
class SpellingBuilder(Builder):
name = 'spelling'
def init(self): self.docnames = [] self.document_data = []
project_words = os.path.join(self.srcdir, self.config.spelling_word_list_filename)
self.checker = SpellingChecker( lang=self.config.spelling_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=project_words, ) self.output_filename = os.path.join(self.outdir, 'output.txt') self.output = codecs.open(self.output_filename, 'wt', encoding='UTF-8')
def write_doc(self, docname, doctree):
filename = self.env.doc2path(docname, base=None)
for node in doctree.traverse(docutils.nodes.Text): if (node.tagname == '#text' and node.parent and node.parent.tagname in TEXT_NODES):
# Determine the line number for this node lineno = get_line_number(node)
# Check the text of the node. for word, suggestions in self.checker.check(node.astext()):
msg_parts = [ docname ] if lineno: msg_parts.append( darkgreen('(line %3d)' % lineno) ) msg_parts.append(red(word)) msg_parts.append( self.format_suggestions(suggestions) ) msg = ' '.join(msg_parts) self.info(msg) self.output.write(u"%s:%s: (%s) %s\n" % ( self.env.doc2path(docname, None), lineno, word, self.format_suggestions(suggestions), ))
# Found at least one bad spelling self.app.statuscode = 1
return
def finish(self): self.output.close() self.info('Output written to %s' % self.output_filename) return
def setup(app): app.info('Initializing Spelling Checker') app.add_builder(SpellingBuilder) return
Saturday, March 16, 13
![Page 103: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/103.jpg)
from sphinx.builders import Builder
class SpellingBuilder(Builder):
name = 'spelling'
def init(self): self.docnames = [] self.document_data = []
project_words = os.path.join(self.srcdir, self.config.spelling_word_list_filename)
self.checker = SpellingChecker( lang=self.config.spelling_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=project_words, ) self.output_filename = os.path.join(self.outdir, 'output.txt') self.output = codecs.open(self.output_filename, 'wt', encoding='UTF-8')
def write_doc(self, docname, doctree):
filename = self.env.doc2path(docname, base=None)
for node in doctree.traverse(docutils.nodes.Text): if (node.tagname == '#text' and node.parent and node.parent.tagname in TEXT_NODES):
# Determine the line number for this node lineno = get_line_number(node)
# Check the text of the node. for word, suggestions in self.checker.check(node.astext()):
msg_parts = [ docname ] if lineno: msg_parts.append( darkgreen('(line %3d)' % lineno) ) msg_parts.append(red(word)) msg_parts.append( self.format_suggestions(suggestions) ) msg = ' '.join(msg_parts) self.info(msg) self.output.write(u"%s:%s: (%s) %s\n" % ( self.env.doc2path(docname, None), lineno, word, self.format_suggestions(suggestions), ))
# Found at least one bad spelling self.app.statuscode = 1
return
def finish(self): self.output.close() self.info('Output written to %s' % self.output_filename) return
def setup(app): app.info('Initializing Spelling Checker') app.add_builder(SpellingBuilder) return
Saturday, March 16, 13
![Page 104: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/104.jpg)
from sphinx.builders import Builder
class SpellingBuilder(Builder):
name = 'spelling'
def init(self): self.docnames = [] self.document_data = []
project_words = os.path.join(self.srcdir, self.config.spelling_word_list_filename)
self.checker = SpellingChecker( lang=self.config.spelling_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=project_words, ) self.output_filename = os.path.join(self.outdir, 'output.txt') self.output = codecs.open(self.output_filename, 'wt', encoding='UTF-8')
def write_doc(self, docname, doctree):
filename = self.env.doc2path(docname, base=None)
for node in doctree.traverse(docutils.nodes.Text): if (node.tagname == '#text' and node.parent and node.parent.tagname in TEXT_NODES):
# Determine the line number for this node lineno = get_line_number(node)
# Check the text of the node. for word, suggestions in self.checker.check(node.astext()):
msg_parts = [ docname ] if lineno: msg_parts.append( darkgreen('(line %3d)' % lineno) ) msg_parts.append(red(word)) msg_parts.append( self.format_suggestions(suggestions) ) msg = ' '.join(msg_parts) self.info(msg) self.output.write(u"%s:%s: (%s) %s\n" % ( self.env.doc2path(docname, None), lineno, word, self.format_suggestions(suggestions), ))
# Found at least one bad spelling self.app.statuscode = 1
return
def finish(self): self.output.close() self.info('Output written to %s' % self.output_filename) return
def setup(app): app.info('Initializing Spelling Checker') app.add_builder(SpellingBuilder) return
Saturday, March 16, 13
![Page 105: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/105.jpg)
from sphinx.builders import Builder
class SpellingBuilder(Builder):
name = 'spelling'
def init(self): self.docnames = [] self.document_data = []
project_words = os.path.join(self.srcdir, self.config.spelling_word_list_filename)
self.checker = SpellingChecker( lang=self.config.spelling_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=project_words, ) self.output_filename = os.path.join(self.outdir, 'output.txt') self.output = codecs.open(self.output_filename, 'wt', encoding='UTF-8')
def write_doc(self, docname, doctree):
filename = self.env.doc2path(docname, base=None)
for node in doctree.traverse(docutils.nodes.Text): if (node.tagname == '#text' and node.parent and node.parent.tagname in TEXT_NODES):
# Determine the line number for this node lineno = get_line_number(node)
# Check the text of the node. for word, suggestions in self.checker.check(node.astext()):
msg_parts = [ docname ] if lineno: msg_parts.append( darkgreen('(line %3d)' % lineno) ) msg_parts.append(red(word)) msg_parts.append( self.format_suggestions(suggestions) ) msg = ' '.join(msg_parts) self.info(msg) self.output.write(u"%s:%s: (%s) %s\n" % ( self.env.doc2path(docname, None), lineno, word, self.format_suggestions(suggestions), ))
# Found at least one bad spelling self.app.statuscode = 1
return
def finish(self): self.output.close() self.info('Output written to %s' % self.output_filename) return
def setup(app): app.info('Initializing Spelling Checker') app.add_builder(SpellingBuilder) return
Saturday, March 16, 13
![Page 106: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/106.jpg)
from sphinx.builders import Builder
class SpellingBuilder(Builder):
name = 'spelling'
def init(self): self.docnames = [] self.document_data = []
project_words = os.path.join(self.srcdir, self.config.spelling_word_list_filename)
self.checker = SpellingChecker( lang=self.config.spelling_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=project_words, ) self.output_filename = os.path.join(self.outdir, 'output.txt') self.output = codecs.open(self.output_filename, 'wt', encoding='UTF-8')
def write_doc(self, docname, doctree):
filename = self.env.doc2path(docname, base=None)
for node in doctree.traverse(docutils.nodes.Text): if (node.tagname == '#text' and node.parent and node.parent.tagname in TEXT_NODES):
# Determine the line number for this node lineno = get_line_number(node)
# Check the text of the node. for word, suggestions in self.checker.check(node.astext()):
msg_parts = [ docname ] if lineno: msg_parts.append( darkgreen('(line %3d)' % lineno) ) msg_parts.append(red(word)) msg_parts.append( self.format_suggestions(suggestions) ) msg = ' '.join(msg_parts) self.info(msg) self.output.write(u"%s:%s: (%s) %s\n" % ( self.env.doc2path(docname, None), lineno, word, self.format_suggestions(suggestions), ))
# Found at least one bad spelling self.app.statuscode = 1
return
def finish(self): self.output.close() self.info('Output written to %s' % self.output_filename) return
def setup(app): app.info('Initializing Spelling Checker') app.add_builder(SpellingBuilder) return
Saturday, March 16, 13
![Page 107: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/107.jpg)
from sphinx.builders import Builder
class SpellingBuilder(Builder):
name = 'spelling'
def init(self): self.docnames = [] self.document_data = []
project_words = os.path.join(self.srcdir, self.config.spelling_word_list_filename)
self.checker = SpellingChecker( lang=self.config.spelling_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=project_words, ) self.output_filename = os.path.join(self.outdir, 'output.txt') self.output = codecs.open(self.output_filename, 'wt', encoding='UTF-8')
def write_doc(self, docname, doctree):
filename = self.env.doc2path(docname, base=None)
for node in doctree.traverse(docutils.nodes.Text): if (node.tagname == '#text' and node.parent and node.parent.tagname in TEXT_NODES):
# Determine the line number for this node lineno = get_line_number(node)
# Check the text of the node. for word, suggestions in self.checker.check(node.astext()):
msg_parts = [ docname ] if lineno: msg_parts.append( darkgreen('(line %3d)' % lineno) ) msg_parts.append(red(word)) msg_parts.append( self.format_suggestions(suggestions) ) msg = ' '.join(msg_parts) self.info(msg) self.output.write(u"%s:%s: (%s) %s\n" % ( self.env.doc2path(docname, None), lineno, word, self.format_suggestions(suggestions), ))
# Found at least one bad spelling self.app.statuscode = 1
return
def finish(self): self.output.close() self.info('Output written to %s' % self.output_filename) return
def setup(app): app.info('Initializing Spelling Checker') app.add_builder(SpellingBuilder) return
Saturday, March 16, 13
![Page 108: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/108.jpg)
from sphinx.builders import Builder
class SpellingBuilder(Builder):
name = 'spelling'
def init(self): self.docnames = [] self.document_data = []
project_words = os.path.join(self.srcdir, self.config.spelling_word_list_filename)
self.checker = SpellingChecker( lang=self.config.spelling_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=project_words, ) self.output_filename = os.path.join(self.outdir, 'output.txt') self.output = codecs.open(self.output_filename, 'wt', encoding='UTF-8')
def write_doc(self, docname, doctree):
filename = self.env.doc2path(docname, base=None)
for node in doctree.traverse(docutils.nodes.Text): if (node.tagname == '#text' and node.parent and node.parent.tagname in TEXT_NODES):
# Determine the line number for this node lineno = get_line_number(node)
# Check the text of the node. for word, suggestions in self.checker.check(node.astext()):
msg_parts = [ docname ] if lineno: msg_parts.append( darkgreen('(line %3d)' % lineno) ) msg_parts.append(red(word)) msg_parts.append( self.format_suggestions(suggestions) ) msg = ' '.join(msg_parts) self.info(msg) self.output.write(u"%s:%s: (%s) %s\n" % ( self.env.doc2path(docname, None), lineno, word, self.format_suggestions(suggestions), ))
# Found at least one bad spelling self.app.statuscode = 1
return
def finish(self): self.output.close() self.info('Output written to %s' % self.output_filename) return
def setup(app): app.info('Initializing Spelling Checker') app.add_builder(SpellingBuilder) return
Saturday, March 16, 13
![Page 109: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/109.jpg)
from sphinx.builders import Builder
class SpellingBuilder(Builder):
name = 'spelling'
def init(self): self.docnames = [] self.document_data = []
project_words = os.path.join(self.srcdir, self.config.spelling_word_list_filename)
self.checker = SpellingChecker( lang=self.config.spelling_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=project_words, ) self.output_filename = os.path.join(self.outdir, 'output.txt') self.output = codecs.open(self.output_filename, 'wt', encoding='UTF-8')
def write_doc(self, docname, doctree):
filename = self.env.doc2path(docname, base=None)
for node in doctree.traverse(docutils.nodes.Text): if (node.tagname == '#text' and node.parent and node.parent.tagname in TEXT_NODES):
# Determine the line number for this node lineno = get_line_number(node)
# Check the text of the node. for word, suggestions in self.checker.check(node.astext()):
msg_parts = [ docname ] if lineno: msg_parts.append( darkgreen('(line %3d)' % lineno) ) msg_parts.append(red(word)) msg_parts.append( self.format_suggestions(suggestions) ) msg = ' '.join(msg_parts) self.info(msg) self.output.write(u"%s:%s: (%s) %s\n" % ( self.env.doc2path(docname, None), lineno, word, self.format_suggestions(suggestions), ))
# Found at least one bad spelling self.app.statuscode = 1
return
def finish(self): self.output.close() self.info('Output written to %s' % self.output_filename) return
def setup(app): app.info('Initializing Spelling Checker') app.add_builder(SpellingBuilder) return
Saturday, March 16, 13
![Page 110: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/110.jpg)
from sphinx.builders import Builder
class SpellingBuilder(Builder):
name = 'spelling'
def init(self): self.docnames = [] self.document_data = []
project_words = os.path.join(self.srcdir, self.config.spelling_word_list_filename)
self.checker = SpellingChecker( lang=self.config.spelling_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=project_words, ) self.output_filename = os.path.join(self.outdir, 'output.txt') self.output = codecs.open(self.output_filename, 'wt', encoding='UTF-8')
def write_doc(self, docname, doctree):
filename = self.env.doc2path(docname, base=None)
for node in doctree.traverse(docutils.nodes.Text): if (node.tagname == '#text' and node.parent and node.parent.tagname in TEXT_NODES):
# Determine the line number for this node lineno = get_line_number(node)
# Check the text of the node. for word, suggestions in self.checker.check(node.astext()):
msg_parts = [ docname ] if lineno: msg_parts.append( darkgreen('(line %3d)' % lineno) ) msg_parts.append(red(word)) msg_parts.append( self.format_suggestions(suggestions) ) msg = ' '.join(msg_parts) self.info(msg) self.output.write(u"%s:%s: (%s) %s\n" % ( self.env.doc2path(docname, None), lineno, word, self.format_suggestions(suggestions), ))
# Found at least one bad spelling self.app.statuscode = 1
return
def finish(self): self.output.close() self.info('Output written to %s' % self.output_filename) return
def setup(app): app.info('Initializing Spelling Checker') app.add_builder(SpellingBuilder) return
Saturday, March 16, 13
![Page 111: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/111.jpg)
from sphinx.builders import Builder
class SpellingBuilder(Builder):
name = 'spelling'
def init(self): self.docnames = [] self.document_data = []
project_words = os.path.join(self.srcdir, self.config.spelling_word_list_filename)
self.checker = SpellingChecker( lang=self.config.spelling_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=project_words, ) self.output_filename = os.path.join(self.outdir, 'output.txt') self.output = codecs.open(self.output_filename, 'wt', encoding='UTF-8')
def write_doc(self, docname, doctree):
filename = self.env.doc2path(docname, base=None)
for node in doctree.traverse(docutils.nodes.Text): if (node.tagname == '#text' and node.parent and node.parent.tagname in TEXT_NODES):
# Determine the line number for this node lineno = get_line_number(node)
# Check the text of the node. for word, suggestions in self.checker.check(node.astext()):
msg_parts = [ docname ] if lineno: msg_parts.append( darkgreen('(line %3d)' % lineno) ) msg_parts.append(red(word)) msg_parts.append( self.format_suggestions(suggestions) ) msg = ' '.join(msg_parts) self.info(msg) self.output.write(u"%s:%s: (%s) %s\n" % ( self.env.doc2path(docname, None), lineno, word, self.format_suggestions(suggestions), ))
# Found at least one bad spelling self.app.statuscode = 1
return
def finish(self): self.output.close() self.info('Output written to %s' % self.output_filename) return
def setup(app): app.info('Initializing Spelling Checker') app.add_builder(SpellingBuilder) return
Saturday, March 16, 13
![Page 112: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/112.jpg)
from sphinx.builders import Builder
class SpellingBuilder(Builder):
name = 'spelling'
def init(self): self.docnames = [] self.document_data = []
project_words = os.path.join(self.srcdir, self.config.spelling_word_list_filename)
self.checker = SpellingChecker( lang=self.config.spelling_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=project_words, ) self.output_filename = os.path.join(self.outdir, 'output.txt') self.output = codecs.open(self.output_filename, 'wt', encoding='UTF-8')
def write_doc(self, docname, doctree):
filename = self.env.doc2path(docname, base=None)
for node in doctree.traverse(docutils.nodes.Text): if (node.tagname == '#text' and node.parent and node.parent.tagname in TEXT_NODES):
# Determine the line number for this node lineno = get_line_number(node)
# Check the text of the node. for word, suggestions in self.checker.check(node.astext()):
msg_parts = [ docname ] if lineno: msg_parts.append( darkgreen('(line %3d)' % lineno) ) msg_parts.append(red(word)) msg_parts.append( self.format_suggestions(suggestions) ) msg = ' '.join(msg_parts) self.info(msg) self.output.write(u"%s:%s: (%s) %s\n" % ( self.env.doc2path(docname, None), lineno, word, self.format_suggestions(suggestions), ))
# Found at least one bad spelling self.app.statuscode = 1
return
def finish(self): self.output.close() self.info('Output written to %s' % self.output_filename) return
def setup(app): app.info('Initializing Spelling Checker') app.add_builder(SpellingBuilder) return
Saturday, March 16, 13
![Page 113: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/113.jpg)
from sphinx.builders import Builder
class SpellingBuilder(Builder):
name = 'spelling'
def init(self): self.docnames = [] self.document_data = []
project_words = os.path.join(self.srcdir, self.config.spelling_word_list_filename)
self.checker = SpellingChecker( lang=self.config.spelling_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=project_words, ) self.output_filename = os.path.join(self.outdir, 'output.txt') self.output = codecs.open(self.output_filename, 'wt', encoding='UTF-8')
def write_doc(self, docname, doctree):
filename = self.env.doc2path(docname, base=None)
for node in doctree.traverse(docutils.nodes.Text): if (node.tagname == '#text' and node.parent and node.parent.tagname in TEXT_NODES):
# Determine the line number for this node lineno = get_line_number(node)
# Check the text of the node. for word, suggestions in self.checker.check(node.astext()):
msg_parts = [ docname ] if lineno: msg_parts.append( darkgreen('(line %3d)' % lineno) ) msg_parts.append(red(word)) msg_parts.append( self.format_suggestions(suggestions) ) msg = ' '.join(msg_parts) self.info(msg) self.output.write(u"%s:%s: (%s) %s\n" % ( self.env.doc2path(docname, None), lineno, word, self.format_suggestions(suggestions), ))
# Found at least one bad spelling self.app.statuscode = 1
return
def finish(self): self.output.close() self.info('Output written to %s' % self.output_filename) return
def setup(app): app.info('Initializing Spelling Checker') app.add_builder(SpellingBuilder) return
Saturday, March 16, 13
![Page 114: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/114.jpg)
from sphinx.builders import Builder
class SpellingBuilder(Builder):
name = 'spelling'
def init(self): self.docnames = [] self.document_data = []
project_words = os.path.join(self.srcdir, self.config.spelling_word_list_filename)
self.checker = SpellingChecker( lang=self.config.spelling_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=project_words, ) self.output_filename = os.path.join(self.outdir, 'output.txt') self.output = codecs.open(self.output_filename, 'wt', encoding='UTF-8')
def write_doc(self, docname, doctree):
filename = self.env.doc2path(docname, base=None)
for node in doctree.traverse(docutils.nodes.Text): if (node.tagname == '#text' and node.parent and node.parent.tagname in TEXT_NODES):
# Determine the line number for this node lineno = get_line_number(node)
# Check the text of the node. for word, suggestions in self.checker.check(node.astext()):
msg_parts = [ docname ] if lineno: msg_parts.append( darkgreen('(line %3d)' % lineno) ) msg_parts.append(red(word)) msg_parts.append( self.format_suggestions(suggestions) ) msg = ' '.join(msg_parts) self.info(msg) self.output.write(u"%s:%s: (%s) %s\n" % ( self.env.doc2path(docname, None), lineno, word, self.format_suggestions(suggestions), ))
# Found at least one bad spelling self.app.statuscode = 1
return
def finish(self): self.output.close() self.info('Output written to %s' % self.output_filename) return
def setup(app): app.info('Initializing Spelling Checker') app.add_builder(SpellingBuilder) return
Saturday, March 16, 13
![Page 115: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/115.jpg)
$ sphinx-build -b spelling -d build/doctrees \ source build/spelling
Running Sphinx v1.1.2Initializing Spelling Checkerloading reprint directiveloading books directivesloading pickled environment... donebuilding [spelling]: all documentsupdating environment: 0 added, 0 changed, 0 removedlooking for now-outdated files... none foundpreparing documents... doneindex (line 13) blarg ["blare", "blarney", "Blair", "blamer", "blazer", "blog"] writing output... [100%]Spelling checker messages written to /Users/dhellmann/Devel/website/website/build/spelling/output.txtbuild finished with problems.
Saturday, March 16, 13
![Page 116: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/116.jpg)
$ sphinx-build -b spelling -d build/doctrees \ source build/spelling
Running Sphinx v1.1.2Initializing Spelling Checkerloading reprint directiveloading books directivesloading pickled environment... donebuilding [spelling]: all documentsupdating environment: 0 added, 0 changed, 0 removedlooking for now-outdated files... none foundpreparing documents... doneindex (line 13) blarg ["blare", "blarney", "Blair", "blamer", "blazer", "blog"] writing output... [100%]Spelling checker messages written to /Users/dhellmann/Devel/website/website/build/spelling/output.txtbuild finished with problems.
Saturday, March 16, 13
![Page 117: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/117.jpg)
$ sphinx-build -b spelling -d build/doctrees \ source build/spelling
Running Sphinx v1.1.2Initializing Spelling Checkerloading reprint directiveloading books directivesloading pickled environment... donebuilding [spelling]: all documentsupdating environment: 0 added, 0 changed, 0 removedlooking for now-outdated files... none foundpreparing documents... doneindex (line 13) blarg ["blare", "blarney", "Blair", "blamer", "blazer", "blog"] writing output... [100%]Spelling checker messages written to /Users/dhellmann/Devel/website/website/build/spelling/output.txtbuild finished with problems.
Saturday, March 16, 13
![Page 118: Better Documentation Through Automation: Creating docutils & Sphinx Extensions](https://reader033.vdocuments.us/reader033/viewer/2022052321/5554b063b4c905fd608b554e/html5/thumbnails/118.jpg)
Better Documentation Through Automation:Creating docutils & Sphinx Extensions
Doug Hellmann@doughellmannPyCon 2013
http://docutils.sourceforge.net/https://bitbucket.org/birkenfeld/sphinx-contrib/http://packages.python.org/pyenchant/http://doughellmann.com
Saturday, March 16, 13