WordLevelDiff.php 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. <?php
  2. namespace Drupal\Component\Diff;
  3. use Drupal\Component\Diff\Engine\HWLDFWordAccumulator;
  4. /**
  5. * @todo document
  6. * @private
  7. * @subpackage DifferenceEngine
  8. */
  9. class WordLevelDiff extends MappedDiff {
  10. const MAX_LINE_LENGTH = 10000;
  11. public function __construct($orig_lines, $closing_lines) {
  12. list($orig_words, $orig_stripped) = $this->_split($orig_lines);
  13. list($closing_words, $closing_stripped) = $this->_split($closing_lines);
  14. parent::__construct($orig_words, $closing_words, $orig_stripped, $closing_stripped);
  15. }
  16. protected function _split($lines) {
  17. $words = [];
  18. $stripped = [];
  19. $first = TRUE;
  20. foreach ($lines as $line) {
  21. // If the line is too long, just pretend the entire line is one big word
  22. // This prevents resource exhaustion problems
  23. if ( $first ) {
  24. $first = FALSE;
  25. }
  26. else {
  27. $words[] = "\n";
  28. $stripped[] = "\n";
  29. }
  30. if (mb_strlen($line) > $this::MAX_LINE_LENGTH) {
  31. $words[] = $line;
  32. $stripped[] = $line;
  33. }
  34. else {
  35. if (preg_match_all('/ ( [^\S\n]+ | [0-9_A-Za-z\x80-\xff]+ | . ) (?: (?!< \n) [^\S\n])? /xs', $line, $m)) {
  36. $words = array_merge($words, $m[0]);
  37. $stripped = array_merge($stripped, $m[1]);
  38. }
  39. }
  40. }
  41. return [$words, $stripped];
  42. }
  43. public function orig() {
  44. $orig = new HWLDFWordAccumulator();
  45. foreach ($this->edits as $edit) {
  46. if ($edit->type == 'copy') {
  47. $orig->addWords($edit->orig);
  48. }
  49. elseif ($edit->orig) {
  50. $orig->addWords($edit->orig, 'mark');
  51. }
  52. }
  53. $lines = $orig->getLines();
  54. return $lines;
  55. }
  56. public function closing() {
  57. $closing = new HWLDFWordAccumulator();
  58. foreach ($this->edits as $edit) {
  59. if ($edit->type == 'copy') {
  60. $closing->addWords($edit->closing);
  61. }
  62. elseif ($edit->closing) {
  63. $closing->addWords($edit->closing, 'mark');
  64. }
  65. }
  66. $lines = $closing->getLines();
  67. return $lines;
  68. }
  69. }