[Checkins] SVN: manuel/trunk/src/ - reorganize the many small documentation files into a larger one

Benji York benji at zope.com
Tue Jun 23 09:16:13 EDT 2009


Log message for revision 101249:
  - reorganize the many small documentation files into a larger one
  - make the documentation more documenty and lest testy
  

Changed:
  D   manuel/trunk/src/functionality.txt
  D   manuel/trunk/src/getting-started.txt
  D   manuel/trunk/src/index.txt
  A   manuel/trunk/src/index.txt
  D   manuel/trunk/src/intro.txt
  U   manuel/trunk/src/manuel/README.txt
  D   manuel/trunk/src/manuel/capture.txt
  U   manuel/trunk/src/manuel/codeblock.py
  D   manuel/trunk/src/manuel/codeblock.txt
  D   manuel/trunk/src/manuel/doctest.txt
  D   manuel/trunk/src/manuel/footnote.txt
  D   manuel/trunk/src/manuel/ignore.txt
  D   manuel/trunk/src/manuel/isolation.txt
  U   manuel/trunk/src/manuel/table-example.txt
  U   manuel/trunk/src/manuel/tests.py

-=-
Deleted: manuel/trunk/src/functionality.txt
===================================================================
--- manuel/trunk/src/functionality.txt	2009-06-23 12:05:48 UTC (rev 101248)
+++ manuel/trunk/src/functionality.txt	2009-06-23 13:16:12 UTC (rev 101249)
@@ -1,25 +0,0 @@
-.. _functionality:
-
-Included Functionality
-======================
-
-Manuel includes several plug-ins out of the box:
-
-:ref:`manuel.capture <capture>`
-    stores regions of a document in variables for later processing
-
-:ref:`manuel.codeblock <code-blocks>`
-    executes code in ".. code-block:: python" blocks
-
-:ref:`manuel.doctest <doctest>`
-    provides traditional doctest processing as a Manuel plug-in
-
-:ref:`manuel.footnote <footnotes>`
-    executes code in reST-style footnodes each time they're referenced (good
-    for getting incedental code out of the main flow of a document)
-
-:ref:`manuel.ignore <ignore>`
-    ignores parts of a document while running tests
-
-:ref:`manuel.isolation <isolation>`
-    makes it easier to have test isolation in doctests

Deleted: manuel/trunk/src/getting-started.txt
===================================================================
--- manuel/trunk/src/getting-started.txt	2009-06-23 12:05:48 UTC (rev 101248)
+++ manuel/trunk/src/getting-started.txt	2009-06-23 13:16:12 UTC (rev 101249)
@@ -1,85 +0,0 @@
-.. _getting-started:
-
-Getting Started
-===============
-
-The plug-ins used for a test are composed together using the "+" operator.
-Let's say you wanted a test that used doctest syntax as well as footnotes.  You
-would create a Manuel instance to use like this:
-
-.. code-block:: python
-
-    import manuel.doctest
-    import manuel.footnote
-
-    m = manuel.doctest.Manuel() + manuel.footnote.Manuel()
-
-You would then pass the Manuel instance to a :class:`manuel.testing.TestSuite`,
-including the names of documents you want to process:
-
-.. ignore-next-block
-.. code-block:: python
-
-    manuel.testing.TestSuite(m, 'test-one.txt', 'test-two.txt')
-
-
-Using unittest
---------------
-
-The simplest way to get started with Manuel is to use :mod:`unittest` to run
-your tests:
-
-.. code-block:: python
-
-    import manuel.codeblock
-    import manuel.doctest
-    import manuel.testing
-    import unittest
-
-    def test_suite():
-        m = manuel.doctest.Manuel()
-        m += manuel.codeblock.Manuel()
-        return manuel.testing.TestSuite(m, 'test-one.txt', 'test-two.txt')
-
-    if __name__ == '__main__':
-        unittest.TextTestRunner().run(test_suite())
-
-
-Using zope.testing
-------------------
-
-If you want to use a more featurfull test runner you can use zope.testing's
-test runner (usable stand-alone -- it isn't dependent on the Zope application
-server).  Create a file named :file:`tests.py` with a :func:`test_setup`
-function that returns a test suite.
-
-The suite can be either a :class:`manuel.testing.TestSuite` object or a
-:class:`unittest.TestSuite` as demonstrated below.
-
-.. code-block:: python
-
-    import manuel.codeblock
-    import manuel.doctest
-    import manuel.testing
-
-    def test_suite():
-        suite = unittest.TestSuite()
-
-        # here you add your other tests to the suite...
-
-        # now you can add the Manuel tests
-        m = manuel.doctest.Manuel()
-        m += manuel.codeblock.Manuel()
-        suite.addTest(manuel.testing.TestSuite(m,
-            'test-one.txt', 'test-two.txt'))
-
-        return suite
-
-
-Others
-------
-
-If you figure out how to make Manuel work with other test runners (nose,
-py.test, etc.), please `send me an email`_ and I'll expand this section.
-
-.. _send me an email: benji+manuel at benjiyork.com

Deleted: manuel/trunk/src/index.txt
===================================================================
--- manuel/trunk/src/index.txt	2009-06-23 12:05:48 UTC (rev 101248)
+++ manuel/trunk/src/index.txt	2009-06-23 13:16:12 UTC (rev 101249)
@@ -1,20 +0,0 @@
-====================
-Manuel documentation
-====================
-
-.. toctree::
-    :maxdepth: 1
-    :numbered:
-
-    intro.txt
-    functionality.txt
-    getting-started.txt
-    manuel/capture.txt
-    manuel/codeblock.txt
-    manuel/doctest.txt
-    manuel/footnote.txt
-    manuel/ignore.txt
-    manuel/isolation.txt
-    manuel/README.txt
-    manuel/table-example.txt
-    manuel/bugs.txt

