Module: HypDiff

Defined in:
lib/hyp_diff.rb,
lib/hyp_diff/version.rb,
lib/hyp_diff/text_from_node.rb

Class Method Summary collapse

Class Method Details

.compare(before, after, options = {}) ⇒ String

Compare two html snippets.

Parameters:

  • before (String)

    the first html snippet

  • after (String)

    the second html snippet

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :render_insertion (Proc)

    provide a callback to render insertions. The callback will receive the inserted text as a html snippet. It should return a new html snippet that will be used in the output. If no callback is given, ‘<ins>`-Tags will be used to highlight insertions.

  • :render_deletion (Proc)

    provide a callback to render deletions. The callback will receive the deleted text as a html snippet. It should return a new html snippet that will be used in the output. If no callback is given, ‘<del>`-Tags will be used to highlight deletions.

  • :markup_from (String)

    specify if the markup from ‘before` or `after` should be used as the basis for the output. Possible values: “before” and “after”. Default: “after”

Returns:

  • (String)

    a new html snippet that highlights changes between ‘before` and `after`



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/hyp_diff.rb', line 17

def compare(before, after, options = {})
  parsed_after = parse(after)
  parsed_before = parse(before)

  text_changes = Diff::LCS.sdiff(extract_text(parsed_before), extract_text(parsed_after))

  markup_from_before = options[:markup_from] == "before"

  change_node_tuples = text_changes.map do |change|
    text_from_node = markup_from_before ? change.old_element : change.new_element
    [change, text_from_node && text_from_node.node]
  end

  render_deletion = options[:render_deletion] || proc { |html| "<del>#{html}</del>" }
  render_insertion = options[:render_insertion] || proc { |html| "<ins>#{html}</ins>" }

  NodeMap.for(change_node_tuples).each do |node, changes|
    node.replace(ChangeRenderer.render(changes, render_deletion, render_insertion))
  end

  modified_fragment = markup_from_before ? parsed_before : parsed_after
  modified_fragment.to_html
end