docstring-checkins Mailing List for Docstring Processing System (Page 11)
Status: Pre-Alpha
Brought to you by:
goodger
You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(53) |
Sep
(54) |
Oct
(26) |
Nov
(27) |
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(60) |
Feb
(85) |
Mar
(94) |
Apr
(40) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: David G. <go...@us...> - 2002-01-26 00:08:42
|
Update of /cvsroot/docstring/dps/test/test_transforms In directory usw-pr-cvs1:/tmp/cvs-serv6821/dps/test/test_transforms Added Files: test_hyperlinks.py Log Message: tests for hyperlink transforms --- NEW FILE: test_hyperlinks.py --- #! /usr/bin/env python """ :Author: David Goodger :Contact: go...@us... :Revision: $Revision: 1.1 $ :Date: $Date: 2002/01/26 00:08:39 $ :Copyright: This module has been placed in the public domain. Tests for dps.transforms.references.Hyperlinks. """ import DPSTestSupport from dps.transforms.references import Hyperlinks import UnitTestFolder try: from restructuredtext import Parser except ImportError: from dps.parsers.restructuredtext import Parser def suite(): parser = Parser(warninglevel=4, errorlevel=4, languagecode='en', debug=UnitTestFolder.debug) s = DPSTestSupport.TransformTestSuite(parser) s.generateTests(totest) return s totest = {} # Exhaustive listing of hyperlink variations: every combination of # target/reference, direct/indirect, internal/external, and named/anonymous. totest['enumerated_hyperlinks'] = ((Hyperlinks,), [ ["""\ direct_ external .. _direct: http://direct """, """\ <document> <paragraph> <reference refuri="http://direct"> direct external <target name="direct" refuri="http://direct"> """], ["""\ indirect_ external .. _indirect: xtarget_ .. _xtarget: http://indirect """, """\ <document> <paragraph> <reference refuri="http://indirect"> indirect external <target name="indirect" refuri="http://indirect"> <target name="xtarget" refuri="http://indirect"> """], ["""\ .. _direct: direct_ internal """, """\ <document> <target name="direct"> <paragraph> <reference refname="direct"> direct internal """], ["""\ .. _ztarget: indirect_ internal .. _indirect2: ztarget_ .. _indirect: indirect2_ """, """\ <document> <target name="ztarget"> <paragraph> <reference refname="ztarget"> indirect internal <target name="indirect2" refname="ztarget"> <target name="indirect" refname="ztarget"> """], ["""\ `direct external`__ __ http://direct """, """\ <document> <paragraph> <reference refuri="http://direct"> direct external <target name="_:1:_" refuri="http://direct"> """], ["""\ `indirect external`__ __ xtarget_ .. _xtarget: http://indirect """, """\ <document> <paragraph> <reference refuri="http://indirect"> indirect external <target name="_:1:_" refuri="http://indirect"> <target name="xtarget" refuri="http://indirect"> """], ["""\ __ `direct internal`__ """, """\ <document> <target name="_:1:_"> <paragraph> <reference refname="_:1:_"> direct internal """], ["""\ .. _ztarget: `indirect internal`__ __ ztarget_ """, """\ <document> <target name="ztarget"> <paragraph> <reference refname="ztarget"> indirect internal <target name="_:1:_" refname="ztarget"> """], ]) totest['hyperlinks'] = ((Hyperlinks,), [ ["""\ .. _internal hyperlink: This paragraph referenced. By this `internal hyperlink`_ referemce. """, """\ <document> <target name="internal hyperlink"> <paragraph> This paragraph referenced. <paragraph> By this \n\ <reference refname="internal hyperlink"> internal hyperlink referemce. """], ["""\ .. _chained: .. _internal hyperlink: This paragraph referenced. By this `internal hyperlink`_ referemce as well as by this chained_ reference. The results of the transform are not visible at the XML level. """, """\ <document> <target name="chained"> <target name="internal hyperlink"> <paragraph> This paragraph referenced. <paragraph> By this \n\ <reference refname="internal hyperlink"> internal hyperlink referemce as well as by this \n\ <reference refname="chained"> chained reference. <paragraph> The results of the transform are not visible at the XML level. """], ["""\ .. _external hyperlink: http://uri `External hyperlink`_ reference. """, """\ <document> <target name="external hyperlink" refuri="http://uri"> <paragraph> <reference refuri="http://uri"> External hyperlink reference. """], ["""\ .. _external hyperlink: http://uri .. _indirect target: `external hyperlink`_ """, """\ <document> <target name="external hyperlink" refuri="http://uri"> <target name="indirect target" refuri="http://uri"> <system_warning level="0"> <paragraph> External hyperlink target "indirect target" is not referenced. """], ["""\ .. _chained: .. _external hyperlink: http://uri `External hyperlink`_ reference and a chained_ reference too. """, """\ <document> <target name="chained" refuri="http://uri"> <target name="external hyperlink" refuri="http://uri"> <paragraph> <reference refuri="http://uri"> External hyperlink reference and a \n\ <reference refuri="http://uri"> chained reference too. """], ["""\ .. _external hyperlink: http://uri .. _indirect hyperlink: `external hyperlink`_ `Indirect hyperlink`_ reference. """, """\ <document> <target name="external hyperlink" refuri="http://uri"> <target name="indirect hyperlink" refuri="http://uri"> <paragraph> <reference refuri="http://uri"> Indirect hyperlink reference. """], ["""\ .. _external hyperlink: http://uri .. _chained: .. _indirect hyperlink: `external hyperlink`_ Chained_ `indirect hyperlink`_ reference. """, """\ <document> <target name="external hyperlink" refuri="http://uri"> <target name="chained" refuri="http://uri"> <target name="indirect hyperlink" refuri="http://uri"> <paragraph> <reference refuri="http://uri"> Chained \n\ <reference refuri="http://uri"> indirect hyperlink reference. """], ["""\ .. __: http://full __ __ http://simplified .. _external: http://indirect.external __ external_ __ `Full syntax anonymous external hyperlink reference`__, `chained anonymous external reference`__, `simplified syntax anonymous external hyperlink reference`__, `indirect anonymous hyperlink reference`__, `internal anonymous hyperlink reference`__. """, """\ <document> <target name="_:1:_" refuri="http://full"> <target name="_:2:_" refuri="http://simplified"> <target name="_:3:_" refuri="http://simplified"> <target name="external" refuri="http://indirect.external"> <target name="_:4:_" refuri="http://indirect.external"> <target name="_:5:_"> <paragraph> <reference refuri="http://full"> Full syntax anonymous external hyperlink reference , <reference refuri="http://simplified"> chained anonymous external reference , <reference refuri="http://simplified"> simplified syntax anonymous external hyperlink reference , <reference refuri="http://indirect.external"> indirect anonymous hyperlink reference , <reference refname="_:5:_"> internal anonymous hyperlink reference . """], ["""\ Duplicate external target_'s (different URIs): .. _target: first .. _target: second """, """\ <document> <paragraph> Duplicate external \n\ <reference refname="target"> target 's (different URIs): <target dupname="target" refuri="first"> <system_warning level="1"> <paragraph> Duplicate explicit target name: "target" <target dupname="target" refuri="second"> """], ]) if __name__ == '__main__': import unittest unittest.main(defaultTest='suite') |
From: David G. <go...@us...> - 2002-01-26 00:07:55
|
Update of /cvsroot/docstring/dps/test/test_transforms In directory usw-pr-cvs1:/tmp/cvs-serv6590/dps/test/test_transforms Modified Files: test_docinfo.py Log Message: updated Index: test_docinfo.py =================================================================== RCS file: /cvsroot/docstring/dps/test/test_transforms/test_docinfo.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_docinfo.py 2002/01/16 02:41:06 1.1 --- test_docinfo.py 2002/01/26 00:07:53 1.2 *************** *** 37,41 **** It is automatically moved to the end of the other bibliographic elements. ! :Author: Me :Version: 1 --- 37,41 ---- It is automatically moved to the end of the other bibliographic elements. ! :Author: Me :Version: 1 *************** *** 130,134 **** <docinfo> <status> ! a <emphasis> simple --- 130,134 ---- <docinfo> <status> ! a \n\ <emphasis> simple *************** *** 309,313 **** <docinfo> <status> ! test_field_lists.py <date> %s --- 309,313 ---- <docinfo> <status> ! test_docinfo.py <date> %s |
From: David G. <go...@us...> - 2002-01-26 00:07:38
|
Update of /cvsroot/docstring/dps/test In directory usw-pr-cvs1:/tmp/cvs-serv6542/dps/test Modified Files: test_statemachine.py Log Message: updated Index: test_statemachine.py =================================================================== RCS file: /cvsroot/docstring/dps/test/test_statemachine.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_statemachine.py 2001/11/23 03:19:43 1.2 --- test_statemachine.py 2002/01/26 00:07:36 1.3 *************** *** 287,291 **** def test_extractindented(self): block = statemachine.string2lines(self.indented_string) ! self.assertEquals(statemachine.extractindented(block), ([s[6:] for s in block], 6, 1)) self.assertEquals(statemachine.extractindented(self.s2l_expected), --- 287,291 ---- def test_extractindented(self): block = statemachine.string2lines(self.indented_string) ! self.assertEquals(statemachine.extractindented(block), ([s[6:] for s in block], 6, 1)) self.assertEquals(statemachine.extractindented(self.s2l_expected), |
From: David G. <go...@us...> - 2002-01-26 00:07:32
|
Update of /cvsroot/docstring/dps/test In directory usw-pr-cvs1:/tmp/cvs-serv6520/dps/test Modified Files: test_nodes.py Log Message: updated Index: test_nodes.py =================================================================== RCS file: /cvsroot/docstring/dps/test/test_nodes.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_nodes.py 2001/11/13 03:08:07 1.2 --- test_nodes.py 2002/01/26 00:07:30 1.3 *************** *** 59,63 **** def test_withtext(self): element = nodes.Element('text\nmore', nodes.Text('text\nmore')) ! self.assertEquals(repr(element), r"<Element: <#text...>>") self.assertEquals(str(element), '<Element>text\nmore</Element>') dom = element.asdom() --- 59,63 ---- def test_withtext(self): element = nodes.Element('text\nmore', nodes.Text('text\nmore')) ! self.assertEquals(repr(element), r"<Element: <#text: 'text\nmore'>>") self.assertEquals(str(element), '<Element>text\nmore</Element>') dom = element.asdom() *************** *** 65,69 **** dom.unlink() element['attr'] = '1' ! self.assertEquals(repr(element), r"<Element: <#text...>>") self.assertEquals(str(element), '<Element attr="1">text\nmore</Element>') --- 65,69 ---- dom.unlink() element['attr'] = '1' ! self.assertEquals(repr(element), r"<Element: <#text: 'text\nmore'>>") self.assertEquals(str(element), '<Element attr="1">text\nmore</Element>') |
From: David G. <go...@us...> - 2002-01-26 00:06:58
|
Update of /cvsroot/docstring/dps/test In directory usw-pr-cvs1:/tmp/cvs-serv6389/dps/test Modified Files: alltests.py Log Message: whitespace Index: alltests.py =================================================================== RCS file: /cvsroot/docstring/dps/test/alltests.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** alltests.py 2001/09/17 04:02:26 1.1 --- alltests.py 2002/01/26 00:06:55 1.2 *************** *** 18,26 **** """Write to a file and a stream (default: stdout) simultaneously.""" ! def __init__(self, filename, stream=sys.__stdout__): self.file = open(filename, 'w') self.stream = stream ! def write(self, string): self.stream.write(string) --- 18,26 ---- """Write to a file and a stream (default: stdout) simultaneously.""" ! def __init__(self, filename, stream=sys.__stdout__): self.file = open(filename, 'w') self.stream = stream ! def write(self, string): self.stream.write(string) |
From: David G. <go...@us...> - 2002-01-26 00:04:52
|
Update of /cvsroot/docstring/dps/test In directory usw-pr-cvs1:/tmp/cvs-serv5934/dps/test Modified Files: DPSTestSupport.py Log Message: parameterized test method Index: DPSTestSupport.py =================================================================== RCS file: /cvsroot/docstring/dps/test/DPSTestSupport.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** DPSTestSupport.py 2002/01/16 02:42:06 1.2 --- DPSTestSupport.py 2002/01/26 00:04:50 1.3 *************** *** 1,5 **** #! /usr/bin/env python """ ! :Author: David Goodger :Contact: go...@us... :Revision: $Revision$ --- 1,5 ---- #! /usr/bin/env python """ ! :Authors: David Goodger; Garth Kidd :Contact: go...@us... :Revision: $Revision$ *************** *** 77,81 **** else: self.id = id - def addTestCase(self, testCaseClass, methodName, input, expected, --- 77,80 ---- *************** *** 88,93 **** Arguments: ! testCaseClass -- ! methodName -- input -- input to the parser. expected -- expected output from the parser. --- 87,92 ---- Arguments: ! testCaseClass -- ! methodName -- input -- input to the parser. expected -- expected output from the parser. *************** *** 171,176 **** CustomTestSuite.__init__(self) ! ! def generateTests(self, dict, dictname='totest'): """ Stock the suite with test cases generated from a test data dictionary. --- 170,176 ---- CustomTestSuite.__init__(self) ! ! def generateTests(self, dict, dictname='totest', ! testmethod='test_transforms'): """ Stock the suite with test cases generated from a test data dictionary. *************** *** 193,197 **** continue self.addTestCase( ! TransformTestCase, 'test_transforms', transforms=transforms, parser=self.parser, input=case[0], expected=case[1], --- 193,197 ---- continue self.addTestCase( ! TransformTestCase, testmethod, transforms=transforms, parser=self.parser, input=case[0], expected=case[1], *************** *** 216,220 **** self.parser = kwargs['parser'] """Input parser for this test case.""" ! del kwargs['transforms'], kwargs['parser'] # only wanted here CustomTestCase.__init__(self, *args, **kwargs) --- 216,220 ---- self.parser = kwargs['parser'] """Input parser for this test case.""" ! del kwargs['transforms'], kwargs['parser'] # only wanted here CustomTestCase.__init__(self, *args, **kwargs) *************** *** 227,229 **** --- 227,245 ---- transformClass().transform(doctree) output = doctree.pformat() + self.compareOutput(self.input, output, self.expected) + + def test_transforms_verbosely(self): + if self.runInDebugger: + pdb.set_trace() + print '\n', self.id + print '-' * 70 + print self.input + doctree = self.parser.parse(self.input) + print '-' * 70 + print doctree.pformat() + for transformClass in self.transforms: + transformClass().transform(doctree) + output = doctree.pformat() + print '-' * 70 + print output self.compareOutput(self.input, output, self.expected) |
From: David G. <go...@us...> - 2002-01-26 00:03:18
|
Update of /cvsroot/docstring/dps/spec In directory usw-pr-cvs1:/tmp/cvs-serv5657/dps/spec Modified Files: gpdi.dtd Log Message: comments Index: gpdi.dtd =================================================================== RCS file: /cvsroot/docstring/dps/spec/gpdi.dtd,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** gpdi.dtd 2001/11/19 04:04:46 1.27 --- gpdi.dtd 2002/01/26 00:03:16 1.28 *************** *** 55,67 **** %additional.basic.atts; "> ! <!-- Reference to an external URI/URL. --> <!ENTITY % refuri.att " refuri CDATA #IMPLIED "> ! <!-- Reference to the `id` attribute of another element. --> <!ENTITY % refid.att " refid IDREF #IMPLIED "> ! <!-- Reference to the `name` attribute of another element. --> <!ENTITY % refname.att " refname CDATA #IMPLIED "> --- 55,71 ---- %additional.basic.atts; "> ! <!-- External reference to a URI/URL. --> <!ENTITY % refuri.att " refuri CDATA #IMPLIED "> ! <!-- Internal reference to the `id` attribute of an element. --> <!ENTITY % refid.att " refid IDREF #IMPLIED "> ! <!-- ! Internal reference to the `name` attribute of an element. On a ! 'target' element, 'refname' indicates an indirect target which may ! resolve to either an internal or external reference. ! --> <!ENTITY % refname.att " refname CDATA #IMPLIED "> |
From: David G. <go...@us...> - 2002-01-26 00:02:19
|
Update of /cvsroot/docstring/dps/spec In directory usw-pr-cvs1:/tmp/cvs-serv5427/dps/spec Modified Files: dps-notes.txt Log Message: added coding conventions, transform notes Index: dps-notes.txt =================================================================== RCS file: /cvsroot/docstring/dps/spec/dps-notes.txt,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** dps-notes.txt 2002/01/16 02:43:21 1.18 --- dps-notes.txt 2002/01/26 00:02:16 1.19 *************** *** 47,54 **** Doc-SIG post 'Suggestions for reST "modes"' as a base. ! - Write modules for common transformations, such as: - Resolving auto-numbered footnotes & references. ! - Resolving internal cross-references and indirect hyperlinks. - Propagating URIs to chained hyperlink targets. --- 47,54 ---- Doc-SIG post 'Suggestions for reST "modes"' as a base. ! - Write modules for common transforms. See Transforms_ below. - Resolving auto-numbered footnotes & references. ! - Resolving internal, external, and indirect hyperlinks. - Propagating URIs to chained hyperlink targets. *************** *** 63,67 **** --- 63,289 ---- and putting it into nodes.py as docstrings? + - Refactor: + + - Apply the `coding conventions`_ as given below. + + + Coding Conventions + ================== + + This project shall follow the generic coding conventions as specified + in the `Style Guide for Python Code`__ and `Docstring Conventions`__ + PEPs, with the following clarifications: + + - 4 spaces per indentation level. No tabs. + - No one-liner compound statements (i.e., no ``if x: return``: use two + lines & indentation), except for degenerate class or method + definitions (i.e., ``class X: pass`` is O.K.). + - Lines should be no more than 78 or 79 characters long. + - "CamelCase" shall be used for class names. + - Use "lowercase" or "lowercase_with_underscores" for function, + method, and variable names. For short names, maximum two joined + words, use lowercase (e.g. 'tagname'). For long names with three or + more joined words, or where it's hard to parse the split between two + words, use lowercase_with_underscores (e.g., 'note_explicit_target', + 'explicit_target'). + + __ http://www.python.org/peps/pep-0008.html + __ http://www.python.org/peps/pep-0257.html + + + Transforms + ========== + + Footnote Numbering + ------------------ + + [Tony] + This runs over a subtree (clearly for Python code, we don't want to + run it over anything bigger than a docstring, lest we confuse + footnotes!) and sorts out the numbering (in my development version of + pyspd (not on the web yet) this is actually done as part of the HTML + output phase, which is clearly the Wrong Place for it. + + David - a question or two on this. Each autonumbered footnote/footnote + reference has the attribute 'auto' set to "1". I want to *insert* + actual footnote numbers into the tree. I can just add a new attribute + 'auto-number' into elements as required, *or* I could ask that you set + 'auto' to be "-1" for the "no number yet" case, and use 'auto' to + store the *actual* number calculated. Which to do is a style issue, so + I'd prefer to leave it up to you (but using the same attribute would + make things a bit neater in the code - I'm not sure if it would + generate as elegant XML, though - I'd need to look up the detailed + attribute present/absent rules). + + [David] + Auto-numbered footnotes have attribute ``auto=1`` and no label. + Auto-numbered footnote_references have no reference text (they're + empty elements). If you resolve the numbering, just add a label + element to the beginning of the footnote, and reference text to the + footnote_reference. Take this input:: + + References to the first ([A]_), third ([#spam]_), and second + ([#]_) footnotes. + + .. [A] This footnote is labeled with "A". + .. [#] This footnote is auto-numbered. + .. [#spam] This footnote has autonumber name "spam". + + Parsed (watch for empty footnote_reference elements: indentation):: + + <document> + <paragraph> + References to the first ( + <footnote_reference refname="a"> + A + ), third ( + <footnote_reference auto="1" refname="spam"> + ), and second + ( + <footnote_reference auto="1"> + ) footnotes. + <footnote name="a"> + <label> + A + <paragraph> + This footnote is labeled with "A". + <footnote auto="1"> + <paragraph> + This footnote is auto-numbered. + <footnote auto="1" name="spam"> + <paragraph> + This footnote has autonumber name "spam". + + Only the first footnote_reference contains reference text. After + auto-numbering resolution, the tree should become:: + + <document> + <paragraph> + References to the first ( + <footnote_reference refname="a"> + A + ), third ( + <footnote_reference auto="1" refname="spam"> + 2 + ), and second + ( + <footnote_reference auto="1" refname="_footnote 1"> + 1 + ) footnotes. + <footnote name="a"> + <label> + A + <paragraph> + This footnote is labeled with "A". + <footnote auto="1" name="_footnote 1"> + <label> + 1 + <paragraph> + This footnote is auto-numbered. + <footnote auto="1" name="spam"> + <label> + 2 + <paragraph> + This footnote has autonumber name "spam". + + The labels and reference text are added to the two auto-numbered + footnotes & footnote_references. The unnamed auto-numbered footnote + & reference need name & refname attributes. Let's use "_footnote " + + footnote number for those attributes (a name-mangling unlikely to + occur in the real world; note that this hasn't been documented yet). + Of course (!), the implicitlinks and refnames instance attributes of + the dps.nodes.document instance must be updated. (It will soon be my + pleasure to document the dps/nodes.py data structure, since I'm + gradually forgetting its details.) + + After adding labels and reference text, the "auto" attributes can be + ignored. + + + [David] + > Let's use "_footnote " + footnote number for those attributes + > (a name-mangling unlikely to occur in the real world; note that + > this hasn't been documented yet). + + [Tony] + > Hmm - I wasn't assuming that unnamed autonumbered footnotes would have any + > name other than the number (since you're following the XML tradition and + > storing such things as strings anyway). + + [David] + I suppose we could go either way. I'm re-examining (for validity) what I + wrote in the spec: + + Automatic footnote numbering may not be mixed with manual footnote + numbering; it would cause numbering and referencing conflicts. + + Would such mixing inevitably cause conflicts? We could probably work around + potential conflicts with a decent algorithm. Should we? Requires thought. + Opinions? + + [Tony] + Well, I read that paragraph in the documentation, and decided that it + was in the category of "don't, in practice, care" so far as I was + concerned. This is the same category I put the forbidding of nested + inline markup - quite clearly one *can* do it, but equally clearly it's + a pain to implement, and not a terribly great gain, all things + considered. + + It's a category with the subtext "examine for correctness after we've + had some experience of people *using* reST in the wild". + Thus, given there are lots of other things to do, I would tend to leave + it as-is (especially if you are able to *warn* people about it if they + do it by mistake). + + To my mind, being able to do ``[#thing]_`` probably give people enough + precision over footnotes whils still allowing autonumbering - the *only* + potential problem is when referring to a footnote in a different + document (and that, again, is something I would leave fallow for the + moment, although we know I tend to want to use roles as annotation for + that sort of thing). + + + Footnote Gathering + ------------------ + + Collect and move footnotes to the end of a document. + + + Hyperlink Target Gathering + -------------------------- + + It probably comes in two phases, because in a Python context we need + to *resolve* them on a per-docstring basis, but if the user is trying + to do the callout form of presentation, they would then want to group + them all at the end of the document. + + + Substitutions + ------------- + + @@@ + + + Table of Contents + ----------------- + + @@@ + + This runs over the entire tree, and locates <section> elements. It + produces a <contents> subtree, which can be inserted at the + appropriate place, with links to the <section>s. It needs to make sure + that the links it uses are *real*, so ideally it will use the + "implicit" link for a section when it exists, and it will have to + invent one when the implicit link isn't there (presumably because the + section is the twelfth "Introduction" in the document...). + + + Index + ----- + + @@@ + + I/O APIs ======== *************** *** 182,185 **** --- 404,443 ---- the normal HTML parser for HTML output, but with extra support "around it" for the Python specific infrastructure. + + + nodes.py + ======== + + Add ``Nodes.walkabout()``, ``Visitor.walkabout()``, + ``Visitor.leave_*()``, and ``GenericVisitor.default_leave()`` methods + to catch elements on the way out? Here's ``Nodes.walkabout()``:: + + def walkabout(self, visitor, ancestry=()): + """ + Traverse a tree of `Node` objects. Call `visitor`'s + ``visit_...`` method (upon initial entry) **and** its + ``leave_...`` method (before exiting). + + Parameters: + + - `visitor`: A `Visitor` object, containing a ``visit_...`` + and ``leave_...`` method for each `Node` subclass + encountered. + - `ancestry`: A list of (parent, index) pairs. `self`'s parent + is the last entry. + """ + method = getattr(visitor, 'visit_' + self.__class__.__name__) + method(self, ancestry) + children = self.getchildren() + for i in range(len(children)): + children[i].walkabout(visitor, ancestry + ((self, i),)) + method = getattr(visitor, 'leave_' + self.__class__.__name__) + method(self, ancestry) + + Here's ``Visitor.walkabout()``:: + + def walkabout(self): + self.doctree.walkabout(self) + |
From: David G. <go...@us...> - 2002-01-26 00:00:53
|
Update of /cvsroot/docstring/dps/dps/transforms In directory usw-pr-cvs1:/tmp/cvs-serv5138/dps/dps/transforms Modified Files: frontmatter.py Log Message: minor refactoring Index: frontmatter.py =================================================================== RCS file: /cvsroot/docstring/dps/dps/transforms/frontmatter.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** frontmatter.py 2002/01/16 02:55:11 1.1 --- frontmatter.py 2002/01/26 00:00:50 1.2 *************** *** 106,123 **** def transform(self, doctree): self.setup_transform(doctree) index = doctree.findnonclass((nodes.comment, nodes.system_warning)) ! if self.checkpromotioncandidate(index): candidate = doctree[index] else: ! return doctree.attributes.update(candidate.attributes) doctree[:] = candidate[:1] + doctree[:index] + candidate[1:] # Check for a lone second-level section. index = doctree.findnonclass((nodes.comment, nodes.system_warning, ! nodes.title)) # new title ! if self.checkpromotioncandidate(index): candidate = doctree[index] else: ! return # Create a subtitle element based on the title element: subtitle = nodes.subtitle() --- 106,132 ---- def transform(self, doctree): self.setup_transform(doctree) + if self.promote_document_title(): + self.promote_document_subtitle() + + def promote_document_title(self): + doctree = self.doctree index = doctree.findnonclass((nodes.comment, nodes.system_warning)) ! if self.check_promotion_candidate(index): candidate = doctree[index] else: ! return None doctree.attributes.update(candidate.attributes) doctree[:] = candidate[:1] + doctree[:index] + candidate[1:] + return 1 + + def promote_document_subtitle(self): + doctree = self.doctree # Check for a lone second-level section. index = doctree.findnonclass((nodes.comment, nodes.system_warning, ! nodes.title)) # skip the new title ! if self.check_promotion_candidate(index): candidate = doctree[index] else: ! return None # Create a subtitle element based on the title element: subtitle = nodes.subtitle() *************** *** 126,138 **** # Put the subtitle element into the doctree doctree[:] = doctree[:1] + [subtitle] + doctree[1:index] + candidate[1:] ! return ! def checkpromotioncandidate(self, index): """ Return 1 iff the index'th child of node should be promoted. """ ! if index is None or len(self.doctree) > (index + 1): ! return None ! if not isinstance(self.doctree[index], nodes.section): return None return 1 --- 135,146 ---- # Put the subtitle element into the doctree doctree[:] = doctree[:1] + [subtitle] + doctree[1:index] + candidate[1:] ! return 1 ! def check_promotion_candidate(self, index): """ Return 1 iff the index'th child of node should be promoted. """ ! if index is None or len(self.doctree) > (index + 1) or \ ! not isinstance(self.doctree[index], nodes.section): return None return 1 *************** *** 211,214 **** --- 219,226 ---- def transform(self, doctree): self.setup_transform(doctree) + self.process_docinfo() + + def process_docinfo(self): + doctree = self.doctree index = doctree.findnonclass((nodes.title, nodes.subtitle, nodes.comment, nodes.system_warning)) *************** *** 218,222 **** if isinstance(candidate, nodes.field_list): biblioindex = doctree.findnonclass((nodes.title, nodes.subtitle)) ! nodelist, remainder = self.extractbibliographic(candidate) if remainder: doctree[index] = remainder --- 230,234 ---- if isinstance(candidate, nodes.field_list): biblioindex = doctree.findnonclass((nodes.title, nodes.subtitle)) ! nodelist, remainder = self.extract_bibliographic(candidate) if remainder: doctree[index] = remainder *************** *** 226,230 **** return ! def extractbibliographic(self, field_list): docinfo = nodes.docinfo() remainder = [] --- 238,242 ---- return ! def extract_bibliographic(self, field_list): docinfo = nodes.docinfo() remainder = [] *************** *** 236,250 **** normedname = utils.normname(name) if not (len(field) == 2 and bibliofields.has_key(normedname) ! and self.checkemptybibliofield(field, name)): raise TransformError biblioclass = bibliofields[normedname] if issubclass(biblioclass, nodes.TextElement): ! if not self.checkcompoundbibliofield(field, name): raise TransformError ! self.filterrcskeywords(field[1][0]) docinfo.append(biblioclass('', '', *field[1][0])) else: # multiple body elements possible if issubclass(biblioclass, nodes.authors): ! self.extractauthors(field, name, docinfo) elif issubclass(biblioclass, nodes.abstract): if abstract: --- 248,262 ---- normedname = utils.normname(name) if not (len(field) == 2 and bibliofields.has_key(normedname) ! and self.check_empty_biblio_field(field, name)): raise TransformError biblioclass = bibliofields[normedname] if issubclass(biblioclass, nodes.TextElement): ! if not self.check_compound_biblio_field(field, name): raise TransformError ! self.filter_rcs_keywords(field[1][0]) docinfo.append(biblioclass('', '', *field[1][0])) else: # multiple body elements possible if issubclass(biblioclass, nodes.authors): ! self.extract_authors(field, name, docinfo) elif issubclass(biblioclass, nodes.abstract): if abstract: *************** *** 268,272 **** return [docinfo], field_list ! def checkemptybibliofield(self, field, name): if len(field[1]) < 1: field[-1] += self.doctree.reporter.error( --- 280,284 ---- return [docinfo], field_list ! def check_empty_biblio_field(self, field, name): if len(field[1]) < 1: field[-1] += self.doctree.reporter.error( *************** *** 275,279 **** return 1 ! def checkcompoundbibliofield(self, field, name): if len(field[1]) > 1: field[-1] += self.doctree.reporter.error( --- 287,291 ---- return 1 ! def check_compound_biblio_field(self, field, name): if len(field[1]) > 1: field[-1] += self.doctree.reporter.error( *************** *** 288,292 **** return 1 ! rcskeywordsubstitutions = [ (re.compile(r'\$' r'Date: (\d\d\d\d)/(\d\d)/(\d\d) [\d:]+ \$$', re.IGNORECASE), r'\1-\2-\3'), --- 300,304 ---- return 1 ! rcs_keyword_substitutions = [ (re.compile(r'\$' r'Date: (\d\d\d\d)/(\d\d)/(\d\d) [\d:]+ \$$', re.IGNORECASE), r'\1-\2-\3'), *************** *** 295,302 **** (re.compile(r'\$[a-zA-Z]+: (.+) \$$'), r'\1'),] ! def filterrcskeywords(self, paragraph): if len(paragraph) == 1 and isinstance(paragraph[0], nodes.Text): textnode = paragraph[0] ! for pattern, substitution in self.rcskeywordsubstitutions: match = pattern.match(textnode.data) if match: --- 307,314 ---- (re.compile(r'\$[a-zA-Z]+: (.+) \$$'), r'\1'),] ! def filter_rcs_keywords(self, paragraph): if len(paragraph) == 1 and isinstance(paragraph[0], nodes.Text): textnode = paragraph[0] ! for pattern, substitution in self.rcs_keyword_substitutions: match = pattern.match(textnode.data) if match: *************** *** 304,318 **** return ! def extractauthors(self, field, name, docinfo): try: if len(field[1]) == 1: if isinstance(field[1][0], nodes.paragraph): ! authors = self.authorsfrom1paragraph(field) elif isinstance(field[1][0], nodes.bullet_list): ! authors = self.authorsfrombulletlist(field) else: raise TransformError else: ! authors = self.authorsfromparagraphs(field) authornodes = [nodes.author('', '', *author) for author in authors if author] --- 316,330 ---- return ! def extract_authors(self, field, name, docinfo): try: if len(field[1]) == 1: if isinstance(field[1][0], nodes.paragraph): ! authors = self.authors_from_one_paragraph(field) elif isinstance(field[1][0], nodes.bullet_list): ! authors = self.authors_from_bullet_list(field) else: raise TransformError else: ! authors = self.authors_from_paragraphs(field) authornodes = [nodes.author('', '', *author) for author in authors if author] *************** *** 328,332 **** raise ! def authorsfrom1paragraph(self, field): text = field[1][0].astext().strip() if not text: --- 340,344 ---- raise ! def authors_from_one_paragraph(self, field): text = field[1][0].astext().strip() if not text: *************** *** 340,344 **** return authors ! def authorsfrombulletlist(self, field): authors = [] for item in field[1][0]: --- 352,356 ---- return authors ! def authors_from_bullet_list(self, field): authors = [] for item in field[1][0]: *************** *** 350,354 **** return authors ! def authorsfromparagraphs(self, field): for item in field[1]: if not isinstance(item, nodes.paragraph): --- 362,366 ---- return authors ! def authors_from_paragraphs(self, field): for item in field[1]: if not isinstance(item, nodes.paragraph): |
From: David G. <go...@us...> - 2002-01-25 23:59:14
|
Update of /cvsroot/docstring/dps/dps/transforms In directory usw-pr-cvs1:/tmp/cvs-serv4631/dps/dps/transforms Modified Files: __init__.py Log Message: docstring Index: __init__.py =================================================================== RCS file: /cvsroot/docstring/dps/dps/transforms/__init__.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** __init__.py 2002/01/16 02:54:52 1.1 --- __init__.py 2002/01/25 23:59:12 1.2 *************** *** 21,29 **** of contents. ! Each transform is an optional step that a DPS Reader may choose to ! perform on the parsed document, depending on the input context. ! ! (@@@ delete: A DPS Reader may also perform Reader-specific transforms ! before performing these standard transforms.) """ --- 21,28 ---- of contents. ! Each transform is an optional step that a DPS Reader may choose to perform on ! the parsed document, depending on the input context. A DPS Reader may also ! perform Reader-specific transforms before or after performing these standard ! transforms. """ |
From: David G. <go...@us...> - 2002-01-25 23:58:39
|
Update of /cvsroot/docstring/dps/dps In directory usw-pr-cvs1:/tmp/cvs-serv4457/dps/dps Modified Files: statemachine.py Log Message: *** empty log message *** Index: statemachine.py =================================================================== RCS file: /cvsroot/docstring/dps/dps/statemachine.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** statemachine.py 2001/11/22 04:17:50 1.12 --- statemachine.py 2002/01/25 23:58:36 1.13 *************** *** 535,539 **** Add a list of transitions to the start of the transition list. ! Parameter: - `names`: a list of transition names. --- 535,539 ---- Add a list of transitions to the start of the transition list. ! Parameters: - `names`: a list of transition names. |
From: David G. <go...@us...> - 2002-01-25 23:58:12
|
Update of /cvsroot/docstring/dps/dps In directory usw-pr-cvs1:/tmp/cvs-serv4356/dps/dps Modified Files: nodes.py Log Message: - Added Visitor classes & Node.walk(). - Improved ``__repr__()``. - Improved some names. - Removed Python-specific element classes. - Reworked for hyperlink transforms. - Added docstrings. Index: nodes.py =================================================================== RCS file: /cvsroot/docstring/dps/dps/nodes.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** nodes.py 2002/01/16 02:47:59 1.21 --- nodes.py 2002/01/25 23:58:09 1.22 *************** *** 8,11 **** --- 8,19 ---- :Copyright: This module has been placed in the public domain. + Classes in CamelCase are abstract base classes or auxiliary classes. The one + exception is `Text`, for a text node; uppercase is used to differentiate from + element classes. + + Classes in lower_case_with_underscores are element classes, matching the XML + element generic identifiers in the DTD_. + + .. _DTD: http://docstring.sourceforge.net/spec/gpdi.dtd """ *************** *** 21,24 **** --- 29,34 ---- class Node: + """Abstract base class of nodes in a document tree.""" + def __nonzero__(self): """Node instances are always true.""" *************** *** 28,42 **** return self._dom_node(dom) ! def _dom_node(self, dom): ! pass ! ! def _rooted_dom_node(self, domroot): ! pass ! def astext(self): ! pass ! def validate(self): ! pass --- 38,58 ---- return self._dom_node(dom) ! def walk(self, visitor, ancestry=()): ! """ ! Traverse a tree of `Node` objects, calling ``visit_*`` methods of ! `visitor`. ! Parameters: ! - `visitor`: A `Visitor` object, containing a ``visit_...`` method for ! each `Node` subclass encountered. ! - `ancestry`: A list of (parent, index) pairs. `self`'s parent is the ! last entry. ! """ ! method = getattr(visitor, 'visit_' + self.__class__.__name__) ! method(self, ancestry) ! children = self.getchildren() ! for i in range(len(children)): ! children[i].walk(visitor, ancestry + ((self, i),)) *************** *** 51,57 **** return '<%s: %s>' % (self.tagname, data) def _dom_node(self, dom): return dom.Text(self.data) ! def _rooted_dom_node(self, domroot): return domroot.createTextNode(self.data) --- 67,79 ---- return '<%s: %s>' % (self.tagname, data) + def shortrepr(self): + data = repr(self.data) + if len(data) > 20: + data = repr(self.data[:16] + ' ...') + return '<%s: %s>' % (self.tagname, data) + def _dom_node(self, dom): return dom.Text(self.data) ! def _rooted_dom_node(self, domroot): return domroot.createTextNode(self.data) *************** *** 67,70 **** --- 89,96 ---- return ''.join(result) + def getchildren(self): + """Text nodes have no children. Return [].""" + return [] + class Element(Node): *************** *** 99,103 **** attribute to the name of the class.""" ! childtextsep = '\n\n' """Separator for child nodes, used by `astext()` method.""" --- 125,129 ---- attribute to the name of the class.""" ! child_text_separator = '\n\n' """Separator for child nodes, used by `astext()` method.""" *************** *** 105,112 **** self.rawsource = rawsource """The raw text from which this element was constructed.""" ! self.children = list(children) """List of child nodes (elements and/or text).""" ! self.attributes = attributes """Dictionary of attribute {name: value}.""" --- 131,138 ---- self.rawsource = rawsource """The raw text from which this element was constructed.""" ! self.children = list(children) """List of child nodes (elements and/or text).""" ! self.attributes = attributes """Dictionary of attribute {name: value}.""" *************** *** 134,142 **** data = '' for c in self.children: ! data += '<%s...>' % c.tagname if len(data) > 60: data = data[:56] + ' ...' break ! return '<%s: %s>' % (self.__class__.__name__, data) def __str__(self): --- 160,179 ---- data = '' for c in self.children: ! data += c.shortrepr() if len(data) > 60: data = data[:56] + ' ...' break ! if self.hasattr('name'): ! return '<%s "%s": %s>' % (self.__class__.__name__, ! self.attributes['name'], data) ! else: ! return '<%s: %s>' % (self.__class__.__name__, data) ! ! def shortrepr(self): ! if self.hasattr('name'): ! return '<%s "%s"...>' % (self.__class__.__name__, ! self.attributes['name']) ! else: ! return '<%s...>' % self.tagname def __str__(self): *************** *** 215,220 **** def astext(self): ! return self.childtextsep.join([child.astext() ! for child in self.children]) def attlist(self): --- 252,257 ---- def astext(self): ! return self.child_text_separator.join( ! [child.astext() for child in self.children]) def attlist(self): *************** *** 251,258 **** def findclass(self, childclass, start=0, end=sys.maxint): """ ! Return the index of the first child whose class matches `childclass`. ! `childclass` may also be a tuple of node classes, in which case any ! of the classes may match. """ if not isinstance(childclass, TupleType): --- 288,299 ---- def findclass(self, childclass, start=0, end=sys.maxint): """ ! Return the index of the first child whose class exactly matches. ! Parameters: ! ! - `childclass`: A `Node` subclass to search for, or a tuple of `Node` ! classes. If a tuple, any of the classes may match. ! - `start`: Initial index to check. ! - `end`: Initial index to *not* check. """ if not isinstance(childclass, TupleType): *************** *** 266,273 **** def findnonclass(self, childclass, start=0, end=sys.maxint): """ ! Return the index of the first child not matching `childclass`. ! `childclass` may also be a tuple of node classes, in which case none ! of the classes may match. """ if not isinstance(childclass, TupleType): --- 307,318 ---- def findnonclass(self, childclass, start=0, end=sys.maxint): """ ! Return the index of the first child whose class does *not* match. ! Parameters: ! ! - `childclass`: A `Node` subclass to skip, or a tuple of `Node` ! classes. If a tuple, none of the classes may match. ! - `start`: Initial index to check. ! - `end`: Initial index to *not* check. """ if not isinstance(childclass, TupleType): *************** *** 276,280 **** match = 0 for c in childclass: ! if isinstance(self[index], c): match = 1 if not match: --- 321,325 ---- match = 0 for c in childclass: ! if isinstance(self.children[index], c): match = 1 if not match: *************** *** 284,290 **** def pformat(self, indent=' ', level=0): return ''.join(['%s%s\n' % (indent * level, self.starttag())] + ! [child.pformat(indent, level+1) ! for child in self.children]) class TextElement(Element): --- 329,339 ---- def pformat(self, indent=' ', level=0): return ''.join(['%s%s\n' % (indent * level, self.starttag())] + ! [child.pformat(indent, level+1) ! for child in self.children]) + def getchildren(self): + """Return this element's children.""" + return self.children + class TextElement(Element): *************** *** 296,300 **** """ ! childtextsep = '' """Separator for child nodes, used by `astext()` method.""" --- 345,349 ---- """ ! child_text_separator = '' """Separator for child nodes, used by `astext()` method.""" *************** *** 308,311 **** --- 357,369 ---- + # ======== + # Mixins + # ======== + + class ToBeResolved: + + resolved = 0 + + # ==================== # Element Categories *************** *** 335,338 **** --- 393,402 ---- + class Reference(ToBeResolved): + + refnode = None + """Resolved reference to a node.""" + + # ============== # Root Element *************** *** 343,360 **** def __init__(self, reporter, languagecode, *args, **kwargs): Element.__init__(self, *args, **kwargs) self.reporter = reporter self.languagecode = languagecode ! self.explicittargets = {} ! self.implicittargets = {} ! self.externaltargets = {} ! self.indirecttargets = {} ! self.substitutiondefs = {} self.refnames = {} ! self.substitutionrefs = {} ! self.anonymoustargets = [] ! self.anonymousrefs = [] self.autofootnotes = [] ! self.autofootnoterefs = [] def asdom(self, dom=xml.dom.minidom): domroot = dom.Document() --- 407,457 ---- def __init__(self, reporter, languagecode, *args, **kwargs): Element.__init__(self, *args, **kwargs) + self.reporter = reporter + """System warning generator.""" + self.languagecode = languagecode ! """ISO 639 2-letter language identifier.""" ! ! self.explicit_targets = {} ! """Mapping of target names to lists of explicit target nodes.""" ! ! self.implicit_targets = {} ! """Mapping of target names to lists of implicit (internal) target ! nodes.""" ! ! self.external_targets = {} ! """Mapping of target names to lists of external target nodes.""" ! ! self.indirect_targets = {} ! """Mapping of target names to indirect target nodes.""" ! ! self.substitution_defs = {} ! """Mapping of substitution names to substitution_definition nodes.""" ! self.refnames = {} ! """Mapping of reference names to reference nodes.""" ! ! self.substitution_refs = {} ! """Mapping of substitution names to substitution_reference nodes.""" ! ! self.anonymous_targets = [] ! """List of anonymous target nodes.""" ! ! self.anonymous_refs = [] ! """List of anonymous reference nodes.""" ! self.autofootnotes = [] ! """List of auto-numbered footnote nodes.""" + self.autofootnote_refs = [] + """List of auto-numbered footnote_reference nodes.""" + + self.anonymous_start = 1 + """Initial anonymous hyperlink number.""" + + self.autofootnote_start = 1 + """Initial auto-numbered footnote number.""" + def asdom(self, dom=xml.dom.minidom): domroot = dom.Document() *************** *** 362,402 **** return domroot ! def addimplicittarget(self, name, targetnode, innode=None): if innode == None: ! innode = targetnode ! if self.explicittargets.has_key(name) \ ! or self.externaltargets.has_key(name) \ ! or self.implicittargets.has_key(name): sw = self.reporter.information( 'Duplicate implicit target name: "%s"' % name) innode += sw ! self.cleartargetnames(name, self.implicittargets) targetnode['dupname'] = name ! self.implicittargets.setdefault(name, []).append(targetnode) ! else: ! self.implicittargets[name] = [targetnode] ! targetnode['name'] = name ! def addexplicittarget(self, name, targetnode, innode=None): if innode == None: ! innode = targetnode ! if self.explicittargets.has_key(name): ! sw = self.reporter.warning( ! 'Duplicate explicit target name: "%s"' % name) innode += sw ! self.cleartargetnames(name, self.explicittargets, ! self.implicittargets, self.externaltargets) ! targetnode['dupname'] = name ! self.explicittargets.setdefault(name, []).append(targetnode) ! return ! elif self.implicittargets.has_key(name): sw = self.reporter.information( 'Duplicate implicit target name: "%s"' % name) innode += sw ! self.cleartargetnames(name, self.implicittargets) ! self.explicittargets[name] = [targetnode] ! targetnode['name'] = name ! def cleartargetnames(self, name, *targetdicts): for targetdict in targetdicts: for node in targetdict.get(name, []): --- 459,506 ---- return domroot ! def note_implicit_target(self, targetnode, innode=None): if innode == None: ! innode = self ! name = targetnode['name'] ! if self.explicit_targets.has_key(name) \ ! or self.external_targets.has_key(name) \ ! or self.implicit_targets.has_key(name): sw = self.reporter.information( 'Duplicate implicit target name: "%s"' % name) innode += sw ! self.clear_target_names(name, self.implicit_targets) ! del targetnode['name'] targetnode['dupname'] = name ! self.implicit_targets.setdefault(name, []).append(targetnode) ! def note_explicit_target(self, targetnode, innode=None): if innode == None: ! innode = self ! name = targetnode['name'] ! if self.explicit_targets.has_key(name): ! level = 1 ! if targetnode.has_key('refuri'): # external target, dups OK ! refuri = targetnode['refuri'] ! for t in self.explicit_targets.get(name, []): ! if not t.has_key('refuri') or t['refuri'] != refuri: ! break ! else: ! level = 0 # just inform if refuri's identical ! sw = self.reporter.system_warning( ! level, 'Duplicate explicit target name: "%s"' % name) innode += sw ! self.clear_target_names(name, self.explicit_targets, ! self.implicit_targets) ! if level > 0: ! del targetnode['name'] ! targetnode['dupname'] = name ! elif self.implicit_targets.has_key(name): sw = self.reporter.information( 'Duplicate implicit target name: "%s"' % name) innode += sw ! self.clear_target_names(name, self.implicit_targets) ! self.explicit_targets.setdefault(name, []).append(targetnode) ! def clear_target_names(self, name, *targetdicts): for targetdict in targetdicts: for node in targetdict.get(name, []): *************** *** 405,466 **** del node['name'] ! def addrefname(self, name, node): ! self.refnames.setdefault(name, []).append(node) ! def addexternaltarget(self, name, reference, targetnode, innode): ! if self.explicittargets.has_key(name): ! level = 0 ! for t in self.explicittargets.get(name, []): ! if not t.has_key('refuri') or t['refuri'] != reference: ! level = 1 ! break ! sw = self.reporter.system_warning( ! level, 'Duplicate external target name: "%s"' % name) ! innode += sw ! self.cleartargetnames(name, self.explicittargets, ! self.externaltargets, self.implicittargets) ! elif self.implicittargets.has_key(name): ! sw = self.reporter.information( ! 'Duplicate implicit target name: "%s"' % name) ! innode += sw ! self.cleartargetnames(name, self.implicittargets) ! self.externaltargets.setdefault(name, []).append(targetnode) ! self.explicittargets.setdefault(name, []).append(targetnode) ! targetnode['name'] = name ! targetnode['refuri'] = reference ! def addindirecttarget(self, refname, targetnode): ! targetnode['refname'] = refname ! self.indirecttargets[refname] = targetnode ! def addanonymoustarget(self, targetnode): ! targetnode['anonymous'] = 1 ! self.anonymoustargets.append(targetnode) ! def addanonymousref(self, refnode): ! refnode['anonymous'] = 1 ! self.anonymousrefs.append(refnode) ! def addautofootnote(self, name, footnotenode): ! footnotenode['auto'] = 1 ! self.autofootnotes.append((name, footnotenode)) ! def addautofootnoteref(self, refname, refnode): ! refnode['auto'] = 1 ! self.autofootnoterefs.append((refname, refnode)) ! def addsubstitutiondef(self, name, substitutiondefnode, innode): ! if self.substitutiondefs.has_key(name): sw = self.reporter.error( 'Duplicate substitution definition name: "%s"' % name) innode += sw ! oldnode = self.substitutiondefs[name] oldnode['dupname'] = oldnode['name'] del oldnode['name'] ! self.substitutiondefs[name] = substitutiondefnode ! def addsubstitutionref(self, refname, subrefnode): ! subrefnode['refname'] = refname ! self.substitutionrefs.setdefault(refname, []).append(subrefnode) --- 509,553 ---- del node['name'] ! def note_refname(self, node): ! self.refnames.setdefault(node['refname'], []).append(node) ! def note_external_target(self, targetnode): ! self.external_targets.setdefault( ! targetnode['name'], []).append(targetnode) ! def note_indirect_target(self, targetnode): ! self.indirect_targets.setdefault( ! targetnode['name'], []).append(targetnode) ! self.note_refname(targetnode) ! def note_anonymous_target(self, targetnode): ! self.anonymous_targets.append(targetnode) ! def note_anonymous_ref(self, refnode): ! self.anonymous_refs.append(refnode) ! def note_autofootnote(self, footnotenode): ! self.autofootnotes.append(footnotenode) ! def note_autofootnote_ref(self, refnode): ! self.autofootnote_refs.append(refnode) ! def note_substitution_def(self, substitutiondefnode, innode=None): ! if innode == None: ! innode = self ! name = substitutiondefnode['name'] ! if self.substitution_defs.has_key(name): sw = self.reporter.error( 'Duplicate substitution definition name: "%s"' % name) innode += sw ! oldnode = self.substitution_defs[name] oldnode['dupname'] = oldnode['name'] del oldnode['name'] ! # keep only the last definition ! self.substitution_defs[name] = substitutiondefnode ! def note_substitution_ref(self, subrefnode): ! self.substitution_refs.setdefault( ! subrefnode['refname'], []).append(subrefnode) *************** *** 497,521 **** class transition(Structural, Element): pass - class package_section(Structural, Element): pass - class module_section(Structural, Element): pass - class class_section(Structural, Element): pass - class method_section(Structural, Element): pass - class function_section(Structural, Element): pass - class module_attribute_section(Structural, Element): pass - class class_attribute_section(Structural, Element): pass - class instance_attribute_section(Structural, Element): pass - - # Structural Support Elements - # --------------------------- - class inheritance_list(Component, Element): pass - class parameter_list(Component, Element): pass - class parameter_item(Component, Element): pass - class optional_parameters(Component, Element): pass - class parameter_tuple(Component, Element): pass - class parameter_default(Component, TextElement): pass - class initial_value(Component, TextElement): pass - - # =============== # Body Elements --- 584,588 ---- *************** *** 558,562 **** class comment(Special, TextElement): pass class substitution_definition(Special, TextElement): pass ! class target(Special, Inline, TextElement): pass class footnote(General, Element): pass class label(Component, TextElement): pass --- 625,629 ---- class comment(Special, TextElement): pass class substitution_definition(Special, TextElement): pass ! class target(Special, Inline, TextElement, ToBeResolved): pass class footnote(General, Element): pass class label(Component, TextElement): pass *************** *** 593,620 **** class emphasis(Inline, TextElement): pass class strong(Inline, TextElement): pass ! class interpreted(Inline, TextElement): pass class literal(Inline, TextElement): pass ! class reference(Inline, TextElement): pass ! class footnote_reference(Inline, TextElement): pass ! class substitution_reference(Inline, TextElement): pass class image(General, Inline, TextElement): pass - class package(Component, Inline, TextElement): pass - class module(Component, Inline, TextElement): pass ! class inline_class(Component, Inline, TextElement): - tagname = 'class' ! class method(Component, Inline, TextElement): pass ! class function(Component, Inline, TextElement): pass ! class variable(Inline, TextElement): pass ! class parameter(Component, Inline, TextElement): pass ! class type(Inline, TextElement): pass ! class class_attribute(Component, Inline, TextElement): pass ! class module_attribute(Component, Inline, TextElement): pass ! class instance_attribute(Component, Inline, TextElement): pass ! class exception_class(Inline, TextElement): pass ! class warning_class(Inline, TextElement): pass --- 660,748 ---- class emphasis(Inline, TextElement): pass class strong(Inline, TextElement): pass ! class interpreted(Inline, Reference, TextElement): pass class literal(Inline, TextElement): pass ! class reference(Inline, Reference, TextElement): pass ! class footnote_reference(Inline, Reference, TextElement): pass ! class substitution_reference(Inline, Reference, TextElement): pass class image(General, Inline, TextElement): pass + # ======================================== + # Auxiliary Classes, Functions, and Data + # ======================================== ! node_class_names = """ ! Text ! abstract attention author authors ! block_quote bullet_list ! caption caution classifier colspec comment contact copyright ! danger date definition definition_list definition_list_item ! description docinfo doctest_block document ! emphasis entry enumerated_list error ! field field_argument field_body field_list field_name figure ! footnote footnote_reference ! hint ! image important interpreted ! label legend list_item literal literal_block long_option ! note ! option option_argument option_list option_list_item organization ! paragraph ! reference revision row ! section short_option status strong substitution_definition ! substitution_reference subtitle system_warning ! table target tbody term tgroup thead tip title transition ! version vms_option ! warning""".split() ! """A list of names of all concrete Node subclasses.""" + class Visitor: ! """ ! "Visitor" pattern [GoF95]_ abstract superclass implementation for document ! tree traversals. ! ! Each node class has corresponding methods, doing nothing by default; ! override individual methods for specific and useful behaviour. The ! "``visit_`` + node class name" method is called by `Node.walk()` upon ! entering a node. ! ! .. [GoF95] Gamma, Helm, Johnson, Vlissides. *Design Patterns: Elements of ! Reusable Object-Oriented Software*. Addison-Wesley, Reading, MA, USA, ! 1995. ! """ ! ! def __init__(self, doctree): ! self.doctree = doctree ! ! def walk(self): ! self.doctree.walk(self) ! ! # Save typing with dynamic definitions. ! for name in node_class_names: ! exec """def visit_%s(self, node, ancestry): pass\n""" % name ! del name ! ! ! class GenericVisitor(Visitor): ! ! """ ! Generic "Visitor" abstract superclass, for simple traversals. ! ! Unless overridden, each ``visit_*`` method calls `default_visit()`. ! ``default_visit()`` must be overridden in subclasses. ! ! Define fully generic visitors by overriding ``default_visit()`` only. ! Define semi-generic visitors by overriding individual ``visit_*()`` ! methods also. ! """ ! ! def default_visit(self, node, ancestry): ! """Override for generic, uniform traversals.""" ! raise NotImplementedError ! ! # Save typing with dynamic definitions. ! for name in node_class_names: ! exec """def visit_%s(self, node, ancestry): ! self.default_visit(node, ancestry)\n""" % name ! del name |
From: David G. <go...@us...> - 2002-01-25 23:50:58
|
Update of /cvsroot/docstring/dps/dps/languages In directory usw-pr-cvs1:/tmp/cvs-serv2949/dps/dps/languages Modified Files: en.py Log Message: - Removed Python-specific interpreted text mapping. Index: en.py =================================================================== RCS file: /cvsroot/docstring/dps/dps/languages/en.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** en.py 2002/01/16 02:50:12 1.5 --- en.py 2002/01/25 23:50:55 1.6 *************** *** 21,45 **** - interpreted = { - 'package': nodes.package, - 'module': nodes.module, - 'class': nodes.inline_class, - 'method': nodes.method, - 'function': nodes.function, - 'variable': nodes.variable, - 'parameter': nodes.parameter, - 'type': nodes.type, - 'class attribute': nodes.class_attribute, - 'classatt': nodes.class_attribute, - 'instance attribute': nodes.instance_attribute, - 'instanceatt': nodes.instance_attribute, - 'module attribute': nodes.module_attribute, - 'moduleatt': nodes.module_attribute, - 'exception class': nodes.exception_class, - 'exception': nodes.exception_class, - 'warning class': nodes.warning_class, - 'warning': nodes.warning_class,} - """Mapping of interpreted text role name to nodes.py class.""" - bibliographic_labels = { 'author': 'Author', --- 21,24 ---- |
From: David G. <go...@us...> - 2002-01-16 02:56:40
|
Update of /cvsroot/docstring/dps In directory usw-pr-cvs1:/tmp/cvs-serv29958/dps Modified Files: HISTORY.txt Log Message: updated Index: HISTORY.txt =================================================================== RCS file: /cvsroot/docstring/dps/HISTORY.txt,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** HISTORY.txt 2001/11/22 04:18:23 1.31 --- HISTORY.txt 2002/01/16 02:56:37 1.32 *************** *** 40,43 **** --- 40,45 ---- * setup.py: Modified for import by install.py. + * dps/__init__.py: Added docstring. + * dps/nodes.py: *************** *** 72,75 **** --- 74,79 ---- - Added element hierarchy base classes. - Removed generic 'directive'. + - 'errorhandler' -> 'reporter'. + - Added document.languagecode. * dps/roman.py: Added to project. Written by and courtesy of Mark *************** *** 103,106 **** --- 107,111 ---- - Added some docstrings. - Added 'parseattributes()', associated functions and exceptions. + - Moved 'normname()' from restructuredtext.states. * dps/test_*.py: Moved to new test/ directory. *************** *** 120,123 **** --- 125,132 ---- - Changed node class names to node classes. - Removed parser-specific data. + - Added 'bibliographic_fields' and 'author_separators' (transform + support). + + * dps/transforms: Subpackage added. * test: Subdirectory added. The top-level consists of a modular test |
From: David G. <go...@us...> - 2002-01-16 02:55:14
|
Update of /cvsroot/docstring/dps/dps/transforms In directory usw-pr-cvs1:/tmp/cvs-serv29718/dps/dps/transforms Added Files: frontmatter.py Log Message: added to project --- NEW FILE: frontmatter.py --- #! /usr/bin/env python """ :Authors: David Goodger, Ueli Schlaepfer :Contact: go...@us... :Revision: $Revision: 1.1 $ :Date: $Date: 2002/01/16 02:55:11 $ :Copyright: This module has been placed in the public domain. Transforms related to the front matter of a document (information found before the main text): - `DocTitle`: Used to transform a lone top level section's title to the document title, and promote a remaining lone top-level section's title to the document subtitle. - `DocInfo`: Used to transform a bibliographic field list into docinfo elements. """ __docformat__ = 'reStructuredText' import re from dps import nodes, utils from dps.transforms import TransformError, Transform class DocTitle(Transform): """ In reStructuredText_, there is no way to specify a document title and subtitle explicitly. Instead, we can supply the document title (and possibly the subtitle as well) implicitly, and use this two-step transform to "raise" or "promote" the title(s) (and their corresponding section contents) to the document level. 1. If the document contains a single top-level section as its first non-comment element, the top-level section's title becomes the document's title, and the top-level section's contents become the document's immediate contents. The lone top-level section header must be the first non-comment element in the document. For example, take this input text:: ================= Top-Level Title ================= A paragraph. Once parsed, it looks like this:: <document> <section name="top-level title"> <title> Top-Level Title <paragraph> A paragraph. After running the DocTitle transform, we have:: <document name="top-level title"> <title> Top-Level Title <paragraph> A paragraph. 2. If step 1 successfully determines the document title, we continue by checking for a subtitle. If the lone top-level section itself contains a single second-level section as its first non-comment element, that section's title is promoted to the document's subtitle, and that section's contents become the document's immediate contents. Given this input text:: ================= Top-Level Title ================= Second-Level Title ~~~~~~~~~~~~~~~~~~ A paragraph. After parsing and running the Section Promotion transform, the result is:: <document name="top-level title"> <title> Top-Level Title <subtitle name="second-level title"> Second-Level Title <paragraph> A paragraph. (Note that the implicit hyperlink target generated by the "Second-Level Title" is preserved on the "subtitle" element itself.) Any comment elements occurring before the document title or subtitle are accumulated and inserted as the first body elements after the title(s). """ def transform(self, doctree): self.setup_transform(doctree) index = doctree.findnonclass((nodes.comment, nodes.system_warning)) if self.checkpromotioncandidate(index): candidate = doctree[index] else: return doctree.attributes.update(candidate.attributes) doctree[:] = candidate[:1] + doctree[:index] + candidate[1:] # Check for a lone second-level section. index = doctree.findnonclass((nodes.comment, nodes.system_warning, nodes.title)) # new title if self.checkpromotioncandidate(index): candidate = doctree[index] else: return # Create a subtitle element based on the title element: subtitle = nodes.subtitle() subtitle.attributes.update(candidate[0].attributes) subtitle[:] = candidate[0][:] # Put the subtitle element into the doctree doctree[:] = doctree[:1] + [subtitle] + doctree[1:index] + candidate[1:] return def checkpromotioncandidate(self, index): """ Return 1 iff the index'th child of node should be promoted. """ if index is None or len(self.doctree) > (index + 1): return None if not isinstance(self.doctree[index], nodes.section): return None return 1 class DocInfo(Transform): """ This transform is specific to the reStructuredText_ markup syntax; see "Bibliographic Fields" in the `reStructuredText Markup Specification`_ for a high-level description. This transform should be run *after* the `DocTitle` transform. Given a field list as the first non-comment element after the document title and subtitle (if present), registered bibliographic field names are transformed to the corresponding DTD elements, becoming child elements of the "docinfo" element. For example, given this document fragment after parsing:: <document> <title> Document Title <field_list> <field> <field_name> Author <field_body> <paragraph> Kilgore Trout <field> <field_name> Status <field_body> <paragraph> $RCSfile: frontmatter.py,v $ ... After running the bibliographic field list transform, the resulting document tree would look like this:: <document> <title> Document Title <docinfo> <author> Kilgore Trout <status> frontmatter.py ... The "Status" field contained an expanded RCS keyword, which is normally (but optionally) cleaned up by the transform. The sole contents of the field body must be a paragraph containing an expanded RCS keyword of the form "$keyword: expansion text $". Any RCS keyword can be processed in any bibliographic field. The dollar signs and leading RCS keyword name are removed. Extra processing is done for the following RCS keywords: - "RCSfile" expands to the name of the file in the RCS or CVS repository, which is the name of the source file with a ",v" suffix appended. The transform will remove the ",v" suffix. - "Date" expands to the format "YYYY/MM/DD hh:mm:ss" (in the UTC time zone). The RCS Keywords transform will extract just the date itself and transform it to an ISO 8601 format date, as in "2000-12-31". (Since the source file for this text is itself stored under CVS, we can't show an example of the "Date" RCS keyword because we can't prevent any RCS keywords used in this explanation from being expanded. Only the "RCSfile" keyword is stable; its expansion text changes only if the file name changes.) """ def transform(self, doctree): self.setup_transform(doctree) index = doctree.findnonclass((nodes.title, nodes.subtitle, nodes.comment, nodes.system_warning)) if index is None: return candidate = doctree[index] if isinstance(candidate, nodes.field_list): biblioindex = doctree.findnonclass((nodes.title, nodes.subtitle)) nodelist, remainder = self.extractbibliographic(candidate) if remainder: doctree[index] = remainder else: del doctree[index] doctree[biblioindex:biblioindex] = nodelist return def extractbibliographic(self, field_list): docinfo = nodes.docinfo() remainder = [] bibliofields = self.language.bibliographic_fields abstract = None for field in field_list: try: name = field[0][0].astext() normedname = utils.normname(name) if not (len(field) == 2 and bibliofields.has_key(normedname) and self.checkemptybibliofield(field, name)): raise TransformError biblioclass = bibliofields[normedname] if issubclass(biblioclass, nodes.TextElement): if not self.checkcompoundbibliofield(field, name): raise TransformError self.filterrcskeywords(field[1][0]) docinfo.append(biblioclass('', '', *field[1][0])) else: # multiple body elements possible if issubclass(biblioclass, nodes.authors): self.extractauthors(field, name, docinfo) elif issubclass(biblioclass, nodes.abstract): if abstract: field[-1] += self.doctree.reporter.error( 'There can only be one abstract.') raise TransformError abstract = nodes.abstract('', *field[1].children) else: docinfo.append(biblioclass('', *field[1].children)) except TransformError: remainder.append(field) continue if abstract: docinfo.append(abstract) if len(docinfo) == 0: return [], field_list if remainder: field_list[:] = remainder else: field_list = None return [docinfo], field_list def checkemptybibliofield(self, field, name): if len(field[1]) < 1: field[-1] += self.doctree.reporter.error( 'Cannot extract empty bibliographic field "%s".' % name) return None return 1 def checkcompoundbibliofield(self, field, name): if len(field[1]) > 1: field[-1] += self.doctree.reporter.error( 'Cannot extract compound bibliographic field "%s".' % name) return None if not isinstance(field[1][0], nodes.paragraph): field[-1] += self.doctree.reporter.error( 'Cannot extract bibliographic field "%s" containing anything ' 'other than a single paragraph.' % name) return None return 1 rcskeywordsubstitutions = [ (re.compile(r'\$' r'Date: (\d\d\d\d)/(\d\d)/(\d\d) [\d:]+ \$$', re.IGNORECASE), r'\1-\2-\3'), (re.compile(r'\$' r'RCSfile: (.+),v \$$', re.IGNORECASE), r'\1'), (re.compile(r'\$[a-zA-Z]+: (.+) \$$'), r'\1'),] def filterrcskeywords(self, paragraph): if len(paragraph) == 1 and isinstance(paragraph[0], nodes.Text): textnode = paragraph[0] for pattern, substitution in self.rcskeywordsubstitutions: match = pattern.match(textnode.data) if match: textnode.data = pattern.sub(substitution, textnode.data) return def extractauthors(self, field, name, docinfo): try: if len(field[1]) == 1: if isinstance(field[1][0], nodes.paragraph): authors = self.authorsfrom1paragraph(field) elif isinstance(field[1][0], nodes.bullet_list): authors = self.authorsfrombulletlist(field) else: raise TransformError else: authors = self.authorsfromparagraphs(field) authornodes = [nodes.author('', '', *author) for author in authors if author] docinfo.append(nodes.authors('', *authornodes)) except TransformError: field[-1] += self.doctree.reporter.error( 'Bibliographic field "%s" incompatible with extraction: ' 'it must contain either a single paragraph (with authors ' 'separated by one of "%s"), multiple paragraphs (one per ' 'author), or a bullet list with one paragraph (one author) ' 'per item.' % (name, ''.join(self.language.author_separators))) raise def authorsfrom1paragraph(self, field): text = field[1][0].astext().strip() if not text: raise TransformError for authorsep in self.language.author_separators: authornames = text.split(authorsep) if len(authornames) > 1: break authornames = [author.strip() for author in authornames] authors = [[nodes.Text(author)] for author in authornames] return authors def authorsfrombulletlist(self, field): authors = [] for item in field[1][0]: if len(item) != 1 or not isinstance(item[0], nodes.paragraph): raise TransformError authors.append(item[0].children) if not authors: raise TransformError return authors def authorsfromparagraphs(self, field): for item in field[1]: if not isinstance(item, nodes.paragraph): raise TransformError authors = [item.children for item in field[1]] return authors |
From: David G. <go...@us...> - 2002-01-16 02:54:55
|
Update of /cvsroot/docstring/dps/dps/transforms In directory usw-pr-cvs1:/tmp/cvs-serv29527/dps/dps/transforms Added Files: __init__.py Log Message: added to project --- NEW FILE: __init__.py --- #! /usr/bin/env python """ :Authors: David Goodger, Ueli Schlaepfer :Contact: go...@us... :Revision: $Revision: 1.1 $ :Date: $Date: 2002/01/16 02:54:52 $ :Copyright: This module has been placed in the public domain. This package contains modules for standard tree transforms available to DPS components. Tree transforms serve a variety of purposes: - To tie up certain syntax-specific "loose ends" that remain after the initial parsing of the input plaintext. These transforms are used to supplement a limited syntax. - To automate the internal linking of the document tree (hyperlink references, footnote references, etc.). - To extract useful information from the document tree. These transforms may be used to construct (for example) indexes and tables of contents. Each transform is an optional step that a DPS Reader may choose to perform on the parsed document, depending on the input context. (@@@ delete: A DPS Reader may also perform Reader-specific transforms before performing these standard transforms.) """ __docformat__ = 'reStructuredText' from dps import languages class TransformError(Exception): pass class Transform: def transform(self, doctree): """Override to transform the document tree.""" raise NotImplementedError('subclass must override this method') def setup_transform(self, doctree): """Initial setup, used by `self.transform()`.""" self.doctree = doctree self.language = languages.language(doctree.languagecode) |
From: David G. <go...@us...> - 2002-01-16 02:52:44
|
Update of /cvsroot/docstring/dps/dps/transforms In directory usw-pr-cvs1:/tmp/cvs-serv29196/transforms Log Message: Directory /cvsroot/docstring/dps/dps/transforms added to the repository |
From: David G. <go...@us...> - 2002-01-16 02:51:50
|
Update of /cvsroot/docstring/dps/dps In directory usw-pr-cvs1:/tmp/cvs-serv29005/dps/dps Modified Files: __init__.py Log Message: - Added docstring. Index: __init__.py =================================================================== RCS file: /cvsroot/docstring/dps/dps/__init__.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** __init__.py 2001/07/22 22:35:43 1.1.1.1 --- __init__.py 2002/01/16 02:51:47 1.2 *************** *** 1,3 **** #! /usr/bin/env python ! # $Id$ ! # by David Goodger --- 1,45 ---- #! /usr/bin/env python ! ! """ ! :Author: David Goodger ! :Contact: go...@us... ! :Revision: $Revision$ ! :Date: $Date$ ! :Copyright: This module has been placed in the public domain. ! ! This is the Docstring Processing System (DPS) Python package. ! ! Package Structure ! ================= ! ! Modules: ! ! - __init__.py: Contains package docstring only (this text). ! ! - nodes.py: DPS document tree (doctree) node class library. ! ! - roman.py: Conversion to and from Roman numerals. Courtesy of Mark ! Pilgrim (http://diveintopython.org/). ! ! - statemachine.py: A finite state machine specialized for ! regular-expression-based text filters. ! ! - urischemes.py: Contains a complete mapping of known URI addressing ! scheme names to descriptions. ! ! - utils.py: Miscellaneous utilities. ! ! Subpackages: ! ! - languages: Language-specific mappings of terms. ! ! - parsers: Syntax-specific input parser modules or packages. ! ! - readers: Context-specific input handlers which understand the data ! source and manage a parser. ! ! - transforms: Modules used by readers and writers to modify DPS ! doctrees. ! ! - writers: Format-specific output translators. ! """ |
From: David G. <go...@us...> - 2002-01-16 02:50:15
|
Update of /cvsroot/docstring/dps/dps/languages In directory usw-pr-cvs1:/tmp/cvs-serv28717/dps/dps/languages Modified Files: en.py Log Message: - Added 'bibliographic_fields' and 'author_separators' (transform support). Index: en.py =================================================================== RCS file: /cvsroot/docstring/dps/dps/languages/en.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** en.py 2001/09/10 04:10:40 1.4 --- en.py 2002/01/16 02:50:12 1.5 *************** *** 14,18 **** __docformat__ = 'reStructuredText' ! __all__ = ['interpreted', 'bibliographic_labels'] --- 14,19 ---- __docformat__ = 'reStructuredText' ! __all__ = ['interpreted', 'bibliographic_labels', 'bibliographic_fields', ! 'author_separators'] *************** *** 53,54 **** --- 54,73 ---- 'abstract': 'Abstract'} """Mapping of bibliographic node class name to label text.""" + + bibliographic_fields = { + 'author': nodes.author, + 'authors': nodes.authors, + 'organization': nodes.organization, + 'contact': nodes.contact, + 'version': nodes.version, + 'revision': nodes.revision, + 'status': nodes.status, + 'date': nodes.date, + 'copyright': nodes.copyright, + 'abstract': nodes.abstract} + """Field name (lowcased) to node class name mapping for bibliographic fields + (field_list).""" + + author_separators = [';', ','] + """List of separator strings for the 'Authors' bibliographic field. Tried in + order.""" |
From: David G. <go...@us...> - 2002-01-16 02:48:02
|
Update of /cvsroot/docstring/dps/dps In directory usw-pr-cvs1:/tmp/cvs-serv28232/dps/dps Modified Files: nodes.py Log Message: - 'errorhandler' -> 'reporter'. - Added document.languagecode. Index: nodes.py =================================================================== RCS file: /cvsroot/docstring/dps/dps/nodes.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** nodes.py 2001/11/22 04:11:44 1.20 --- nodes.py 2002/01/16 02:47:59 1.21 *************** *** 341,346 **** class document(Root, Element): ! def __init__(self, errorhandler, *args, **kwargs): Element.__init__(self, *args, **kwargs) self.explicittargets = {} self.implicittargets = {} --- 341,348 ---- class document(Root, Element): ! def __init__(self, reporter, languagecode, *args, **kwargs): Element.__init__(self, *args, **kwargs) + self.reporter = reporter + self.languagecode = languagecode self.explicittargets = {} self.implicittargets = {} *************** *** 354,358 **** self.autofootnotes = [] self.autofootnoterefs = [] - self.errorhandler = errorhandler def asdom(self, dom=xml.dom.minidom): --- 356,359 ---- *************** *** 367,371 **** or self.externaltargets.has_key(name) \ or self.implicittargets.has_key(name): ! sw = self.errorhandler.information( 'Duplicate implicit target name: "%s"' % name) innode += sw --- 368,372 ---- or self.externaltargets.has_key(name) \ or self.implicittargets.has_key(name): ! sw = self.reporter.information( 'Duplicate implicit target name: "%s"' % name) innode += sw *************** *** 381,385 **** innode = targetnode if self.explicittargets.has_key(name): ! sw = self.errorhandler.warning( 'Duplicate explicit target name: "%s"' % name) innode += sw --- 382,386 ---- innode = targetnode if self.explicittargets.has_key(name): ! sw = self.reporter.warning( 'Duplicate explicit target name: "%s"' % name) innode += sw *************** *** 390,394 **** return elif self.implicittargets.has_key(name): ! sw = self.errorhandler.information( 'Duplicate implicit target name: "%s"' % name) innode += sw --- 391,395 ---- return elif self.implicittargets.has_key(name): ! sw = self.reporter.information( 'Duplicate implicit target name: "%s"' % name) innode += sw *************** *** 414,418 **** level = 1 break ! sw = self.errorhandler.system_warning( level, 'Duplicate external target name: "%s"' % name) innode += sw --- 415,419 ---- level = 1 break ! sw = self.reporter.system_warning( level, 'Duplicate external target name: "%s"' % name) innode += sw *************** *** 420,424 **** self.externaltargets, self.implicittargets) elif self.implicittargets.has_key(name): ! sw = self.errorhandler.information( 'Duplicate implicit target name: "%s"' % name) innode += sw --- 421,425 ---- self.externaltargets, self.implicittargets) elif self.implicittargets.has_key(name): ! sw = self.reporter.information( 'Duplicate implicit target name: "%s"' % name) innode += sw *************** *** 451,455 **** def addsubstitutiondef(self, name, substitutiondefnode, innode): if self.substitutiondefs.has_key(name): ! sw = self.errorhandler.error( 'Duplicate substitution definition name: "%s"' % name) innode += sw --- 452,456 ---- def addsubstitutiondef(self, name, substitutiondefnode, innode): if self.substitutiondefs.has_key(name): ! sw = self.reporter.error( 'Duplicate substitution definition name: "%s"' % name) innode += sw |
From: David G. <go...@us...> - 2002-01-16 02:45:25
|
Update of /cvsroot/docstring/dps/dps In directory usw-pr-cvs1:/tmp/cvs-serv27722/dps/dps Modified Files: utils.py Log Message: - Moved `normname()` from restructuredtext/states.py. Index: utils.py =================================================================== RCS file: /cvsroot/docstring/dps/dps/utils.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** utils.py 2001/11/22 04:10:50 1.9 --- utils.py 2002/01/16 02:45:22 1.10 *************** *** 173,174 **** --- 173,178 ---- attributes[name] = convertor(value) # raises ValueError if invalud return attributes + + def normname(name): + """Return a case- and whitespace-normalized name.""" + return ' '.join(name.lower().split()) |
From: David G. <go...@us...> - 2002-01-16 02:43:52
|
Update of /cvsroot/docstring/dps In directory usw-pr-cvs1:/tmp/cvs-serv27369/dps Modified Files: setup.py Log Message: updated Index: setup.py =================================================================== RCS file: /cvsroot/docstring/dps/setup.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** setup.py 2001/08/23 03:53:54 1.3 --- setup.py 2002/01/16 02:43:49 1.4 *************** *** 13,17 **** author_email = 'go...@us...', license = 'public domain', ! packages = ['dps', 'dps.parsers', 'dps.formatters', 'dps.languages']) return dist --- 13,18 ---- author_email = 'go...@us...', license = 'public domain', ! packages = ['dps', 'dps.readers', 'dps.parsers', ! 'dps.writers', 'dps.transforms', 'dps.languages']) return dist |
From: David G. <go...@us...> - 2002-01-16 02:43:24
|
Update of /cvsroot/docstring/dps/spec In directory usw-pr-cvs1:/tmp/cvs-serv27293/dps/spec Modified Files: dps-notes.txt Log Message: updated Index: dps-notes.txt =================================================================== RCS file: /cvsroot/docstring/dps/spec/dps-notes.txt,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** dps-notes.txt 2001/11/06 02:10:13 1.17 --- dps-notes.txt 2002/01/16 02:43:21 1.18 *************** *** 44,49 **** - Add validation? See http://pytrex.sourceforge.net, RELAX NG. ! - Incorporate "modes", using Tony Ibbs' 2001-08-03 Doc-SIG post ! 'Suggestions for reST "modes"' as a base. - Write modules for common transformations, such as: --- 44,49 ---- - Add validation? See http://pytrex.sourceforge.net, RELAX NG. ! - Incorporate readers/"input modes", using Tony Ibbs' 2001-08-03 ! Doc-SIG post 'Suggestions for reST "modes"' as a base. - Write modules for common transformations, such as: |
From: David G. <go...@us...> - 2002-01-16 02:43:15
|
Update of /cvsroot/docstring/dps/spec In directory usw-pr-cvs1:/tmp/cvs-serv27260/dps/spec Modified Files: doctree.txt Log Message: updated Index: doctree.txt =================================================================== RCS file: /cvsroot/docstring/dps/spec/doctree.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** doctree.txt 2001/11/19 04:01:39 1.6 --- doctree.txt 2002/01/16 02:43:13 1.7 *************** *** 122,126 **** - ``autofootnotes`` - ``autofootnoterefs`` ! - ``errorhandler`` --- 122,126 ---- - ``autofootnotes`` - ``autofootnoterefs`` ! - ``reporter`` |
From: David G. <go...@us...> - 2002-01-16 02:42:08
|
Update of /cvsroot/docstring/dps/test In directory usw-pr-cvs1:/tmp/cvs-serv27085/dps/test Modified Files: DPSTestSupport.py Log Message: support for transform tests Index: DPSTestSupport.py =================================================================== RCS file: /cvsroot/docstring/dps/test/DPSTestSupport.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** DPSTestSupport.py 2001/09/17 04:04:07 1.1 --- DPSTestSupport.py 2002/01/16 02:42:06 1.2 *************** *** 10,20 **** :Modules: ! Try to import modules from the current working copy of dps ! first, or from the installed version. In test modules, import these modules ! from here: - `statemachine` is 'dps.statemachine' - `nodes` is 'dps.nodes' - `utils` is 'dps.utils' """ __docformat__ = 'reStructuredText' --- 10,22 ---- :Modules: ! Try to import modules from the current working copy of dps first, ! or from the installed version. In test modules, import these ! modules from here: - `statemachine` is 'dps.statemachine' - `nodes` is 'dps.nodes' + - `urischemes` is 'dps.urischemes' - `utils` is 'dps.utils' + - `transforms` is 'dps.transforms' """ __docformat__ = 'reStructuredText' *************** *** 29,36 **** import dps # or restructuredtext on path? ! from dps import statemachine, nodes, utils try: import mypdb as pdb except: import pdb --- 31,229 ---- import dps # or restructuredtext on path? ! from dps import statemachine, nodes, urischemes, utils, transforms + import unittest, difflib, inspect, os, sys + try: import mypdb as pdb except: import pdb + + + class CustomTestSuite(unittest.TestSuite): + + """ + A collection of custom TestCases. + + """ + + id = '' + """Identifier for the TestSuite. Prepended to the + TestCase identifiers to make identification easier.""" + + nextTestCaseId = 0 + """The next identifier to use for non-identified test cases.""" + + def __init__(self, tests=(), id=None): + """ + Initialize the CustomTestSuite. + + Arguments: + + id -- identifier for the suite, prepended to test cases. + """ + unittest.TestSuite.__init__(self, tests) + if id is None: + outerframes = inspect.getouterframes(inspect.currentframe()) + mypath = outerframes[0][1] + callerpath = outerframes[1][1] + mydir, myname = os.path.split(mypath) + if not mydir: + mydir = os.curdir + if callerpath.startswith(mydir): + self.id = callerpath[len(mydir) + 1:] # caller's module + else: + self.id = callerpath + else: + self.id = id + + + def addTestCase(self, testCaseClass, methodName, input, expected, + id=None, runInDebugger=0, shortDescription=None, + **kwargs): + """ + Create a custom TestCase in the CustomTestSuite. + Also return it, just in case. + + Arguments: + + testCaseClass -- + methodName -- + input -- input to the parser. + expected -- expected output from the parser. + id -- unique test identifier, used by the test framework. + runInDebugger -- if true, run this test under the pdb debugger. + shortDescription -- override to default test description. + """ + if id is None: # generate id if required + id = self.nextTestCaseId + self.nextTestCaseId += 1 + # test identifier will become suiteid.testid + tcid = '%s: %s' % (self.id, id) + # generate and add test case + tc = testCaseClass(methodName, input, expected, tcid, + runInDebugger=runInDebugger, + shortDescription=shortDescription, + **kwargs) + self.addTest(tc) + return tc + + + class CustomTestCase(unittest.TestCase): + + compare = difflib.Differ().compare + """Comparison method shared by all subclasses.""" + + def __init__(self, methodName, input, expected, id, + runInDebugger=0, shortDescription=None): + """ + Initialise the CustomTestCase. + + Arguments: + + methodName -- name of test method to run. + input -- input to the parser. + expected -- expected output from the parser. + id -- unique test identifier, used by the test framework. + runInDebugger -- if true, run this test under the pdb debugger. + shortDescription -- override to default test description. + """ + self.id = id + self.input = input + self.expected = expected + self.runInDebugger = runInDebugger + # Ring your mother. + unittest.TestCase.__init__(self, methodName) + + def __str__(self): + """ + Return string conversion. Overridden to give test id, in addition to + method name. + """ + return '%s; %s' % (self.id, unittest.TestCase.__str__(self)) + + def compareOutput(self, input, output, expected): + """`input`, `output`, and `expected` should all be strings.""" + try: + self.assertEquals('\n' + output, '\n' + expected) + except AssertionError: + print >>sys.stderr, '\n%s\ninput:' % (self,) + print >>sys.stderr, input + print >>sys.stderr, '-: expected\n+: output' + print >>sys.stderr, ''.join(self.compare(expected.splitlines(1), + output.splitlines(1))) + raise + + + class TransformTestSuite(CustomTestSuite): + + """ + A collection of TransformTestCases. + + A TransformTestSuite instance manufactures TransformTestCases, + keeps track of them, and provides a shared test fixture (a-la + setUp and tearDown). + """ + + def __init__(self, parser): + self.parser = parser + """Parser shared by all test cases.""" + + CustomTestSuite.__init__(self) + + def generateTests(self, dict, dictname='totest'): + """ + Stock the suite with test cases generated from a test data dictionary. + + Each dictionary key (test type's name) maps to a list of transform + classes and list of tests. Each test is a list: input, expected + output, optional modifier. The optional third entry, a behavior + modifier, can be 0 (temporarily disable this test) or 1 (run this test + under the pdb debugger). Tests should be self-documenting and not + require external comments. + """ + for name, (transforms, cases) in dict.items(): + for casenum in range(len(cases)): + case = cases[casenum] + runInDebugger = 0 + if len(case)==3: + if case[2]: + runInDebugger = 1 + else: + continue + self.addTestCase( + TransformTestCase, 'test_transforms', + transforms=transforms, parser=self.parser, + input=case[0], expected=case[1], + id='%s[%r][%s]' % (dictname, name, casenum), + runInDebugger=runInDebugger) + + + class TransformTestCase(CustomTestCase): + + """ + Output checker for the transform. + + Should probably be called TransformOutputChecker, but I can deal with + that later when/if someone comes up with a category of transform test + cases that have nothing to do with the input and output of the transform. + """ + + def __init__(self, *args, **kwargs): + self.transforms = kwargs['transforms'] + """List of transforms to perform for this test case.""" + + self.parser = kwargs['parser'] + """Input parser for this test case.""" + + del kwargs['transforms'], kwargs['parser'] # only wanted here + CustomTestCase.__init__(self, *args, **kwargs) + + def test_transforms(self): + if self.runInDebugger: + pdb.set_trace() + doctree = self.parser.parse(self.input) + for transformClass in self.transforms: + transformClass().transform(doctree) + output = doctree.pformat() + self.compareOutput(self.input, output, self.expected) |