Copied: manuel/trunk/src/index.txt (from rev 101247, manuel/trunk/src/intro.txt)
===================================================================
--- manuel/trunk/src/index.txt	                        (rev 0)
+++ manuel/trunk/src/index.txt	2009-06-23 13:16:12 UTC (rev 101249)
@@ -0,0 +1,751 @@
+======
+Manuel
+======
+
+Manuel lets you mix and match traditional doctests with custom test syntax.
+
+Several plug-ins are included that provide new test syntax (see
+:ref:`functionality`).  You can also create your own plug-ins.
+
+For example, if you've ever wanted to include a large chunk of Python in a
+doctest but were irritated by all the ">>>" and "..." prompts required, you'd
+like the :mod:`manuel.codeblock` module.  It lets you execute code using
+Sphinx-style "..  code-block:: python" directives.  The markup looks like
+this::
+
+    .. code-block:: python
+
+        import foo
+
+        def my_func(bar):
+            return foo.baz(bar)
+
+Incidentally, the implementation of :mod:`manuel.codeblock` is only 22 lines of
+code.
+
+The plug-ins included in Manuel make good examples while being quite useful in
+their own right.  The Manuel documentation makes extensive use of them as well.
+Follow the "Show Source" link to the left to see the `reST
+<http://docutils.sourceforge.net/rst.html>`_ source of this document.
+
+For a large example of creating test syntax, take a look at the
+:ref:`fit-table-example` or for all the details, :ref:`theory-of-operation`.
+
+To see how to get Manuel wired up see :ref:`getting-started`.
+
+.. contents::
+
+
+.. reset-globs
+.. _functionality:
+
+Included Functionality
+======================
+
+Manuel includes several plug-ins out of the box:
+
+:ref:`manuel.capture <capture>`
+    stores regions of a document in variables for later processing
+
+:ref:`manuel.codeblock <code-blocks>`
+    executes code in ".. code-block:: python" blocks
+
+:ref:`manuel.doctest <doctest>`
+    provides traditional doctest processing as a Manuel plug-in
+
+:ref:`manuel.footnote <footnotes>`
+    executes code in reST-style footnodes each time they're referenced (good
+    for getting incedental code out of the main flow of a document)
+
+:ref:`manuel.ignore <ignore>`
+    ignores parts of a document while running tests
+
+:ref:`manuel.isolation <isolation>`
+    makes it easier to have test isolation in doctests
+
+
+.. reset-globs
+.. _getting-started:
+
+Getting Started
+===============
+
+The plug-ins used for a test are composed together using the "+" operator.
+Let's say you wanted a test that used doctest syntax as well as footnotes.  You
+would create a Manuel instance to use like this:
+
+.. code-block:: python
+
+    import manuel.doctest
+    import manuel.footnote
+
+    m = manuel.doctest.Manuel() + manuel.footnote.Manuel()
+
+You would then pass the Manuel instance to a :class:`manuel.testing.TestSuite`,
+including the names of documents you want to process:
+
+.. ignore-next-block
+.. code-block:: python
+
+    manuel.testing.TestSuite(m, 'test-one.txt', 'test-two.txt')
+
+
+Using unittest
+--------------
+
+The simplest way to get started with Manuel is to use :mod:`unittest` to run
+your tests:
+
+.. code-block:: python
+
+    import manuel.codeblock
+    import manuel.doctest
+    import manuel.testing
+    import unittest
+
+    def test_suite():
+        m = manuel.doctest.Manuel()
+        m += manuel.codeblock.Manuel()
+        return manuel.testing.TestSuite(m, 'test-one.txt', 'test-two.txt')
+
+    if __name__ == '__main__':
+        unittest.TextTestRunner().run(test_suite())
+
+
+Using zope.testing
+------------------
+
+If you want to use a more featurfull test runner you can use zope.testing's
+test runner (usable stand-alone -- it isn't dependent on the Zope application
+server).  Create a file named :file:`tests.py` with a :func:`test_setup`
+function that returns a test suite.
+
+The suite can be either a :class:`manuel.testing.TestSuite` object or a
+:class:`unittest.TestSuite` as demonstrated below.
+
+.. code-block:: python
+
+    import manuel.codeblock
+    import manuel.doctest
+    import manuel.testing
+
+    def test_suite():
+        suite = unittest.TestSuite()
+
+        # here you add your other tests to the suite...
+
+        # now you can add the Manuel tests
+        m = manuel.doctest.Manuel()
+        m += manuel.codeblock.Manuel()
+        suite.addTest(manuel.testing.TestSuite(m,
+            'test-one.txt', 'test-two.txt'))
+
+        return suite
+
+
+Others
+------
+
+If you figure out how to make Manuel work with other test runners (nose,
+py.test, etc.), please `send me an email`_ and I'll expand this section.
+
+.. _send me an email: benji+manuel at benjiyork.com
+
+
+.. reset-globs
+.. _doctest:
+
+Doctests
+========
+
+Manuel is all about making testable documents and well-documented tests.  Of
+course, Python's doctest module is a long-standing fixture in that space, so it
+only makes sense for Manuel to support doctest syntax.
+
+Handling doctests is easy:
+
+.. ignore-next-block
+.. code-block:: python
+
+    import manuel.doctest
+
+    m = manuel.doctest.Manuel()
+    suite = manuel.testing.TestSuite(m, 'my-doctest.txt')
+
+Of course you can mix in other Manuel syntax plug-ins as well (including ones
+you write yourself).
+
+.. ignore-next-block
+.. code-block:: python
+
+    import manuel.doctest
+    import manuel.codeblock
+
+    m = manuel.doctest.Manuel()
+    m += manuel.codeblock.Manuel()
+    suite = manuel.testing.TestSuite(m, 'my-doctest-with-code-blocks.txt')
+
+The :class:`manuel.doctest.Manuel` constructor also takes :data:`optionflags`
+and :data:`checker` arguments.
+
+.. ignore-next-block
+.. code-block:: python
+
+    m = manuel.doctest.Manuel(optionflags=optionflags, checker=checker)
+
+See the `doctest documentation <http://docs.python.org/library/doctest.html>`_
+for more information about the `available options
+<http://docs.python.org/library/doctest.html#doctest-options>`_  and `output
+checkers <http://docs.python.org/library/doctest.html#outputchecker-objects>`_
+
+
+.. note:: :mod:`zope.testing.renormalizing` provides an :class:`OutputChecker`
+   for smoothing out differences between actual and expected output for things
+   that are hard to control (like memory addresses and time).  See the
+   `module's doctests <http://svn.zope.org/zope.testing/trunk/src/zope/testing/renormalizing.py?view=markup>`_
+   for more information on how it works.
+
+
+.. reset-globs
+.. _capture:
+
+Capturing Blocks
+================
+
+When writing documentation the need often arrises to describe the contents of
+files or other non-python information.  You may also want to put that
+information under test.  :mod:`manuel.capture` helps with that.
+
+If you were writing the problems for a programming contest, you might want to
+describe the input and output files for each challenge.
+
+You would then show the contestant the expected output of their program.  But
+you want to be sure that your examples are correct.
+
+To do that you might write your document like this:
+
+::
+
+    Given this example input file::
+
+        6
+        1
+        8
+        20
+        11
+        65
+        2
+
+    .. -> input
+
+    Your program should generare this output file::
+
+        1
+        2
+        6
+        8
+        11
+        20
+        65
+
+    .. -> expected
+
+        >>> correct = '\n'.join(
+        ...     map(str, sorted(map(int, input.splitlines())))) + '\n'
+        >>> expected == correct
+        True
+
+.. -> source
+
+    >>> import manuel
+    >>> document = manuel.Document(source)
+    >>> import manuel.capture
+    >>> m = manuel.capture.Manuel()
+    >>> import manuel.doctest
+    >>> m += manuel.doctest.Manuel()
+    >>> document.process_with(m, globs={})
+    >>> print document.formatted(),
+
+This uses the syntax implemented in :mod:`manuel.collect` to capture a block of
+text into a varible (the one named after "->").
+
+Whenever a line of the structure ".. -> VAR" is detected, the text of the
+*previous* block will be stored in the given variable.
+
+.. the paragraph below could be phrased better
+
+Of course, lines that start with ".. " are reST comments, so when the document
+is rendered with docutils or Sphinx, the tests will dissapear and only the
+intended document contents will remain.
+
+
+.. reset-globs
+.. _code-blocks:
+
+Code Blocks
+===========
+
+`Sphinx <http://sphinx.pocoo.org/>`_ and other docutils `extensions
+<http://docutils.sourceforge.net/sandbox/code-block-directive/docs/syntax-highlight.html>`_
+provide a `"code-block" directive <http://sphinx.pocoo.org/markup/code.html>`_,
+which allows inlined snippets of code in reST documents.
+
+The :mod:`manuel.codeblock` module provides the ability to execute the contents
+of Python code-blocks.  For example::
+
+    .. code-block:: python
+
+        print 'hello'
+
+.. Let's create a reST document with a code block.
+
+    >>> import manuel.codeblock
+    >>> document = manuel.Document("""
+    ... Here is a code-block:
+    ...
+    ... .. code-block:: python
+    ...
+    ...     x = 'hello'
+    ...
+    ... A little prose to separate the examples.
+    ...
+    ...     >>> print x
+    ...     hello
+    ...
+    ... """)
+
+.. Since the above document mixes code-blocks and doctests, we'll mix in the
+   doctest handler.
+
+    >>> import manuel.doctest
+    >>> m = manuel.codeblock.Manuel()
+    >>> m += manuel.doctest.Manuel()
+    >>> document.process_with(m, globs={})
+
+    Both code blocks were found (for a total of five regions -- text, block,
+    text, block, and text):
+
+    >>> len(list(document))
+    5
+
+    We can see that none of the tests in the document failed:
+
+    >>> print document.formatted(),
+
+If the code-block generates some sort of error...
+
+.. code-block:: python
+
+    .. code-block:: python
+
+        print does_not_exist
+
+.. -> source
+
+    >>> document = manuel.Document(source, location='fake.txt')
+
+.. the document above was specially formulated to have nothing before or after
+   the code-block
+
+    >>> document.source.startswith('.. code-block')
+    True
+    >>> document.source.endswith('print does_not_exist\n')
+    True
+
+...that error will be reported:
+
+    >>> document.process_with(m, globs={})
+    Traceback (most recent call last):
+        ...
+    NameError: name 'does_not_exist' is not defined
+
+If you find that you want to include a code-block in a document but don't want
+Manuel to execute it, use :ref:`manuel.ignore <ignore>` to ignore that
+particular block.
+
+
+Invisible Code Blocks
+---------------------
+
+At times you'll want to have a block of code that is executed but not displayed
+in the rendered document (like some setup for later examples).
+
+When using doctest's native format (">>>") that's easy to do, you just put the
+code in a reST comment, like so:
+
+::
+
+    .. this is some setup, it is hidden in a reST comment
+
+        >>> a = 5
+        >>> b = a + 3
+
+However, if you want to include a relatively large chunk of Python, you'd
+rather use a code-block, but that means that it will be included in the
+rendered document.  Instead, :mod:`manuel.codeblock` also understands a variant
+of the code-block directive that is actually a reST comment: "..
+invisible-code-block:: python"::
+
+    .. invisible-code-block:: python
+
+        a = 5
+        b = a + 3
+
+.. -> source
+
+    >>> import manuel
+    >>> document = manuel.Document(source)
+    >>> document.process_with(m, globs={})
+    >>> print document.formatted()
+
+.. note: The "invisible-code-block" directive will work with either one or two
+   colons.  The reason is that reST processers (like docutils and Sphinx) will
+   generate an error for unrecognized directives (like invisible-code-block).
+   Therefore you can use a single colon and the line will be interpreted as a
+   comment instead.
+
+.. the single-colon variant works too
+
+    >>> document = manuel.Document("""
+    ...
+    ... .. invisible-code-block: python
+    ...
+    ...     raise RuntimeError('it worked!')
+    ...
+    ... """)
+    >>> document.process_with(m, globs={})
+    Traceback (most recent call last):
+        ...
+    RuntimeError: it worked!
+
+
+.. reset-globs
+.. _footnotes:
+
+Footnotes
+=========
+
+The :mod:`manuel.footnote` module provides an implementation of reST footnote
+handling, but instead of just plain text, the footnotes can contain any syntax
+Manuel can interpret including doctests.
+
+    >>> import manuel.footnote
+    >>> m = manuel.footnote.Manuel()
+
+Here's an example of combining footnotes with doctests:
+
+.. so we also need the doctest Manuel plug-in
+
+    >>> import manuel.doctest
+    >>> m += manuel.doctest.Manuel()
+
+::
+
+    Here we reference a footnote. [1]_
+
+        >>> x
+        42
+
+    Here we reference another. [2]_
+
+        >>> x
+        100
+
+    .. [1] This is a test footnote definition.
+
+        >>> x = 42
+
+    .. [2] This is another test footnote definition.
+
+        >>> x = 100
+
+    .. [3] This is a footnote that will never be executed.
+
+        >>> raise RuntimeError('nooooo!')
+
+.. -> source
+
+    >>> import manuel
+    >>> document = manuel.Document(source)
+    >>> document.process_with(m, globs={})
+    >>> print document.formatted(),
+
+.. The order of examples in footnotes is preserved.  If not, the document below
+   would generate an error because "a" won't be defined when "b = a + 1" is
+   evaluated.
+
+    >>> document = manuel.Document("""
+    ... Here we want some imports to be done. [foo]_
+    ...
+    ...     >>> a + b
+    ...     3
+    ...
+    ... A little prose to separate the examples.
+    ...
+    ... .. [foo] Do something
+    ...
+    ...     >>> a = 1
+    ...
+    ...     >>> b = a + 1
+    ...
+    ... """)
+    >>> document.process_with(m, globs={})
+    >>> print document.formatted()
+
+It is possible to reference more than one footnote on a single line.
+
+::
+
+    This line has several footnotes on it. [1]_ [2]_ [3]_
+
+        >>> z
+        105
+
+    A little prose to separate the examples.
+
+    .. [1] Do something
+
+        >>> w = 3
+
+    .. [2] Do something
+
+        >>> x = 5
+
+    .. [3] Do something
+
+        >>> y = 7
+
+        >>> z = w * x * y
+
+.. -> source2
+
+    >>> document = manuel.Document(source)
+    >>> document.process_with(m, globs={})
+    >>> print document.formatted()
+
+
+.. reset-globs
+.. _ignore:
+
+Ignoring Blocks
+===============
+
+.. reset-globs
+
+Occasionally the need arrises to ignore a block of markup that would otherwise
+be parsed by a Manuel plug-in.
+
+For example, this document has a code-block that will generate a syntax error::
+
+    The following is invalid Python.
+
+    .. code-block:: python
+
+        def foo:
+            pass
+
+.. -> source
+
+    >>> import manuel
+    >>> document = manuel.Document(source)
+    >>> import manuel.codeblock
+    >>> m = manuel.codeblock.Manuel()
+
+We can see that when executed, the SyntaxError escapes.
+
+    >>> import manuel.codeblock
+    >>> m = manuel.codeblock.Manuel()
+    >>> document.process_with(m, globs={})
+    Traceback (most recent call last):
+      ...
+      File "<memory>:4", line 2
+         def foo:
+                ^
+    SyntaxError: invalid syntax
+
+The :mod:`manuel.ignore` module provides a way to ignore parts of a document
+using a directive ".. ignore-next-block".
+
+Because Manuel plug-ins are executed in the order they are accumulated, we want
+:mod:`manuel.ignore` to be the base Manuel object, with any additional plug-ins
+added to it.
+
+.. code-block:: python
+
+    import manuel.ignore
+    import manuel.doctest
+    m = manuel.ignore.Manuel()
+    m += manuel.codeblock.Manuel()
+    m += manuel.doctest.Manuel()
+
+If we add an ignore marker to the block we don't want processed...
+
+.. code-block:: python
+
+    The following is invalid Python.
+
+    .. ignore-next-block
+    .. code-block:: python
+
+        def foo:
+            pass
+
+.. -> source
+
+    >>> document = manuel.Document(source)
+
+...the error goes away.
+
+    >>> document.process_with(m, globs={})
+    >>> print document.formatted(),
+
+
+Ignoring Literal Blocks
+-----------------------
+
+Ignoring literal blocks is a little more involved::
+
+    Here is some invalid Python:
+
+    .. ignore-next-block
+
+    ::
+
+       >>> lambda: print 'hi'
+
+.. -> source
+
+    >>> document = manuel.Document(source)
+
+    >>> document.process_with(m, globs={})
+    >>> print document.formatted(),
+
+.. we want to be very sure that the above example without the ignore actually
+   generates an error:
+
+    >>> document = manuel.Document(document.source.replace(
+    ...     '.. ignore-next-block', ''))
+    >>> document.process_with(m, globs={})
+    >>> print document.formatted(),
+    File "<memory>"...
+    Failed example:
+        lambda: print 'hi'
+    Exception raised:
+          ...
+          File "<doctest <memory>[0]>", line 1
+             lambda: print 'hi'
+                         ^
+         SyntaxError: invalid syntax
+
+
+.. reset-globs
+.. _isolation:
+
+Test Isolation
+==============
+
+One of the advantages of unittest over doctest is that the individual tests are
+isolated from one-another.
+
+In large doctests (like this one) you may want to keep later tests from
+depending on incedental details of earlier tests, preventing the tests from
+becoming brittle and harder to change.
+
+Test isolation is one approach to reducing this intra-doctest coupling.  The
+:mod:`manuel.isolation` module provides a plug-in to help.
+
+The ".. reset-globs" directive resets the globals in the test::
+
+    We define a variable.
+
+        >>> x = 'hello'
+
+    It is still defined.
+
+        >>> print x
+        hello
+
+    Now we can reset the globals...
+
+    .. reset-globs
+
+    ...and the name binding will be gone:
+
+        >>> print x
+        Traceback (most recent call last):
+            ...
+        NameError: name 'x' is not defined
+
+.. -> source
+
+    >>> import manuel
+    >>> document = manuel.Document(source)
+    >>> import manuel.isolation
+    >>> import manuel.doctest
+    >>> m = manuel.isolation.Manuel()
+    >>> m += manuel.doctest.Manuel()
+
+We can see that after the globals have been reset, the second "print x" line
+raises an error.
+
+Of course, resetting to an empty set of global variables isn't always what's
+wanted.  In that case there is a ".. capture-globs" directive that saves a
+baseline set of globals that will be restored at each reset.
+
+::
+
+    We define a variable.
+
+        >>> x = 'hello'
+
+    It is still defined.
+
+        >>> print x
+        hello
+
+    We can capture the currently defined globals:
+
+    .. capture-globs
+
+    Of course capturing the globals doesn't disturb them.
+
+        >>> print x
+        hello
+
+    Now if we define a new global...
+
+        >>> y = 'goodbye'
+        >>> print y
+        goodbye
+
+    .. reset-globs
+
+    ...it will disappear after a reset.
+
+        >>> print y
+        Traceback (most recent call last):
+            ...
+        NameError: name 'y' is not defined
+
+    But the captured globals will still be defined.
+
+        >>> print x
+        hello
+
+.. -> source
+
+    >>> import manuel
+    >>> document = manuel.Document(source)
+    >>> document.process_with(m, globs={})
+    >>> print document.formatted(),
+
+
+Further Reading
+===============
+
+.. toctree::
+    :maxdepth: 1
+
+    manuel/README.txt
+    manuel/table-example.txt
+    manuel/bugs.txt


