/mod/wiki/inline-diff/Text/Diff/Renderer/inline.php

https://github.com/jarednipper/HSU-common-code · PHP · 155 lines · 84 code · 27 blank · 44 comment · 11 complexity · a76e3188b541c3d564d0aac7a1a6c8d9 MD5 · raw file

  1. <?php
  2. require_once 'Text/Diff/Renderer.php';
  3. /**
  4. * "Inline" diff renderer.
  5. *
  6. * This class renders diffs in the Wiki-style "inline" format.
  7. *
  8. * $Horde: framework/Text_Diff/Diff/Renderer/inline.php,v 1.16 2006/01/08 00:06:57 jan Exp $
  9. *
  10. * @author Ciprian Popovici
  11. * @package Text_Diff
  12. */
  13. class Text_Diff_Renderer_inline extends Text_Diff_Renderer {
  14. /**
  15. * Number of leading context "lines" to preserve.
  16. */
  17. var $_leading_context_lines = 10000;
  18. /**
  19. * Number of trailing context "lines" to preserve.
  20. */
  21. var $_trailing_context_lines = 10000;
  22. /**
  23. * Prefix for inserted text.
  24. */
  25. var $_ins_prefix = '<ins>';
  26. /**
  27. * Suffix for inserted text.
  28. */
  29. var $_ins_suffix = '</ins>';
  30. /**
  31. * Prefix for deleted text.
  32. */
  33. var $_del_prefix = '<del>';
  34. /**
  35. * Suffix for deleted text.
  36. */
  37. var $_del_suffix = '</del>';
  38. /**
  39. * Header for each change block.
  40. */
  41. var $_block_header = '';
  42. /**
  43. * What are we currently splitting on? Used to recurse to show word-level
  44. * changes.
  45. */
  46. var $_split_level = 'lines';
  47. function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
  48. {
  49. return $this->_block_header;
  50. }
  51. function _startBlock($header)
  52. {
  53. return $header;
  54. }
  55. function _lines($lines, $prefix = ' ', $encode = true)
  56. {
  57. if ($encode) {
  58. array_walk($lines, array(&$this, '_encode'));
  59. }
  60. if ($this->_split_level == 'words') {
  61. return implode('', $lines);
  62. } else {
  63. return implode("\n", $lines) . "\n";
  64. }
  65. }
  66. function _added($lines)
  67. {
  68. array_walk($lines, array(&$this, '_encode'));
  69. $lines[0] = $this->_ins_prefix . $lines[0];
  70. $lines[count($lines) - 1] .= $this->_ins_suffix;
  71. return $this->_lines($lines, ' ', false);
  72. }
  73. function _deleted($lines, $words = false)
  74. {
  75. array_walk($lines, array(&$this, '_encode'));
  76. $lines[0] = $this->_del_prefix . $lines[0];
  77. $lines[count($lines) - 1] .= $this->_del_suffix;
  78. return $this->_lines($lines, ' ', false);
  79. }
  80. function _changed($orig, $final)
  81. {
  82. /* If we've already split on words, don't try to do so again - just
  83. * display. */
  84. if ($this->_split_level == 'words') {
  85. $prefix = '';
  86. while ($orig[0] !== false && $final[0] !== false &&
  87. substr($orig[0], 0, 1) == ' ' &&
  88. substr($final[0], 0, 1) == ' ') {
  89. $prefix .= substr($orig[0], 0, 1);
  90. $orig[0] = substr($orig[0], 1);
  91. $final[0] = substr($final[0], 1);
  92. }
  93. return $prefix . $this->_deleted($orig) . $this->_added($final);
  94. }
  95. $text1 = implode("\n", $orig);
  96. $text2 = implode("\n", $final);
  97. /* Non-printing newline marker. */
  98. $nl = "\0";
  99. /* We want to split on word boundaries, but we need to
  100. * preserve whitespace as well. Therefore we split on words,
  101. * but include all blocks of whitespace in the wordlist. */
  102. $diff = &new Text_Diff($this->_splitOnWords($text1, $nl),
  103. $this->_splitOnWords($text2, $nl));
  104. /* Get the diff in inline format. */
  105. $renderer = &new Text_Diff_Renderer_inline(array_merge($this->getParams(),
  106. array('split_level' => 'words')));
  107. /* Run the diff and get the output. */
  108. return str_replace($nl, "\n", $renderer->render($diff)) . "\n";
  109. }
  110. function _splitOnWords($string, $newlineEscape = "\n")
  111. {
  112. $words = array();
  113. $length = strlen($string);
  114. $pos = 0;
  115. while ($pos < $length) {
  116. // Eat a word with any preceding whitespace.
  117. $spaces = strspn(substr($string, $pos), " \n");
  118. $nextpos = strcspn(substr($string, $pos + $spaces), " \n");
  119. $words[] = str_replace("\n", $newlineEscape, substr($string, $pos, $spaces + $nextpos));
  120. $pos += $spaces + $nextpos;
  121. }
  122. return $words;
  123. }
  124. function _encode(&$string)
  125. {
  126. $string = htmlspecialchars($string);
  127. }
  128. }