[Checkins] SVN: manuel/trunk/src/manuel/ make the capture directive use the current indentation to determine how
Benji York
benji at zope.com
Sat Aug 15 17:43:59 EDT 2009
Log message for revision 102842:
make the capture directive use the current indentation to determine how
much to capture
Changed:
U manuel/trunk/src/manuel/README.txt
U manuel/trunk/src/manuel/capture.py
A manuel/trunk/src/manuel/capture.txt
U manuel/trunk/src/manuel/tests.py
-=-
Modified: manuel/trunk/src/manuel/README.txt
===================================================================
--- manuel/trunk/src/manuel/README.txt 2009-08-15 20:43:56 UTC (rev 102841)
+++ manuel/trunk/src/manuel/README.txt 2009-08-15 21:43:58 UTC (rev 102842)
@@ -179,15 +179,15 @@
result = region.evaluated
if not result.passed:
region.formatted = (
- "the numbers aren't in sorted order: "
- + ', '.join(map(str, result.test.numbers)))
+ "the numbers aren't in sorted order: %s\n"
+ % ', '.join(map(str, result.test.numbers)))
Since one of the test cases failed we get an appropriate message out of the
formatter.
>>> format(document)
>>> [region.formatted for region in document]
- [None, None, None, "the numbers aren't in sorted order: 3, 5, 1"]
+ [None, None, None, "the numbers aren't in sorted order: 3, 5, 1\n"]
Manuel Objects
@@ -301,14 +301,15 @@
create a single document that has both.
>>> document = manuel.Document("""
- ... We can test Python...
+ ... We can have a list of numbers...
...
+ ... a very nice list: 3, 6, 2
+ ...
+ ... ... and we can test Python.
+ ...
... >>> 1 + 1
... 42
...
- ... ...and lists of numbers.
- ...
- ... a very nice list: 3, 6, 2
... """)
Obviously both of those tests will fail, but first we have to configure Manuel
@@ -332,10 +333,11 @@
>>> for region in document:
... print (region.lineno, region.parsed or region.source)
- (1, '\nWe can test Python...\n\n')
- (4, <doctest.Example instance at 0x...>)
- (6, '\n...and lists of numbers.\n\n')
- (9, <NumbersTest object at 0x...>)
+ (1, '\nWe can have a list of numbers...\n\n')
+ (4, <NumbersTest object at 0x...>)
+ (5, '\n... and we can test Python.\n\n')
+ (8, <doctest.Example instance at 0x...>)
+ (10, '\n')
We can look at the formatted output to see that each of the two tests failed.
@@ -344,15 +346,15 @@
... print '-'*70
... print region.formatted,
----------------------------------------------------------------------
- File "<memory>", line 4, in <memory>
+ the numbers aren't in sorted order: 3, 6, 2
+ ----------------------------------------------------------------------
+ File "<memory>", line 8, in <memory>
Failed example:
1 + 1
Expected:
42
Got:
2
- ----------------------------------------------------------------------
- the numbers aren't in sorted order: 3, 6, 2
Priorities
Modified: manuel/trunk/src/manuel/capture.py
===================================================================
--- manuel/trunk/src/manuel/capture.py 2009-08-15 20:43:56 UTC (rev 102841)
+++ manuel/trunk/src/manuel/capture.py 2009-08-15 21:43:58 UTC (rev 102842)
@@ -3,7 +3,9 @@
import string
import textwrap
-CAPTURE_DIRECTIVE = re.compile(r'^\.\.\s*->\s*(?P<name>\S+).*$', re.MULTILINE)
+CAPTURE_DIRECTIVE = re.compile(
+ r'^(?P<indent>(\t| )*)\.\.\s*->\s*(?P<name>\S+).*$',
+ re.MULTILINE)
class Capture(object):
@@ -11,15 +13,42 @@
self.name = name
self.block = block
+def normalize_whitespace(s):
+ return s.replace('\t', ' '*8) # turn tabs into spaces
+
@manuel.timing(manuel.EARLY)
def find_captures(document):
- for region in document.find_regions(CAPTURE_DIRECTIVE):
+ while True:
+ regions = document.find_regions(CAPTURE_DIRECTIVE)
+ if not regions:
+ break
+ region = regions[-1]
# note that start and end have different bases, "start" is the offset
# from the begining of the region, "end" is a document line number
- end = region.lineno-2
+ end = region.lineno - 2
- # not that we've extracted the information we need, lets slice up the
+ indent = region.start_match.group('indent')
+ indent = normalize_whitespace(indent)
+
+ def indent_matches(line):
+ """Is the indentation of a line match what we're looking for?"""
+ line = normalize_whitespace(line)
+
+ if not line.strip():
+ # the line consists entirely of whitespace (or nothing at all),
+ # so is not considered to be of the appropriate indentation
+ return False
+
+ if line.startswith(indent):
+ if line[len(indent)] not in string.whitespace:
+ return True
+
+ # if none of the above found the indentation to be a match, it is
+ # not a match
+ return False
+
+ # now that we've extracted the information we need, lets slice up the
# document's regions to match
for candidate in document:
@@ -32,13 +61,13 @@
raise RuntimeError('both start and end lines must be in the '
'same region')
+ start = None
for offset, line in reversed(list(enumerate(lines))):
if offset > end - found_region.lineno:
continue
- if line and line[0] in string.whitespace:
- start = offset
- if line and line[0] not in string.whitespace:
+ if indent_matches(line):
break
+ start = offset + 1
else:
raise RuntimeError("couldn't find the start of the block")
Added: manuel/trunk/src/manuel/capture.txt
===================================================================
--- manuel/trunk/src/manuel/capture.txt (rev 0)
+++ manuel/trunk/src/manuel/capture.txt 2009-08-15 21:43:58 UTC (rev 102842)
@@ -0,0 +1,59 @@
+manuel.capture
+==============
+
+This document explores the edge cases and boundry conditions of the
+manuel.capture module. It is not meant as end-user documentation, but is
+rather a set of tests.
+
+
+Respecting indentation
+----------------------
+
+The text captured is determined by the indentation of the capture directive.
+
+::
+
+ First level of indentation.
+
+ Second level of indentation.
+
+ Third level of indentation.
+
+ .. -> foo
+
+.. -> source
+
+ >>> import manuel
+ >>> document = manuel.Document(source)
+ >>> import manuel.capture
+ >>> manuel.capture.find_captures(document)
+ >>> [r.parsed.block for r in document if r.parsed]
+ ['Third level of indentation.\n']
+
+
+Nested directives
+-----------------
+
+If two capture directives are nested, the outer one is effective.
+
+::
+
+ First level of indentation.
+
+ Second level of indentation.
+
+ Third level of indentation.
+
+ .. -> foo
+
+ .. -> bar
+
+.. -> source
+
+ >>> import manuel
+ >>> document = manuel.Document(source)
+ >>> import manuel.capture
+ >>> manuel.capture.find_captures(document)
+ >>> [r.parsed.block for r in document if r.parsed]
+ ['Second level of indentation.\n\n Third level of indentation.\n\n.. -> foo\n']
+
Property changes on: manuel/trunk/src/manuel/capture.txt
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: manuel/trunk/src/manuel/tests.py
===================================================================
--- manuel/trunk/src/manuel/tests.py 2009-08-15 20:43:56 UTC (rev 102841)
+++ manuel/trunk/src/manuel/tests.py 2009-08-15 21:43:58 UTC (rev 102842)
@@ -31,7 +31,8 @@
(re.compile(r'<zope\.testing\.doctest\.'), '<doctest.'),
])
- tests = ['../index.txt', 'table-example.txt', 'README.txt', 'bugs.txt']
+ tests = ['../index.txt', 'table-example.txt', 'README.txt', 'bugs.txt',
+ 'capture.txt']
m = manuel.ignore.Manuel()
m += manuel.doctest.Manuel(optionflags=optionflags, checker=checker)
More information about the Checkins
mailing list