Class: Plum::DraftDiff

Inherits:
Object
  • Object
show all
Defined in:
app/services/plum/draft_diff.rb

Overview

Field-by-field comparison between an entry's live content and its working draft, tokenized for git-style rendering (equal / deleted / inserted segments). Rich text is compared as readable text, structured fields as pretty-printed JSON.

Defined Under Namespace

Classes: FieldChange

Constant Summary collapse

TOKEN_LIMIT =

Beyond this many differing tokens, fall back to a wholesale replaced-block diff instead of an O(n*m) LCS table.

1500

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(entry) ⇒ DraftDiff

Returns a new instance of DraftDiff.



13
14
15
16
# File 'app/services/plum/draft_diff.rb', line 13

def initialize(entry)
  @entry = entry
  @content_type = entry.content_type
end

Class Method Details

.word_diff(old_text, new_text) ⇒ Object

Word-level diff as [[op, text], ...] with op in :eq/:del/:ins. Whitespace is kept as tokens so spacing survives reconstruction.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'app/services/plum/draft_diff.rb', line 28

def self.word_diff(old_text, new_text)
  a = tokenize(old_text)
  b = tokenize(new_text)

  prefix = common_prefix_length(a, b)
  suffix = common_suffix_length(a, b, prefix)
  middle_a = a[prefix...(a.length - suffix)]
  middle_b = b[prefix...(b.length - suffix)]

  segments = []
  segments << [ :eq, a.first(prefix).join ] if prefix.positive?
  segments.concat(diff_middle(middle_a, middle_b))
  segments << [ :eq, a.last(suffix).join ] if suffix.positive?
  merge_segments(segments)
end

Instance Method Details

#any?Boolean

Returns:

  • (Boolean)


22
23
24
# File 'app/services/plum/draft_diff.rb', line 22

def any?
  changes.any?
end

#changesObject



18
19
20
# File 'app/services/plum/draft_diff.rb', line 18

def changes
  @changes ||= build_changes
end