Index: DiffEngine.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/diff/DiffEngine.php,v
retrieving revision 1.1.4.1
diff -U3 -r1.1.4.1 DiffEngine.php
--- DiffEngine.php	6 Jun 2007 18:14:25 -0000	1.1.4.1
+++ DiffEngine.php	7 Dec 2007 22:02:10 -0000
@@ -1119,3 +1119,137 @@
 		}
 	}
 }
+
+/**
+ * Diff formatter which uses Drupal theme functions.
+ * @private
+ * @subpackage DifferenceEngine
+ */
+class DrupalDiffFormatter extends DiffFormatter
+{
+
+  var $rows;
+
+  function DrupalDiffFormatter() {
+    $this->leading_context_lines = 2;
+    $this->trailing_context_lines = 2;
+  }
+
+  function _start_diff() {
+    $this->rows = array();
+  }
+
+  function _end_diff() {
+    return $this->rows;
+  }
+
+  function _block_header( $xbeg, $xlen, $ybeg, $ylen ) {
+    return array(
+      array(
+        'data' => '<strong>' . t('Line %nr', array('%nr' => $xbeg)) . '</strong>',
+        'colspan' => 2
+      ),
+      array(
+        'data' => '<strong>' . t('Line %nr', array('%nr' => $ybeg)) . '</strong>',
+        'colspan' => 2
+      )
+    );
+  }
+
+  function _start_block( $header ) {
+    if ($this->show_header) {
+      $this->rows[] = $header;
+    }
+  }
+
+  function _end_block() {
+  }
+
+  function _lines( $lines, $prefix=' ', $color='white' ) {
+  }
+
+  /**
+   * Note: you should HTML-escape parameter before calling this.
+   */
+  function addedLine($line) {
+    return array(
+      array(
+        'data' => '+',
+      ),
+      array(
+        'data' => $line,
+        'class' => 'diff-addedline'
+      )
+    );
+  }
+
+  /**
+   * Note: you should HTML-escape parameter before calling this.
+   */
+  function deletedLine($line) {
+    return array(
+      array(
+        'data' => '-',
+      ),
+      array(
+        'data' => $line,
+        'class' => 'diff-deletedline',
+      )
+    );
+  }
+
+  /**
+   * Note: you should HTML-escape parameter before calling this.
+   */
+  function contextLine($line) {
+    return array(
+      '&nbsp;',
+      array(
+        'data' => $line,
+        'class' => 'diff-context',
+      )
+    );
+  }
+
+  function emptyLine() {
+    return array(
+      '&nbsp;',
+      '&nbsp;'
+    );
+  }
+
+  function _added($lines) {
+    foreach($lines as $line) {
+      $this->rows[] = array_merge($this->emptyLine(), $this->addedLine(check_plain($line)));
+    }
+  }
+
+  function _deleted($lines) {
+    foreach($lines as $line) {
+      $this->rows[] = array_merge($this->deletedLine(check_plain ($line)), $this->emptyLine());
+    }
+  }
+
+  function _context($lines) {
+    foreach($lines as $line) {
+      $this->rows[] = array_merge($this->contextLine(check_plain ($line)), $this->contextLine(check_plain($line)));
+    }
+  }
+
+  function _changed($orig, $closing) {
+    $diff = new WordLevelDiff($orig, $closing);
+    $del = $diff->orig();
+    $add = $diff->closing();
+
+    // Notice that WordLevelDiff returns HTML-escaped output.
+    // Hence, we will be calling addedLine/deletedLine without HTML-escaping.
+
+    while ($line = array_shift($del)) {
+      $aline = array_shift( $add );
+      $this->rows[] = array_merge($this->deletedLine($line), $this->addedLine($aline));
+    }
+    foreach ($add as $line) {  // If any leftovers
+      $this->rows[] = array_merge($this->emptyLine(), $this->addedLine($line));
+    }
+  }
+}
Index: diff.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/diff/diff.css,v
retrieving revision 1.2.2.3
diff -U3 -r1.2.2.3 diff.css
--- diff.css	31 Jan 2007 18:05:55 -0000	1.2.2.3
+++ diff.css	7 Dec 2007 22:02:10 -0000
@@ -4,6 +4,10 @@
   width: 100%;
   margin-bottom: 20px;
 }
+table.diff tr.even, table.diff tr.odd {
+  background-color: inherit;
+  border: none;
+}
 td.diff-prevlink {
   text-align: left;
 }
Index: diff.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/diff/diff.module,v
retrieving revision 1.8.2.8
diff -U3 -r1.8.2.8 diff.module
--- diff.module	6 Jun 2007 18:14:25 -0000	1.8.2.8
+++ diff.module	7 Dec 2007 22:02:10 -0000
@@ -320,16 +320,43 @@
     $prev_link = '';
   }
 