Property changes on: manuel/trunk/src/index.txt
___________________________________________________________________
Added: svn:mergeinfo
   + 
Added: svn:eol-style
   + native

Deleted: manuel/trunk/src/intro.txt
===================================================================
--- manuel/trunk/src/intro.txt	2009-06-23 12:05:48 UTC (rev 101248)
+++ manuel/trunk/src/intro.txt	2009-06-23 13:16:12 UTC (rev 101249)
@@ -1,33 +0,0 @@
-Introduction
-============
-
-Manuel lets you mix and match traditional doctests with custom test syntax.
-
-Several plug-ins are included that provide new test syntax (see
-:ref:`functionality`).  You can also create your own plug-ins.
-
-For example, if you've ever wanted to include a large chunk of Python in a
-doctest but were irritated by all the ">>>" and "..." prompts required, you'd
-like the :mod:`manuel.codeblock` module.  It lets you execute code using
-Sphinx-style "..  code-block:: python" directives.  The markup looks like
-this::
-
-    .. code-block:: python
-
-        import foo
-
-        def my_func(bar):
-            return foo.baz(bar)
-
-Incidentally, the implementation of :mod:`manuel.codeblock` is only 22 lines of
-code.
-
-The plug-ins included in Manuel make good examples while being quite useful in
-their own right.  The Manuel documentation makes extensive use of them as well.
-All the included plug-ins are listed in the :ref:`next section
-<functionality>`.
-
-For a large example of creating test syntax, take a look at the
-:ref:`fit-table-example` or for all the details, :ref:`theory-of-operation`.
-
-To see how to get Manuel wired up see the :ref:`getting-started` section.

