From: <go...@us...> - 2002-05-05 14:49:13
|
Update of /cvsroot/docutils/docutils/docutils In directory usw-pr-cvs1:/tmp/cvs-serv16102/docutils/docutils Modified Files: nodes.py Log Message: - Added ``TreeCopyVisitor`` class. - Added a ``copy`` method to ``Node`` and subclasses. - Added a ``SkipDeparture`` exception for visitors. Index: nodes.py =================================================================== RCS file: /cvsroot/docutils/docutils/docutils/nodes.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** nodes.py 20 Apr 2002 03:03:04 -0000 1.1.1.1 --- nodes.py 5 May 2002 14:49:10 -0000 1.2 *************** *** 17,21 **** element generic identifiers in the DTD_. ! .. _DTD: http://docstring.sourceforge.net/spec/gpdi.dtd """ --- 17,21 ---- element generic identifiers in the DTD_. ! .. _DTD: http://docutils.sourceforge.net/spec/docutils.dtd """ *************** *** 51,54 **** --- 51,58 ---- raise NotImplementedError + def copy(self): + """Return a copy of self.""" + raise NotImplementedError + def walk(self, visitor): """ *************** *** 66,79 **** name = 'visit_' + self.__class__.__name__ method = getattr(visitor, name, visitor.unknown_visit) ! visitor.doctree.reporter.debug(name, category='nodes.Node.walk') try: method(self) - children = self.getchildren() - try: - for i in range(len(children)): - children[i].walk(visitor) - except SkipSiblings: - pass except (SkipChildren, SkipNode): pass --- 70,85 ---- name = 'visit_' + self.__class__.__name__ method = getattr(visitor, name, visitor.unknown_visit) ! visitor.document.reporter.debug(name, category='nodes.Node.walk') try: method(self) except (SkipChildren, SkipNode): + return + except SkipDeparture: # not applicable; ignore + pass + children = self.getchildren() + try: + for i in range(len(children)): + children[i].walk(visitor) + except SkipSiblings: pass *************** *** 88,96 **** and ``depart_...`` methods for each `Node` subclass encountered. """ name = 'visit_' + self.__class__.__name__ method = getattr(visitor, name, visitor.unknown_visit) ! visitor.doctree.reporter.debug(name, category='nodes.Node.walkabout') try: ! method(self) children = self.getchildren() try: --- 94,108 ---- and ``depart_...`` methods for each `Node` subclass encountered. """ + call_depart = 1 name = 'visit_' + self.__class__.__name__ method = getattr(visitor, name, visitor.unknown_visit) ! visitor.document.reporter.debug(name, category='nodes.Node.walkabout') try: ! try: ! method(self) ! except SkipNode: ! return ! except SkipDeparture: ! call_depart = 0 children = self.getchildren() try: *************** *** 101,110 **** except SkipChildren: pass ! except SkipNode: ! return ! name = 'depart_' + self.__class__.__name__ ! method = getattr(visitor, name, visitor.unknown_departure) ! visitor.doctree.reporter.debug(name, category='nodes.Node.walkabout') ! method(self) --- 113,122 ---- except SkipChildren: pass ! if call_depart: ! name = 'depart_' + self.__class__.__name__ ! method = getattr(visitor, name, visitor.unknown_departure) ! visitor.document.reporter.debug( ! name, category='nodes.Node.walkabout') ! method(self) *************** *** 134,137 **** --- 146,152 ---- return self.data + def copy(self): + return self.__class__(self.data) + def pformat(self, indent=' ', level=0): result = [] *************** *** 187,191 **** """List of child nodes (elements and/or `Text`).""" ! self.extend(children) # extend self.children w/ attributes self.attributes = {} --- 202,206 ---- """List of child nodes (elements and/or `Text`).""" ! self.extend(children) # maintain parent info self.attributes = {} *************** *** 426,429 **** --- 441,447 ---- return self.children + def copy(self): + return self.__class__(**self.attributes) + class TextElement(Element): *************** *** 490,498 **** class Special(Body): ! """Special internal body elements, not true document components.""" pass ! class Component: pass class Inline: pass --- 508,516 ---- class Special(Body): ! """Special internal body elements.""" pass ! class Part: pass class Inline: pass *************** *** 514,518 **** class document(Root, Structural, Element): ! def __init__(self, reporter, languagecode, *args, **kwargs): Element.__init__(self, *args, **kwargs) --- 532,536 ---- class document(Root, Structural, Element): ! def __init__(self, reporter, language_code, *args, **kwargs): Element.__init__(self, *args, **kwargs) *************** *** 520,524 **** """System message generator.""" ! self.languagecode = languagecode """ISO 639 2-letter language identifier.""" --- 538,542 ---- """System message generator.""" ! self.language_code = language_code """ISO 639 2-letter language identifier.""" *************** *** 764,767 **** --- 782,789 ---- self.pending.append(pending) + def copy(self): + return self.__class__(self.reporter, self.language_code, + **self.attributes) + # ================ *************** *** 821,843 **** class bullet_list(Sequential, Element): pass class enumerated_list(Sequential, Element): pass ! class list_item(Component, Element): pass class definition_list(Sequential, Element): pass ! class definition_list_item(Component, Element): pass ! class term(Component, TextElement): pass ! class classifier(Component, TextElement): pass ! class definition(Component, Element): pass class field_list(Sequential, Element): pass ! class field(Component, Element): pass ! class field_name(Component, TextElement): pass ! class field_argument(Component, TextElement): pass ! class field_body(Component, Element): pass ! class option(Component, Element): child_text_separator = '' ! class option_argument(Component, TextElement): def astext(self): --- 843,865 ---- class bullet_list(Sequential, Element): pass class enumerated_list(Sequential, Element): pass ! class list_item(Part, Element): pass class definition_list(Sequential, Element): pass ! class definition_list_item(Part, Element): pass ! class term(Part, TextElement): pass ! class classifier(Part, TextElement): pass ! class definition(Part, Element): pass class field_list(Sequential, Element): pass ! class field(Part, Element): pass ! class field_name(Part, TextElement): pass ! class field_argument(Part, TextElement): pass ! class field_body(Part, Element): pass ! class option(Part, Element): child_text_separator = '' ! class option_argument(Part, TextElement): def astext(self): *************** *** 845,849 **** ! class option_group(Component, Element): child_text_separator = ', ' --- 867,871 ---- ! class option_group(Part, Element): child_text_separator = ', ' *************** *** 853,863 **** ! class option_list_item(Component, Element): child_text_separator = ' ' ! class option_string(Component, TextElement): pass ! class description(Component, Element): pass class literal_block(General, TextElement): pass class block_quote(General, Element): pass --- 875,885 ---- ! class option_list_item(Part, Element): child_text_separator = ' ' ! class option_string(Part, TextElement): pass ! class description(Part, Element): pass class literal_block(General, TextElement): pass class block_quote(General, Element): pass *************** *** 877,891 **** class footnote(General, Element, BackLinkable): pass class citation(General, Element, BackLinkable): pass ! class label(Component, TextElement): pass class figure(General, Element): pass ! class caption(Component, TextElement): pass ! class legend(Component, Element): pass class table(General, Element): pass ! class tgroup(Component, Element): pass ! class colspec(Component, Element): pass ! class thead(Component, Element): pass ! class tbody(Component, Element): pass ! class row(Component, Element): pass ! class entry(Component, Element): pass --- 899,913 ---- class footnote(General, Element, BackLinkable): pass class citation(General, Element, BackLinkable): pass ! class label(Part, TextElement): pass class figure(General, Element): pass ! class caption(Part, TextElement): pass ! class legend(Part, Element): pass class table(General, Element): pass ! class tgroup(Part, Element): pass ! class colspec(Part, Element): pass ! class thead(Part, Element): pass ! class tbody(Part, Element): pass ! class row(Part, Element): pass ! class entry(Part, Element): pass *************** *** 957,960 **** --- 979,988 ---- internals.extend(['%9s%s' % ('', line) for line in value.pformat().splitlines()]) + elif value and type(value) == ListType \ + and isinstance(value[0], Node): + internals.append('%7s%s:' % ('', key)) + for v in value: + internals.extend(['%9s%s' % ('', line) + for line in v.pformat().splitlines()]) else: internals.append('%7s%s: %r' % ('', key, value)) *************** *** 963,966 **** --- 991,998 ---- for line in internals])) + def copy(self): + return self.__class__(self.transform, self.stage, self.details, + **self.attributes) + class raw(Special, Inline, PreBibliographic, TextElement): *************** *** 992,996 **** return self.get('alt', '') ! class problematic(Inline, TextElement): pass --- 1024,1028 ---- return self.get('alt', '') ! class problematic(Inline, TextElement): pass *************** *** 1044,1049 **** """ ! def __init__(self, doctree): ! self.doctree = doctree def unknown_visit(self, node): --- 1076,1081 ---- """ ! def __init__(self, document): ! self.document = document def unknown_visit(self, node): *************** *** 1079,1088 **** Unless overridden, each ``visit_...`` method calls `default_visit()`, and each ``depart_...`` method (when using `Node.walkabout()`) calls ! `default_departure()`. `default_visit()` (`default_departure()`) must be ! overridden in subclasses. ! Define fully generic visitors by overriding `default_visit()` ! (`default_departure()`) only. Define semi-generic visitors by overriding ! individual ``visit_...()`` (``depart_...()``) methods also. `NodeVisitor.unknown_visit()` (`NodeVisitor.unknown_departure()`) should --- 1111,1120 ---- Unless overridden, each ``visit_...`` method calls `default_visit()`, and each ``depart_...`` method (when using `Node.walkabout()`) calls ! `default_departure()`. `default_visit()` (and `default_departure()`) must ! be overridden in subclasses. ! Define fully generic visitors by overriding `default_visit()` (and ! `default_departure()`) only. Define semi-generic visitors by overriding ! individual ``visit_...()`` (and ``depart_...()``) methods also. `NodeVisitor.unknown_visit()` (`NodeVisitor.unknown_departure()`) should *************** *** 1111,1112 **** --- 1143,1169 ---- class SkipSiblings(VisitorException): pass class SkipNode(VisitorException): pass + class SkipDeparture(VisitorException): pass + + + class TreeCopyVisitor(GenericNodeVisitor): + + """ + Make a complete copy of a tree or branch, including element attributes. + """ + + def __init__(self, document): + GenericNodeVisitor.__init__(self, document) + self.parent_stack = [[]] + + def get_tree_copy(self): + return self.parent_stack[0][0] + + def default_visit(self, node): + """""" + newnode = node.copy() + self.parent_stack[-1].append(newnode) + self.parent_stack.append(newnode) + + def default_departure(self, node): + """""" + self.parent_stack.pop() |