Class: Websitary::Htmldiff
- Inherits:
-
Object
- Object
- Websitary::Htmldiff
- Defined in:
- lib/websitary/htmldiff.rb
Overview
A simple class to generate diffs for html files using hpricot. It’s quite likely that it will miss certain details and yields wrong results (especially wrong-negative) in certain occasions.
Constant Summary collapse
- VERSION =
'0.1'- REVISION =
'164'
Instance Method Summary collapse
-
#diff ⇒ Object
Do the diff.
-
#explode(node) ⇒ Object
Collect all nodes and subnodes in a hpricot document.
- #highlight(child) ⇒ Object
-
#initialize(args) ⇒ Htmldiff
constructor
- args
- A hash Fields: :oldtext
- The old version :newtext
- The new version :highlight
- Don’t strip old content but highlight new one with this color :args
-
Command-line arguments.
-
#process(node = @new) ⇒ Object
It goes like this: if a node isn’t in the list of old nodes either the node or its content has changed.
- #replace_inner(child, ihtml) ⇒ Object
Constructor Details
#initialize(args) ⇒ Htmldiff
- args
-
A hash
Fields:
- :oldtext
-
The old version
- :newtext
-
The new version
- :highlight
-
Don’t strip old content but highlight new one with this color
- :args
-
Command-line arguments
28 29 30 31 32 33 34 |
# File 'lib/websitary/htmldiff.rb', line 28 def initialize(args) @args = args @high = args[:highlight] || args[:highlightcolor] @old = explode(args[:olddoc] || Hpricot(args[:oldtext] || File.read(args[:oldfile]))) @new = args[:newdoc] || Hpricot(args[:newtext] || File.read(args[:newfile])) @changed = false end |
Instance Method Details
#diff ⇒ Object
Do the diff. Return an empty string if nothing has changed.
38 39 40 41 |
# File 'lib/websitary/htmldiff.rb', line 38 def diff rv = process.to_s @changed ? rv : '' end |
#explode(node) ⇒ Object
Collect all nodes and subnodes in a hpricot document.
71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/websitary/htmldiff.rb', line 71 def explode(node) if node.respond_to?(:each_child) acc = [node.to_html.strip] node.each_child do |child| acc += explode(child) end acc else [node.to_html.strip] end end |
#highlight(child) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/websitary/htmldiff.rb', line 84 def highlight(child) @changed = true if @high if child.respond_to?(:each_child) acc = [] child.each_child do |ch| acc << replace_inner(ch, highlight(ch).to_s) end replace_inner(child, acc.join("\n")) else case @args[:highlight] when String opts = %{class="#{@args[:highlight]}"} when true, Numeric opts = %{class="highlight"} else opts = %{style="background-color: #{@args[:highlightcolor]};"} end ihtml = %{<span #{opts}>#{child.to_s}</span>} replace_inner(child, ihtml) end else child end end |
#process(node = @new) ⇒ Object
It goes like this: if a node isn’t in the list of old nodes either the node or its content has changed. If the content is a single node, the whole node has changed. If only some sub-nodes have changed, collect those.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/websitary/htmldiff.rb', line 48 def process(node=@new) acc = [] node.each_child do |child| ch = child.to_html.strip next if ch.nil? or ch.empty? if @old.include?(ch) if @high acc << child end else if child.respond_to?(:each_child) acc << process(child) else acc << highlight(child).to_s acc << '<br />' unless @high end end end replace_inner(node, acc.join("\n")) end |
#replace_inner(child, ihtml) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/websitary/htmldiff.rb', line 111 def replace_inner(child, ihtml) case child when Hpricot::Comment child when Hpricot::Text Hpricot(ihtml) else child.inner_html = ihtml child end end |