Modified: manuel/trunk/src/manuel/README.txt
===================================================================
--- manuel/trunk/src/manuel/README.txt	2009-06-23 12:05:48 UTC (rev 101248)
+++ manuel/trunk/src/manuel/README.txt	2009-06-23 13:16:12 UTC (rev 101249)
@@ -3,6 +3,8 @@
 Theory of Operation
 ===================
 
+.. XXX this really wants to be a "How To Write a Plug-in" tutorial.
+
 Manuel parses documents (tests), evaluates their contents, then formats the
 result of the evaluation.  The functionality is accessed via the :mod:`manuel`
 package.

Deleted: manuel/trunk/src/manuel/capture.txt
===================================================================
--- manuel/trunk/src/manuel/capture.txt	2009-06-23 12:05:48 UTC (rev 101248)
+++ manuel/trunk/src/manuel/capture.txt	2009-06-23 13:16:12 UTC (rev 101249)
@@ -1,70 +0,0 @@
-.. _capture:
-
-Capturing Blocks
-================
-
-When writing documentation the need often arrises to describe the contents of
-files or other non-python information.  You may also want to put that
-information under test.  :mod:`manuel.capture` helps with that.
-
-If you were writing the problems for a programming contest, you might want to
-describe the input and output files for each challenge.
-
-You would then show the contestant the expected output of their program.  But
-you want to be sure that your examples are correct.
-
-To do that you might write your document like this:
-
-::
-
-    Given this example input file::
-
-        6
-        1
-        8
-        20
-        11
-        65
-        2
-
-    .. -> input
-
-    Your program should generare this output file::
-
-        1
-        2
-        6
-        8
-        11
-        20
-        65
-
-    .. -> expected
-
-        >>> correct = '\n'.join(
-        ...     map(str, sorted(map(int, input.splitlines())))) + '\n'
-        >>> expected == correct
-        True
-
-.. -> source
-
-    >>> import manuel
-    >>> document = manuel.Document(source)
-    >>> import manuel.capture
-    >>> m = manuel.capture.Manuel()
-    >>> import manuel.doctest
-    >>> m += manuel.doctest.Manuel()
-    >>> document.process_with(m, globs={})
-    >>> print document.formatted(),
-
-This uses the syntax implemented in :mod:`manuel.collect` to capture a block of
-text into a varible (the one named after "->").
-
-Whenever a line of the structure ".. -> VAR" is detected, the text of the
-*previous* block will be stored in the given variable.
-
-.. the paragraph below could be phrased better
-
-Of course, lines that start with ".. " are reST comments, so when the document
-is rendered with docutils or Sphinx, the tests will dissapear and only the
-intended document contents will remain.

