diff options
author | smerten <smerten@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> | 2010-08-01 17:53:06 +0000 |
---|---|---|
committer | smerten <smerten@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> | 2010-08-01 17:53:06 +0000 |
commit | 896a1b33f87b8f37e527d79aa8763b6c434d7ea7 (patch) | |
tree | 59906f1a6b24b3a9d70a9cd8fcaf13050fd3bb31 /sandbox/rstdiff/rstdiff.py | |
parent | d53f1e26e35b5c39efd391aaead5afe9f9b0e656 (diff) | |
download | docutils-896a1b33f87b8f37e527d79aa8763b6c434d7ea7.tar.gz |
Added many tests and todos. One test doesn't run yet.
Empty inlines are not generated.
Necessary attributes are considered.
Elements which may contain only #PCDATA propagate their inner changes
up to the element itself.
git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk@6382 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
Diffstat (limited to 'sandbox/rstdiff/rstdiff.py')
-rwxr-xr-x | sandbox/rstdiff/rstdiff.py | 167 |
1 files changed, 165 insertions, 2 deletions
diff --git a/sandbox/rstdiff/rstdiff.py b/sandbox/rstdiff/rstdiff.py index 6866d332f..835d33ada 100755 --- a/sandbox/rstdiff/rstdiff.py +++ b/sandbox/rstdiff/rstdiff.py @@ -337,10 +337,10 @@ class DocutilsDispatcher(HashableNodeImpl): % ( name, ", ".join([ arg.__class__.__name__ for arg in ( node, ) + args ]), )) for arg in ( node, ) + args: - print(" %s" % ( arg, )) + print(" > %s" % ( arg, )) result = method(node, *args) if self.debug: - print(" %s" % ( result, )) + print(" < %s" % ( result, )) return result ########################################################################### @@ -407,6 +407,7 @@ class DocutilsDispatcher(HashableNodeImpl): ########################################################################### # Merging + # TODO The resulting class names should be configurable NewDelete = 'removed' NewInsert = 'added' NewReplaced = 'replaced' @@ -546,6 +547,9 @@ class DocutilsDispatcher(HashableNodeImpl): childEq_White = rootEq_White def copyChildren_Text(self, head, tail, root, newType): + if not tail and isinstance(head, nodes.Text) and not head.astext(): + # Do not create empty inlines + return [ ] inline = nodes.inline() self.setNewType(inline, newType) inline.extend([ head, ] + tail) @@ -555,6 +559,163 @@ class DocutilsDispatcher(HashableNodeImpl): copyChildren_Word = copyChildren_Text copyChildren_White = copyChildren_Text + ########################################################################### + # For some elements their attributes need to be considered to + # detect changes. + + def attributeEq(self, node, other, attribute): + if (attribute in node) != (attribute in other): + return False + if not attribute in node: + return True + return node[attribute] == other[attribute] + + ########################################################################### + # reference + + def rootEq_reference(self, node, other): + return self.attributeEq(node, other, 'refuri') + + ########################################################################### + # target + + def rootEq_target(self, node, other): + return self.attributeEq(node, other, 'refuri') + + ########################################################################### + # bullet_list + + # TODO This is typically a minor change and should be requested by + # a special option + + def attributeEq_bullet_list(self, node, other): + return self.attributeEq(node, other, 'bullet') + + def rootEq_bullet_list(self, node, other): + return self.attributeEq_bullet_list(node, other) + + def childEq_bullet_list(self, node, other): + return (self.attributeEq_bullet_list(node, other) + and self.childrenEq(node, other)) + + ########################################################################### + # enumerated_list + + # TODO This is typically a minor change and should be requested by + # a special option + + def attributeEq_enumerated_list(self, node, other): + return (self.attributeEq(node, other, 'enumtype') + and self.attributeEq(node, other, 'prefix') + and self.attributeEq(node, other, 'suffix') + and self.attributeEq(node, other, 'start')) + + def rootEq_enumerated_list(self, node, other): + return self.attributeEq_enumerated_list(node, other) + + def childEq_option_argument(self, node, other): + return (self.attributeEq_enumerated_list(node, other) + and self.childrenEq(node, other)) + + ########################################################################### + # image + + def rootEq_image(self, node, other): + if node.__class__ != other.__class__: + return False + return self.attributeEq(node, other, 'uri') + + ########################################################################### + # Some elements may contain only #PCDATA. They need to propagate + # changes in their children up to the element itself. + + def rootEqWithChildren(self, node, other): + if node.__class__ != other.__class__: + return False + return self.childrenEq(node, other) + + ########################################################################### + # comment + + rootEq_comment = rootEqWithChildren + + ########################################################################### + # literal + + rootEq_literal = rootEqWithChildren + + ########################################################################### + # option_string + + rootEq_option_string = rootEqWithChildren + + ########################################################################### + # label + + # TODO This is typically a minor change and should be requested by + # a special option + + rootEq_label = rootEqWithChildren + + ########################################################################### + # footnote_reference + + # TODO This is typically a minor change and should be requested by + # a special option + + rootEq_footnote_reference = rootEqWithChildren + + ########################################################################### + # citation_reference + + # TODO This is typically a minor change and should be requested by + # a special option + + rootEq_citation_reference = rootEqWithChildren + + ########################################################################### + # For some elements their attributes need to be considered to + # detect changes *and* they may contain only #PCDATA. + + ########################################################################### + # option_argument + + # TODO This is typically a minor change and should be requested by + # a special option + + def attributeEq_option_argument(self, node, other): + return self.attributeEq(node, other, 'delimiter') + + def rootEq_option_argument(self, node, other): + return (self.attributeEq_option_argument(node, other) + and self.rootEqWithChildren(node, other)) + + def childEq_option_argument(self, node, other): + return (self.attributeEq_option_argument(node, other) + and self.childrenEq(node, other)) + + ########################################################################### + + # TODO A change in certain elements must propagate the change up + # or down since they may occur only once. These elements are + # <title> (down), <subtitle> (down), <decoration> (down), + # <docinfo> (down), <transition>, <header> (down), <footer> + # (down), <info>, <term> (down), <definition> (down), <field_name> + # (down), <field_body> (down), <option_group> (down), + # <description> (down), <option_string> (up), <attribution> + # (down), <label> (up), <caption> (down), <legend> (down), + # <thead>, <tbody>, <entry> (down) (because otherwise the column + # count is wrong) + # + # However, only those need to be considered which may have + # replacing changes at all. Typically not the case for container + # elements. + + # TODO Why are changes in text are propagated up? For instance + # <entry><paragraph>+</paragraph></entry> => + # <entry><paragraph>++</paragraph></entry> becomes a change in the + # <entry>! + ############################################################################### ############################################################################### # Main @@ -709,3 +870,5 @@ if __name__ == '__main__': pub.writer.write(diffDoc, pub.destination) pub.writer.assemble_parts() + +# TODO The CSS classes need to be set in a CSS stylesheet |