-  // display table
-  $output .= '<table class="diff">';
-  $output .= '<thead><tr><th></th><th>'. $old_header .'</th><th></th><th>'. $new_header .'</th></tr></thead>';
-  if ($new_log || $old_log) {
-    $output .= '<tr><td></td><td>'. $old_log .'</td><td></td><td>'. $new_log .'</td></tr>';
-  }
-  $output .= '<tr><td></td><td class="diff-prevlink">'. $prev_link .'</td><td></td><td class="diff-nextlink">'. $next_link .'</td></tr>';
-  $output .= _diff_table_body($old_node, $new_node);
-  $output .= '</table>';
-  $output .= '<hr/>';
+  $header = array(
+    array(
+      'data' => $old_header,
+      'colspan' => 2
+    ),
+    array(
+      'data' => $new_header,
+      'colspan' => 2
+    )
+  );
+  $rows = array();
+  if ($old_log || $new_log) {
+    $rows[] = array(
+      array(
+        'data' => $old_log,
+        'colspan' => 2
+      ),
+      array(
+        'data' => $new_log,
+        'colspan' => 2
+      )
+    );
+  }
+  $rows[] = array(
+    array(
+      'data' => $prev_link,
+      'class' => 'diff-prevlink',
+      'colspan' => 2
+    ),
+    array(
+      'data' => $next_link,
+      'class' => 'diff-nextlink',
+      'colspan' => 2
+    )
+  );
+  $rows = array_merge($rows, _diff_body_rows($old_node, $new_node));
+  $output = theme('table', $header, $rows, array('class' => 'diff'));
 
   if ($node->vid == $new_vid) {
     $output .= '<div class="diff-section-title">'. t('Current revision:') .'</div>';
@@ -343,13 +370,21 @@
 }
 
 /**
- * Create the table body of the diff between $old_node and $new_node.
- * The result is a html table part enclosed in <tbody> tags.
+ * Creates an array of rows which represent a diff between $old_node and $new_node.
+ * The rows can be used via theme('table') to be displayed.
+ *
+ * @param $old_node
+ *   Node for comparison which will be displayed on the left side.
+ * @param $new_node
+ *   Node for comparison which will be displayed on the right side.
  */
-function _diff_table_body(&$old_node, &$new_node) {
+function _diff_body_rows(&$old_node, &$new_node) {
   drupal_add_css(drupal_get_path('module', 'diff') .'/diff.css', 'module', 'all', FALSE);
   include_once('DiffEngine.php');
   include_once('node.inc');
+  if (module_exists('taxonomy')) {
+    include_once('taxonomy.inc');
+  }
   if (module_exists('upload')) {
     include_once('upload.inc');
   }
@@ -357,27 +392,38 @@
     include_once('cck.inc');
   }
 
-  $output = '<tbody>';
+  $rows = array();
   $any_visible_change = false;
   $node_diffs = module_invoke_all('diff', $old_node, $new_node);
   foreach($node_diffs as $node_diff) {
     $diff = new Diff($node_diff['old'], $node_diff['new']);
-    $formatter = new TableDiffFormatter();
+    $formatter = new DrupalDiffFormatter();
     if (isset($node_diff['format'])) {
       $formatter->show_header = $node_diff['format']['show_header'];
     }
-    $formatter_output = $formatter->format($diff);
-    if ($formatter_output) {
-      $output .= '<tr><td colspan="4" class="diff-section-title">'. t('Changes to %name', array('%name' => $node_diff['name'])) .'</td></tr>';
-      $output .= $formatter_output;
+    $diff_rows = $formatter->format($diff);
+    if (count($diff_rows)) {
+      $rows[] = array(
+        array(
+          'data' => t('Changes to %name', array('%name' => $node_diff['name'])),
+          'class' => 'diff-section-title',
+          'colspan' => 4
+        )
+      );
+      $rows = array_merge($rows, $diff_rows);
       $any_visible_change = true;
     }
   }
   if (!$any_visible_change) {
-    $output .= '<tr><td colspan="4" class="diff-section-title">' .t('No visible changes') .'</td></tr>';
+    $rows[] = array(
+      array(
+        'data' => t('No visible changes'),
+        'class' => 'diff-section-title',
+        'colspan' => 4
+      )
+    );
   }
-  $output .= '</tbody>';
-  return $output;
+  return $rows;
 }
 
 /**
@@ -477,10 +523,12 @@
 
   $op = isset($form_values['op']) ? $form_values['op'] : '';
   if ($op == t('Preview changes')) {
+    // Diff module excpects node as object, thus $form_values is cast to an object.
     $node = (object)$form_values;
-    $changes  = '<table class="diff">';
-    $changes .= _diff_table_body(node_load($form_values['nid']), $node);
-    $changes .= '</table>';
+    // Create diff of old node and edited node
+    $rows = _diff_body_rows(node_load($form_values['nid']), $node);
+    $changes = theme('table', array(), $rows, array('class' => 'diff'));
+    // Prepend diff to edit form
     $form['#prefix'] = isset($form['#prefix']) ? $changes . $form['#prefix'] : $changes;
     return $form;
   }