Modified: manuel/trunk/src/manuel/codeblock.py
===================================================================
--- manuel/trunk/src/manuel/codeblock.py	2009-06-23 12:05:48 UTC (rev 101248)
+++ manuel/trunk/src/manuel/codeblock.py	2009-06-23 13:16:12 UTC (rev 101249)
@@ -2,7 +2,7 @@
 import manuel
 import textwrap
 
-CODEBLOCK_START = re.compile(r'^\.\.\s*(invisible-)?code-block::\s*python\b', re.MULTILINE)
+CODEBLOCK_START = re.compile(r'^\.\.\s*(invisible-)?code-block::?\s*python\b', re.MULTILINE)
 CODEBLOCK_END = re.compile(r'(\n\Z|\n(?=\S))')
 
 

Deleted: manuel/trunk/src/manuel/codeblock.txt
===================================================================
--- manuel/trunk/src/manuel/codeblock.txt	2009-06-23 12:05:48 UTC (rev 101248)
+++ manuel/trunk/src/manuel/codeblock.txt	2009-06-23 13:16:12 UTC (rev 101249)
@@ -1,123 +0,0 @@
-.. _code-blocks:
-
-Code Blocks
-===========
-
-`Sphinx <http://sphinx.pocoo.org/>`_ and other docutils `extensions
-<http://docutils.sourceforge.net/sandbox/code-block-directive/docs/syntax-highlight.html>`_
-provide a `"code-block" directive <http://sphinx.pocoo.org/markup/code.html>`_,
-which allows inlined snippets of code in `reST
-<http://docutils.sourceforge.net/rst.html>`_ documents.
-
-For example a block of Python would be prefixed with ".. code-block:: python"::
-
-    .. code-block:: python
-
-        print 'hello'
-
-The :mod:`manuel.codeblock` module provides the ability to execute the contents
-of Python code-blocks.
-
-.. code-block:: python
-
-    import manuel.codeblock
-
-.. Let's create a reST document with a code block.
-
-    >>> document = manuel.Document("""
-    ... Here is a code-block:
-    ...
-    ... .. code-block:: python
-    ...
-    ...     x = 'hello'
-    ...
-    ... A little prose to separate the examples.
-    ...
-    ...     >>> print x
-    ...     hello
-    ...
-    ... """)
-
-.. Since the above document mixes code-blocks and doctests, we'll mix in the
-   doctest handler.
-
-    >>> import manuel.doctest
-    >>> m = manuel.codeblock.Manuel()
-    >>> m += manuel.doctest.Manuel()
-    >>> document.process_with(m, globs={})
-
-    Both code blocks were found (for a total of five regions -- text, block,
-    text, block, and text):
-
-    >>> len(list(document))
-    5
-
-    We can see that none of the tests in the document failed:
-
-    >>> print document.formatted(),
-
-If the code-block generates some sort of error...
-
-.. code-block:: python
-
-    .. code-block:: python
-
-        print does_not_exist
-
-.. -> source
-
-    >>> document = manuel.Document(source, location='fake.txt')
-
-.. the document above was specially formulated to have nothing before or after
-   the code-block
-
-    >>> document.source.startswith('.. code-block')
-    True
-    >>> document.source.endswith('print does_not_exist\n')
-    True
-
-...that error will be reported:
-
-    >>> document.process_with(m, globs={})
-    Traceback (most recent call last):
-        ...
-    NameError: name 'does_not_exist' is not defined
-
-If you find that you want to include a code-block in a document but don't want
-Manuel to execute it, use :ref:`manuel.ignore <ignore>` to ignore that
-particular block.
-
-
-Invisible Code Blocks
----------------------
-
-At times you'll want to have a block of code that is executed but not displayed
-in the rendered document (like some setup for later examples).
-
-When using doctest's native format (">>>") that's easy to do, you just put the
-code in a reST comment, like so:
-
-::
-
-    .. this is some setup, it is hidden in a reST comment
-
-        >>> a = 5
-        >>> b = a + 3
-
-However, if you want to include a relatively large chunk of Python, you'd
-rather use a code-block, but that means that it will be included in the
-rendered document.  Instead, :mod:`manuel.codeblock` also understands a variant
-of the code-block directive (".. code-block:: python") that is actually a reST
-comment: ".. invisible-code-block:: python" (note the single colon)::
-
-    .. invisible-code-block:: python
-
-        a = 5
-        b = a + 3
-
-.. -> source
-
-    >>> import manuel
-    >>> document = manuel.Document(source)
-    >>> document.process_with(m, globs={})
-    >>> print document.formatted()

