diff --git a/inc/DifferenceEngine.php b/inc/DifferenceEngine.php
index 1b68cf6d3ad990aa8541260b93b5476c77d3e226..e0fbf8e030fdef502eb12379c8fa84340c9e3399 100644
--- a/inc/DifferenceEngine.php
+++ b/inc/DifferenceEngine.php
@@ -797,7 +797,7 @@ class DiffFormatter {
 
     function _lines($lines, $prefix = ' ') {
         foreach ($lines as $line)
-            echo "$prefix $line\n";
+            echo "$prefix ".$this->_escape($line)."\n";
     }
 
     function _context($lines) {
@@ -816,6 +816,10 @@ class DiffFormatter {
         echo "---\n";
         $this->_added($closing);
     }
+
+    function _escape($str){
+        return $str;
+    }
 }
 
 /**
@@ -871,13 +875,13 @@ class _HWLDF_WordAccumulator {
     function _flushGroup($new_tag) {
         if ($this->_group !== '') {
             if ($this->_tag == 'mark')
-                $this->_line .= '<strong '.HTMLDiff::css('diff-mark').'>'.$this->_group.'</strong>';
+                $this->_line .= '<strong '.HTMLDiff::css('diff-mark').'>'.$this->_escape($this->_group).'</strong>';
             elseif ($this->_tag == 'add')
-                $this->_line .= '<span '.HTMLDiff::css('diff-addedline').'>'.$this->_group.'</span>';
+                $this->_line .= '<span '.HTMLDiff::css('diff-addedline').'>'.$this->_escape($this->_group).'</span>';
             elseif ($this->_tag == 'del')
-                $this->_line .= '<span '.HTMLDiff::css('diff-deletedline').'><del>'.$this->_group.'</del></span>';
+                $this->_line .= '<span '.HTMLDiff::css('diff-deletedline').'><del>'.$this->_escape($this->_group).'</del></span>';
             else
-                $this->_line .= $this->_group;
+                $this->_line .= $this->_escape($this->_group);
         }
         $this->_group = '';
         $this->_tag = $new_tag;
@@ -912,6 +916,10 @@ class _HWLDF_WordAccumulator {
         $this->_flushLine('~done');
         return $this->_lines;
     }
+
+    function _escape($str){
+        return hsc($str);
+    }
 }
 
 class WordLevelDiff extends MappedDiff {
@@ -1029,6 +1037,7 @@ class UnifiedDiffFormatter extends DiffFormatter {
  *
  */
 class TableDiffFormatter extends DiffFormatter {
+    var $colspan = 2;
 
     function __construct() {
         $this->leading_context_lines = 2;
@@ -1053,8 +1062,8 @@ class TableDiffFormatter extends DiffFormatter {
         global $lang;
         $l1 = $lang['line'].' '.$xbeg;
         $l2 = $lang['line'].' '.$ybeg;
-        $r = '<tr><td '.HTMLDiff::css('diff-blockheader').' colspan="2">'.$l1.":</td>\n".
-             '<td '.HTMLDiff::css('diff-blockheader').' colspan="2">'.$l2.":</td>\n".
+        $r = '<tr><td '.HTMLDiff::css('diff-blockheader').' colspan="'.$this->colspan.'">'.$l1.":</td>\n".
+             '<td '.HTMLDiff::css('diff-blockheader').' colspan="'.$this->colspan.'">'.$l2.":</td>\n".
              "</tr>\n";
         return $r;
     }
@@ -1069,25 +1078,38 @@ class TableDiffFormatter extends DiffFormatter {
     function _lines($lines, $prefix=' ', $color="white") {
     }
 
-    function addedLine($line) {
-        return '<td>+</td><td '.HTMLDiff::css('diff-addedline').'>' .  $line.'</td>';
+    function addedLine($line,$escaped=false) {
+        if (!$escaped){
+            $line = $this->_escape($line);
+        }
+        return '<td '.HTMLDiff::css('diff-lineheader').'>+</td>'.
+               '<td '.HTMLDiff::css('diff-addedline').'>' .  $line.'</td>';
     }
 
-    function deletedLine($line) {
-        return '<td>-</td><td '.HTMLDiff::css('diff-deletedline').'>' .  $line.'</td>';
+    function deletedLine($line,$escaped=false) {
+        if (!$escaped){
+            $line = $this->_escape($line);
+        }
+        return '<td '.HTMLDiff::css('diff-lineheader').'>-</td>'.
+               '<td '.HTMLDiff::css('diff-deletedline').'>' .  $line.'</td>';
     }
 
     function emptyLine() {
-        return '<td colspan="2">&#160;</td>';
+        return '<td colspan="'.$this->colspan.'">&#160;</td>';
     }
 
     function contextLine($line) {
-        return '<td> </td><td '.HTMLDiff::css('diff-context').'>'.$line.'</td>';
+        return '<td '.HTMLDiff::css('diff-lineheader').'>&#160;</td>'.
+               '<td '.HTMLDiff::css('diff-context').'>'.$this->_escape($line).'</td>';
     }
 
     function _added($lines) {
+        $this->_addedLines($lines,false);
+    }
+
+    function _addedLines($lines,$escaped=false){
         foreach ($lines as $line) {
-            print('<tr>' . $this->emptyLine() . $this->addedLine($line) . "</tr>\n");
+            print('<tr>' . $this->emptyLine() . $this->addedLine($line,$escaped) . "</tr>\n");
         }
     }
 
@@ -1104,15 +1126,19 @@ class TableDiffFormatter extends DiffFormatter {
     }
 
     function _changed($orig, $closing) {
-        $diff = new WordLevelDiff($orig, $closing);
+        $diff = new WordLevelDiff($orig, $closing);  // this escapes the diff data
         $del = $diff->orig();
         $add = $diff->closing();
 
         while ($line = array_shift($del)) {
             $aline = array_shift($add);
-            print('<tr>' . $this->deletedLine($line) . $this->addedLine($aline) . "</tr>\n");
+            print('<tr>' . $this->deletedLine($line,true) . $this->addedLine($aline,true) . "</tr>\n");
         }
-        $this->_added($add); # If any leftovers
+        $this->_addedLines($add,true); # If any leftovers
+    }
+
+    function _escape($str) {
+        return hsc($str);
     }
 }
 
@@ -1121,7 +1147,7 @@ class TableDiffFormatter extends DiffFormatter {
  *
  */
 class InlineDiffFormatter extends DiffFormatter {
-    var $colspan = 4;
+    var $colspan = 2;
 
     function __construct() {
         $this->leading_context_lines = 2;
@@ -1167,28 +1193,32 @@ class InlineDiffFormatter extends DiffFormatter {
 
     function _added($lines) {
         foreach ($lines as $line) {
-            print('<tr><td colspan="'.$this->colspan.'" '.HTMLDiff::css('diff-addedline').'>'. $line . "</td></tr>\n");
+            print('<tr><td '.HTMLDiff::css('diff-lineheader').'>&#160;</td><td '.HTMLDiff::css('diff-addedline').'>'. $this->_escape($line) . "</td></tr>\n");
         }
     }
 
     function _deleted($lines) {
         foreach ($lines as $line) {
-            print('<tr><td colspan="'.$this->colspan.'" '.HTMLDiff::css('diff-deletedline').'><del>' . $line . "</del></td></tr>\n");
+            print('<tr><td '.HTMLDiff::css('diff-lineheader').'>&#160;</td><td '.HTMLDiff::css('diff-deletedline').'><del>' . $this->_escape($line) . "</del></td></tr>\n");
         }
     }
 
     function _context($lines) {
         foreach ($lines as $line) {
-            print('<tr><td colspan="'.$this->colspan.'" '.HTMLDiff::css('diff-context').'>'.$line."</td></tr>\n");
+            print('<tr><td '.HTMLDiff::css('diff-lineheader').'>&#160;</td><td '.HTMLDiff::css('diff-context').'>'. $this->_escape($line) ."</td></tr>\n");
         }
     }
 
     function _changed($orig, $closing) {
-        $diff = new InlineWordLevelDiff($orig, $closing);
+        $diff = new InlineWordLevelDiff($orig, $closing);  // this escapes the diff data
         $add = $diff->inline();
 
         foreach ($add as $line)
-            print('<tr><td colspan="'.$this->colspan.'">'.$line."</td></tr>\n");
+            print('<tr><td '.HTMLDiff::css('diff-lineheader').'>&#160;</td><td>'.$line."</td></tr>\n");
+    }
+
+    function _escape($str) {
+        return hsc($str);
     }
 }
 
diff --git a/inc/html.php b/inc/html.php
index c2723bcebda5db93d873f7e42fea83cb97eb1600..59415f7da0e602f3fb1cd3dde04fe4b4e9ccf4a6 100644
--- a/inc/html.php
+++ b/inc/html.php
@@ -1003,14 +1003,16 @@ function html_backlinks(){
  * @param string $r_rev   Right revision
  * @param string $id      Page id, if null $ID is used
  * @param bool   $media   If it is for media files
+ * @param bool   $inline  Return the header on a single line
  * @return array HTML snippets for diff header
  */
-function html_diff_head($l_rev, $r_rev, $id = null, $media = false) {
+function html_diff_head($l_rev, $r_rev, $id = null, $media = false, $inline = false) {
     global $lang;
     if ($id === null) {
         global $ID;
         $id = $ID;
     }
+    $head_separator = $inline ? ' ' : '<br />';
     $media_or_wikiFN = $media ? 'mediaFN' : 'wikiFN';
     $ml_or_wl = $media ? 'ml' : 'wl';
     $l_minor = $r_minor = '';
@@ -1032,7 +1034,7 @@ function html_diff_head($l_rev, $r_rev, $id = null, $media = false) {
         $l_head_title = ($media) ? dformat($l_rev) : $id.' ['.dformat($l_rev).']';
         $l_head = '<a class="wikilink1" href="'.$ml_or_wl($id,"rev=$l_rev").'">'.
         $l_head_title.'</a>'.
-        '<br />'.$l_user.' '.$l_sum;
+        $head_separator.$l_user.' '.$l_sum;
     }
 
     if($r_rev){
@@ -1050,7 +1052,7 @@ function html_diff_head($l_rev, $r_rev, $id = null, $media = false) {
         $r_head_title = ($media) ? dformat($r_rev) : $id.' ['.dformat($r_rev).']';
         $r_head = '<a class="wikilink1" href="'.$ml_or_wl($id,"rev=$r_rev").'">'.
         $r_head_title.'</a>'.
-        '<br />'.$r_user.' '.$r_sum;
+        $head_separator.$r_user.' '.$r_sum;
     }elseif($_rev = @filemtime($media_or_wikiFN($id))){
         $_info   = getRevisionInfo($id,$_rev,true, $media);
         if($_info['user']){
@@ -1067,7 +1069,7 @@ function html_diff_head($l_rev, $r_rev, $id = null, $media = false) {
         $r_head  = '<a class="wikilink1" href="'.$ml_or_wl($id).'">'.
         $r_head_title.'</a> '.
         '('.$lang['current'].')'.
-        '<br />'.$_user.' '.$_sum;
+        $head_separator.$_user.' '.$_sum;
     }else{
         $r_head = '&mdash; ('.$lang['current'].')';
     }
@@ -1160,10 +1162,10 @@ function html_diff($text='',$intro=true,$type=null){
         }
         $r_text = rawWiki($ID,$r_rev);
 
-        list($l_head, $r_head, $l_minor, $r_minor) = html_diff_head($l_rev, $r_rev);
+        list($l_head, $r_head, $l_minor, $r_minor) = html_diff_head($l_rev, $r_rev, null, false, $type == 'inline');
     }
 
-    $df = new Diff(explode("\n",hsc($l_text)),explode("\n",hsc($r_text)));
+    $df = new Diff(explode("\n",$l_text),explode("\n",$r_text));
 
     if($type == 'inline'){
         $tdf = new InlineDiffFormatter();
@@ -1205,6 +1207,18 @@ function html_diff($text='',$intro=true,$type=null){
     ?>
     <div class="table">
     <table class="diff diff_<?php echo $type?>">
+    <?php if ($type == 'inline') { ?>
+    <tr>
+    <th class="diff-lineheader">-</th><th <?php echo $l_minor?>>
+    <?php echo $l_head?>
+    </th>
+    </tr>
+    <tr>
+    <th class="diff-lineheader">+</th><th <?php echo $r_minor?>>
+    <?php echo $r_head?>
+    </th>
+    </tr>
+    <?php } else { ?>
     <tr>
     <th colspan="2" <?php echo $l_minor?>>
     <?php echo $l_head?>
@@ -1213,7 +1227,8 @@ function html_diff($text='',$intro=true,$type=null){
     <?php echo $r_head?>
     </th>
     </tr>
-    <?php echo html_insert_softbreaks($tdf->format($df)); ?>
+    <?php }
+    echo html_insert_softbreaks($tdf->format($df)); ?>
     </table>
     </div>
     <?php
@@ -1238,8 +1253,8 @@ function html_softbreak_callback($match){
 &\#?\\w{1,6};)                        # ... for html entities - we don't want to split them (ok to catch some invalid combinations)
 &\#?\\w{1,6};                         # yes pattern - a quicker match for the html entity, since we know we have one
 |
-[?/,&\#;:]+                           # no pattern - any other group of 'special' characters to insert a breaking character after
-)                                     # end conditional expression
+[?/,&\#;:]                            # no pattern - any other group of 'special' characters to insert a breaking character after
+)+                                    # end conditional expression
 REGEX;
 
   return preg_replace('<'.$regex.'>xu','\0&#8203;',$match[0]);
diff --git a/lib/tpl/default/design.css b/lib/tpl/default/design.css
index 3405ec258355b0b0411afd5c5d035b744292493d..4772fd2a5ec1e583c60a555a12b56528dea11434 100644
--- a/lib/tpl/default/design.css
+++ b/lib/tpl/default/design.css
@@ -632,7 +632,6 @@ div.dokuwiki td.diff-blockheader {
 div.dokuwiki table.diff th {
   border-bottom: 1px solid __border__;
   font-size: 110%;
-  width: 50%;
   font-weight: normal;
   text-align: left;
 }
@@ -650,6 +649,17 @@ div.dokuwiki table.diff th span.sum {
 div.dokuwiki table.diff th.minor {
   font-style: italic;
 }
+.dokuwiki table.diff_sidebyside th {
+    width: 50%;
+}
+.dokuwiki table.diff .diff-lineheader {
+    width: .7em;
+    text-align: right;
+}
+[dir=rtl] .dokuwiki table.diff .diff-lineheader {
+    text-align: left;
+}
+.dokuwiki table.diff .diff-lineheader,
 div.dokuwiki table.diff td {
   font-family: monospace;
   font-size: 100%;
diff --git a/lib/tpl/dokuwiki/css/_diff.css b/lib/tpl/dokuwiki/css/_diff.css
index 62f8312133d602be4d6154018b37670e30cf9b80..58c24b5c79b840595350f6cff7f62ae99b40ca59 100644
--- a/lib/tpl/dokuwiki/css/_diff.css
+++ b/lib/tpl/dokuwiki/css/_diff.css
@@ -21,7 +21,6 @@
 .dokuwiki table.diff th {
     border-bottom: 1px solid __border__;
     font-size: 110%;
-    width: 50%;
     font-weight: normal;
 }
 .dokuwiki table.diff th a {
@@ -37,8 +36,19 @@
 .dokuwiki table.diff th.minor {
     color: #999;
 }
+.dokuwiki table.diff_sidebyside th {
+    width: 50%;
+}
 
 /* table body */
+.dokuwiki table.diff .diff-lineheader {
+    width: .7em;
+    text-align: right;
+}
+[dir=rtl] .dokuwiki table.diff .diff-lineheader {
+    text-align: left;
+}
+.dokuwiki table.diff .diff-lineheader,
 .dokuwiki table.diff td {
     font-family: Consolas, "Andale Mono WT", "Andale Mono", "Bitstream Vera Sans Mono", "Nimbus Mono L", Monaco, "Courier New", monospace;
 }