This patch makes diff creation a function of Page, instead of having it hardcoded in do_diff.
Mostly created for FeatureRequests/DiffUnsavedChanges, although it might also be useful in other contexts.
# HG changeset patch # User johannes@sipsolutions.net # Node ID 8e9cde09becae14ac999773a92014a8a93380723 # Parent 95a2991fb76cd8ba71ccb41e84a010fded342efe This patch makes diff creation a function of Page, instead of having it hardcoded in do_diff. Mostly created for FeatureRequests/DiffUnsavedChanges, although it might also be useful in other contexts. diff -r 95a2991fb76c -r 8e9cde09beca MoinMoin/Page.py --- a/MoinMoin/Page.py Wed Jul 19 23:58:06 2006 +0200 +++ b/MoinMoin/Page.py Wed Jul 19 23:31:41 2006 +0100 @@ -951,6 +951,60 @@ class Page: self.request.write(text) raise MoinMoinNoFooter + + def send_diff(self, old_lines, difftitle, **kw): + """ Output a diff between the current page and the given lines + + @param old_lines: old lines to diff against + @param difftitle: title for the diff + @keyword content_id: set the id of the enclosing div + @keyword edit_count: number of times the page had been edited between old_lines and now + @keyword rev1, rev2: old and new revision + @keyword ignorews: ignore whitespace + @keyword show_ignorews_link: show link to diff ignoring whitespace + """ + content_id = kw.get('content_id', "content") + rev1 = kw.get('rev1', None) + rev2 = kw.get('rev2', None) + edit_count = kw.get('edit_count', 1) + show_ignws_link = kw.get('show_ignorews_link', False) + ignorews = kw.get('ignorews', False) + _ = self.request.getText + + self.request.write(self.request.formatter.startContent(content_id)) + self.request.write('<p class="diff-header">') + self.request.write(difftitle) + self.request.write('</p>') + + if self.request.user.show_fancy_diff: + from MoinMoin.util.diff import diff + self.request.write(diff(self.request, '\n'.join(old_lines), self.get_raw_body())) + self.send_page(self.request, count_hit=0, content_only=1, content_id="content-below-diff") + else: + lines = wikiutil.linediff(old_lines, self.getlines()) + if not lines: + msg = _("No differences found!") + if edit_count > 1: + msg = msg + '<p>' + _('The page was saved %(count)d times, though!') % { + 'count': edit_count} + self.request.write(msg) + else: + if ignorews: + self.request.write(_('(ignoring whitespace)') + '<br>') + elif show_ignws_link: + qstr = 'action=diff&ignorews=1' + if rev1: qstr = '%s&rev1=%s' % (qstr, rev1) + if rev2: qstr = '%s&rev2=%s' % (qstr, rev2) + self.request.write(Page(self.request, self.page_name).link_to(self.request, + text=_('Ignore changes in the amount of whitespace'), + querystr=qstr) + '<p>') + + self.request.write(self.request.formatter.preformatted(True)) + for line in lines: + if line[0] == "@": + self.request.write(self.request.formatter.rule()) + self.request.write(wikiutil.escape(line)+'\n') + self.request.write(self.request.formatter.preformatted(False)) def send_page(self, request, msg=None, **keywords): """ Output the formatted page. diff -r 95a2991fb76c -r 8e9cde09beca MoinMoin/wikiaction.py --- a/MoinMoin/wikiaction.py Wed Jul 19 23:58:06 2006 +0200 +++ b/MoinMoin/wikiaction.py Wed Jul 19 23:31:41 2006 +0100 @@ -159,44 +159,19 @@ def do_diff(pagename, request): edit_count = abs(oldcount1 - oldcount2) # this should use the formatter, but there is none? - request.write('<div id="content">\n') # start content div - request.write('<p class="diff-header">') - request.write(_('Differences between revisions %d and %d') % (oldpage.get_real_rev(), newpage.get_real_rev())) + title = _('Differences between revisions %d and %d') % (oldpage.get_real_rev(), newpage.get_real_rev()) if edit_count > 1: - request.write(' ' + _('(spanning %d versions)') % (edit_count,)) - request.write('</p>') - - if request.user.show_fancy_diff: - from MoinMoin.util.diff import diff - request.write(diff(request, oldpage.get_raw_body(), newpage.get_raw_body())) - newpage.send_page(request, count_hit=0, content_only=1, content_id="content-below-diff") - else: - lines = wikiutil.linediff(oldpage.getlines(), newpage.getlines()) - if not lines: - msg = _("No differences found!") - if edit_count > 1: - msg = msg + '<p>' + _('The page was saved %(count)d times, though!') % { - 'count': edit_count} - request.write(msg) - else: - if ignorews: - request.write(_('(ignoring whitespace)') + '<br>') - else: - qstr = 'action=diff&ignorews=1' - if rev1: qstr = '%s&rev1=%s' % (qstr, rev1) - if rev2: qstr = '%s&rev2=%s' % (qstr, rev2) - request.write(Page(request, pagename).link_to(request, - text=_('Ignore changes in the amount of whitespace'), - querystr=qstr) + '<p>') - - request.write('<pre>') - for line in lines: - if line[0] == "@": - request.write('<hr>') - request.write(wikiutil.escape(line)+'\n') - request.write('</pre>') - - request.write('</div>\n') # end content div + title += ' ' + _('(spanning %d versions)') % (edit_count,) + newpage.send_diff(oldpage.getlines(), + title, + show_ignorews_link = True, + ignorews = ignorews, + rev1 = rev1, + rev2 = rev2, + edit_count = edit_count) + + request.write(request.formatter.endContent()) + wikiutil.send_footer(request, pagename)
-- JohannesBerg 2005-10-12 13:10:10
Moving the code from the action makes sense, because other code may like to do a diff of two page revisions, or maybe just a diff between too strings. but Page is already too big to add more code. Maybe create a DiffView object or function that may be use by other code.
Ok, that function is essentially standalone, it'll just need a page and request object passed in additionally and then it can be dropped into a new module. Do you think passing the old string and a new page object is fine? -- JohannesBerg 2005-10-12 14:19:33
- Why not passing two strings? in the page editor case, you will create a diff with the new text and the old page text. In other cases, maybe diff with page a text against page b text.
It is time to fix the html creation - the current code breaks the output abstraction, so if you try to use foo formatter to render the diff, you will have raw html in your foo format. This was smaller problem in an action that can use other format, but as a page or generic diff view, it should work with any formatter.
I agree, but that requires changes in the formatter API. -- JohannesBerg 2005-10-12 14:19:33
Yea, that missing div api again
I propose to shift that refactoring to 2.0 branch or we will have the work twice.
The problem of this refactoring idea is neither HTML output nor the large Page.py file -- it is the fact that the page object should not handle HTML at all (and that previous attempts in this direction are wrong). If this method generated a unified diff or another abstract format, it would be ok. But like this, it is not really usable. -- AlexanderSchremmer 2005-10-16 17:36:15