Deleted: manuel/trunk/src/manuel/doctest.txt
===================================================================
--- manuel/trunk/src/manuel/doctest.txt	2009-06-23 12:05:48 UTC (rev 101248)
+++ manuel/trunk/src/manuel/doctest.txt	2009-06-23 13:16:12 UTC (rev 101249)
@@ -1,48 +0,0 @@
-.. _doctest:
-
-Doctests
-========
-
-Manuel is all about making testable documents and well-documented tests.  Of
-course, Python's doctest module is a long-standing fixture in that space, so it
-only makes sense for Manuel to support doctest syntax.
-
-Handling doctests is easy:
-
-.. code-block:: python
-
-    import manuel.doctest
-
-    m = manuel.doctest.Manuel()
-    suite = manuel.testing.TestSuite(m, 'my-doctest.txt')
-
-Of course you can mix in other Manuel syntax plug-ins as well (including ones
-you write yourself).
-
-.. code-block:: python
-
-    import manuel.doctest
-    import manuel.codeblock
-
-    m = manuel.doctest.Manuel()
-    m += manuel.codeblock.Manuel()
-    suite = manuel.testing.TestSuite(m, 'my-doctest-with-code-blocks.txt')
-
-The :class:`manuel.doctest.Manuel` constructor also takes :data:`optionflags`
-and :data:`checker` arguments.
-
-.. code-block:: python
-
-    m = manuel.doctest.Manuel(optionflags=optionflags, checker=checker)
-
-See the `doctest documentation <http://docs.python.org/library/doctest.html>`_
-for more information about the `available options
-<http://docs.python.org/library/doctest.html#doctest-options>`_  and `output
-checkers <http://docs.python.org/library/doctest.html#outputchecker-objects>`_
-
-
-.. note:: :mod:`zope.testing.renormalizing` provides an :class:`OutputChecker`
-   for smoothing out differences between actual and expected output for things
-   that are hard to control (like memory addresses and time).  See the
-   `module's doctests <http://svn.zope.org/zope.testing/trunk/src/zope/testing/renormalizing.py?view=markup>`_
-   for more information on how it works.

Deleted: manuel/trunk/src/manuel/footnote.txt
===================================================================
--- manuel/trunk/src/manuel/footnote.txt	2009-06-23 12:05:48 UTC (rev 101248)
+++ manuel/trunk/src/manuel/footnote.txt	2009-06-23 13:16:12 UTC (rev 101249)
@@ -1,103 +0,0 @@
-.. _footnotes:
-
-=========
-Footnotes
-=========
-
-The :mod:`manuel.footnote` module provides an implementation of reST footnote
-handling, but instead of just plain text, the footnotes can contain any syntax
-Manuel can interpret including doctests.
-
-    >>> import manuel.footnote
-    >>> m = manuel.footnote.Manuel()
-
-Here's an example of combining footnotes with doctests:
-
-.. so we also need the doctest Manuel plug-in
-
-    >>> import manuel.doctest
-    >>> m += manuel.doctest.Manuel()
-
-::
-
-    Here we reference a footnote. [1]_
-
-        >>> x
-        42
-
-    Here we reference another. [2]_
-
-        >>> x
-        100
-
-    .. [1] This is a test footnote definition.
-
-        >>> x = 42
-
-    .. [2] This is another test footnote definition.
-
-        >>> x = 100
-
-    .. [3] This is a footnote that will never be executed.
-
-        >>> raise RuntimeError('nooooo!')
-
-.. -> source
-
-    >>> import manuel
-    >>> document = manuel.Document(source)
-    >>> document.process_with(m, globs={})
-    >>> print document.formatted(),
-
-.. The order of examples in footnotes is preserved.  If not, the document below
-   would generate an error because "a" won't be defined when "b = a + 1" is
-   evaluated.
-
-    >>> document = manuel.Document("""
-    ... Here we want some imports to be done. [foo]_
-    ...
-    ...     >>> a + b
-    ...     3
-    ...
-    ... A little prose to separate the examples.
-    ...
-    ... .. [foo] Do something
-    ...
-    ...     >>> a = 1
-    ...
-    ...     >>> b = a + 1
-    ...
-    ... """)
-    >>> document.process_with(m, globs={})
-    >>> print document.formatted()
-
-It is possible to reference more than one footnote on a single line.
-
-::
-
-    This line has several footnotes on it. [1]_ [2]_ [3]_
-
-        >>> z
-        105
-
-    A little prose to separate the examples.
-
-    .. [1] Do something
-
-        >>> w = 3
-
-    .. [2] Do something
-
-        >>> x = 5
-
-    .. [3] Do something
-
-        >>> y = 7
-
-        >>> z = w * x * y
-
-.. -> source2
-
-    >>> document = manuel.Document(source)
-    >>> document.process_with(m, globs={})
-    >>> print document.formatted()

Deleted: manuel/trunk/src/manuel/ignore.txt
===================================================================
--- manuel/trunk/src/manuel/ignore.txt	2009-06-23 12:05:48 UTC (rev 101248)
+++ manuel/trunk/src/manuel/ignore.txt	2009-06-23 13:16:12 UTC (rev 101249)
@@ -1,104 +0,0 @@
-.. _ignore:
-
-Ignoring Blocks
-===============
-
-Occasionally the need arrises to ignore a block of markup that would otherwise
-be parsed by a Manuel plug-in.
-
-For example, this document has a code-block will generate a Syntax error:
-
-    >>> import manuel
-    >>> document = manuel.Document("""
-    ... The following is invalid Python.
-    ...
-    ... .. code-block:: python
-    ...
-    ...     def foo:
-    ...         pass
-    ...
-    ... """)
-
-We can see that when executed, the SyntaxError escapes.
-
-    >>> import manuel.codeblock
-    >>> m = manuel.codeblock.Manuel()
-    >>> document.process_with(m, globs={})
-    Traceback (most recent call last):
-      ...
-      File "<memory>:4", line 2
-         def foo:
-                ^
-    SyntaxError: invalid syntax
-
-The :mod:`manuel.ignore` module provides a way to ignore parts of a document
-using a directive ".. ignore-next-block".
-
-Because Manuel plug-ins are executed in the order they are accumulated, we want
-:mod:`manuel.ignore` to be the base Manuel object, with any others added to it.
-
-.. code-block:: python
-
-    import manuel.ignore
-    import manuel.doctest
-    m = manuel.ignore.Manuel()
-    m += manuel.codeblock.Manuel()
-    m += manuel.doctest.Manuel()
-
-If we add an ignore marker to the block we don't want processed...
-
-.. code-block:: python
-
-    >>> document = manuel.Document("""
-    ... The following is invalid Python.
-    ... 
-    ... .. ignore-next-block
-    ... .. code-block:: python
-    ... 
-    ...     def foo:
-    ...         pass
-    ... """)
-
-...the error goes away.
-
-    >>> document.process_with(m, globs={})
-    >>> print document.formatted(),
-
-
-Ignoring Literal Blocks
------------------------
-
-Ignoring literal blocks is a little more involved:
-
-    >>> document = manuel.Document("""
-    ... Here is some invalid Python:
-    ... 
-    ... .. ignore-next-block
-    ... 
-    ... ::
-    ... 
-    ...    >>> lambda: print 'hi'
-    ... """)
-
-.. no need for this bit to be visible in the docs
-
-    >>> document.process_with(m, globs={})
-    >>> print document.formatted(),
-
-.. we want to be very sure that the above example without the ignore actually
-   generates an error:
-
-    >>> document = manuel.Document(document.source.replace(
-    ...     '.. ignore-next-block', ''))
-    >>> document.process_with(m, globs={})
-    >>> print document.formatted(),
-    File "<memory>", line 8, in <memory>
-    Failed example:
-        lambda: print 'hi'
-    Exception raised:
-          ...
-          File "<doctest <memory>[0]>", line 1
-             lambda: print 'hi'
-                         ^
-         SyntaxError: invalid syntax
-

Deleted: manuel/trunk/src/manuel/isolation.txt
===================================================================
--- manuel/trunk/src/manuel/isolation.txt	2009-06-23 12:05:48 UTC (rev 101248)
+++ manuel/trunk/src/manuel/isolation.txt	2009-06-23 13:16:12 UTC (rev 101249)
@@ -1,102 +0,0 @@
-.. _isolation:
-
-Test Isolation
-==============
-
-One of the advantages of unittest over doctest is that the individual tests are
-isolated from one-another.
-
-In large doctests the later tests often depend on incedental details of earlier
-tests, making the tests more brittle and harder to change.
-
-Test isolation is one approach to reducing this intra-doctest coupling.  The
-:mod:`manuel.isolation` module provides a plug-in to help.
-
-    >>> import manuel.isolation
-    >>> m = manuel.isolation.Manuel()
-
-The ".. reset-globs" directive resets the globals in the test.  Let's create a
-Manuel document to test isolation with:
-
-    >>> document = manuel.Document("""
-    ... We define a variable.
-    ...
-    ...     >>> x = 'hello'
-    ...
-    ... It is still defined.
-    ...
-    ...     >>> print x
-    ...     hello
-    ...     
-    ... Now we can reset the globals and it will be gone.
-    ...
-    ... .. reset-globs
-    ...
-    ...     >>> print x
-    ... """)
-
-Since the above document mixes isolation and doctests, we'll mix in the doctest
-handler.
-
-    >>> import manuel.doctest
-    >>> m += manuel.doctest.Manuel()
-
-We can see that after the globals have been reset, the "print x" line raises an
-error.
-
-    >>> document.process_with(m, globs={})
-    >>> print document.formatted(),
-    File "<memory>", line 2, in <memory>
-    Failed example:
-        print x
-    Exception raised:
-        ...
-        NameError: name 'x' is not defined
-
-Of course, resetting to an empty set of global variables isn't always what's
-wanted.  In that case there is a ".. capture-globs" directive that saves a
-baseline set of globals that will be restored at each reset.
-
-
-    >>> document = manuel.Document("""
-    ... We define a variable.
-    ...
-    ...     >>> x = 'hello'
-    ...
-    ... It is still defined.
-    ...
-    ...     >>> print x
-    ...     hello
-    ...
-    ... We can capture the currently defined globals:
-    ...
-    ... .. capture-globs
-    ...
-    ... Of course capturing the globals doesn't disturb them.
-    ...
-    ...     >>> print x
-    ...     hello
-    ... 
-    ... Now if we define a new global...
-    ...
-    ...     >>> y = 'goodbye'
-    ...     >>> print y
-    ...     goodbye
-    ...
-    ... .. reset-globs
-    ...
-    ... ...it will disappear after a reset.
-    ...
-    ...     >>> print y
-    ...     Traceback (most recent call last):
-    ...         ...
-    ...     NameError: name 'y' is not defined
-    ...     
-    ... But the captured globals will still be defined.
-    ...
-    ...     >>> print x
-    ...     hello
-    ...
-    ... """)
-    >>> document.process_with(m, globs={})
-    >>> print document.formatted(),

Modified: manuel/trunk/src/manuel/table-example.txt
===================================================================
--- manuel/trunk/src/manuel/table-example.txt	2009-06-23 12:05:48 UTC (rev 101248)
+++ manuel/trunk/src/manuel/table-example.txt	2009-06-23 13:16:12 UTC (rev 101249)
@@ -321,7 +321,7 @@
 .. this next bit is actually a reST comment, but it is run during tests anyway
     (note the single colon instead of double colon)
 
-.. invisible-code-block:: python
+.. invisible-code-block: python
 
     import unittest
     suite = manuel.testing.TestSuite(m, 'table-example.txt')

Modified: manuel/trunk/src/manuel/tests.py
===================================================================
--- manuel/trunk/src/manuel/tests.py	2009-06-23 12:05:48 UTC (rev 101248)
+++ manuel/trunk/src/manuel/tests.py	2009-06-23 13:16:12 UTC (rev 101249)
@@ -30,9 +30,7 @@
         (re.compile(r'<zope\.testing\.doctest\.'), '<doctest.'),
         ])
 
-    tests = ['README.txt', 'footnote.txt', 'bugs.txt', 'codeblock.txt',
-        'isolation.txt', 'table-example.txt', '../getting-started.txt',
-        'ignore.txt', 'capture.txt']
+    tests = ['../index.txt', 'table-example.txt', 'README.txt', 'bugs.txt']
 
     tests = map(get_abs_path, tests)
 



More information about the Checkins mailing list