html_slicer 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -0
- data/CHANGELOG +16 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +336 -0
- data/Rakefile +1 -0
- data/app/views/html_slicer/_first_slice.html.erb +10 -0
- data/app/views/html_slicer/_first_slice.html.haml +8 -0
- data/app/views/html_slicer/_first_slice.html.slim +9 -0
- data/app/views/html_slicer/_gap.html.erb +7 -0
- data/app/views/html_slicer/_gap.html.haml +7 -0
- data/app/views/html_slicer/_gap.html.slim +8 -0
- data/app/views/html_slicer/_last_slice.html.erb +10 -0
- data/app/views/html_slicer/_last_slice.html.haml +8 -0
- data/app/views/html_slicer/_last_slice.html.slim +9 -0
- data/app/views/html_slicer/_next_slice.html.erb +10 -0
- data/app/views/html_slicer/_next_slice.html.haml +8 -0
- data/app/views/html_slicer/_next_slice.html.slim +9 -0
- data/app/views/html_slicer/_prev_slice.html.erb +10 -0
- data/app/views/html_slicer/_prev_slice.html.haml +8 -0
- data/app/views/html_slicer/_prev_slice.html.slim +9 -0
- data/app/views/html_slicer/_slice.html.erb +11 -0
- data/app/views/html_slicer/_slice.html.haml +9 -0
- data/app/views/html_slicer/_slice.html.slim +10 -0
- data/app/views/html_slicer/_slicer.html.erb +22 -0
- data/app/views/html_slicer/_slicer.html.haml +17 -0
- data/app/views/html_slicer/_slicer.html.slim +18 -0
- data/config/locales/html_slicer.yml +8 -0
- data/html_slicer.gemspec +27 -0
- data/lib/html_slicer/config.rb +85 -0
- data/lib/html_slicer/engine.rb +4 -0
- data/lib/html_slicer/helpers/action_view_extension.rb +92 -0
- data/lib/html_slicer/helpers/slicer.rb +184 -0
- data/lib/html_slicer/helpers/smart_params.rb +35 -0
- data/lib/html_slicer/helpers/tags.rb +100 -0
- data/lib/html_slicer/installer.rb +118 -0
- data/lib/html_slicer/interface.rb +105 -0
- data/lib/html_slicer/models/active_record_extension.rb +22 -0
- data/lib/html_slicer/options.rb +60 -0
- data/lib/html_slicer/processor.rb +46 -0
- data/lib/html_slicer/railtie.rb +15 -0
- data/lib/html_slicer/resizing.rb +46 -0
- data/lib/html_slicer/slicing.rb +101 -0
- data/lib/html_slicer/utilities.rb +132 -0
- data/lib/html_slicer/version.rb +3 -0
- data/lib/html_slicer.rb +23 -0
- metadata +105 -0
@@ -0,0 +1,105 @@
|
|
1
|
+
module HtmlSlicer
|
2
|
+
|
3
|
+
class Interface # General accessor instance
|
4
|
+
attr_reader :document, :options, :current_slice
|
5
|
+
|
6
|
+
delegate :root, :to => :document
|
7
|
+
|
8
|
+
def initialize(content, options = {})
|
9
|
+
raise(TypeError, "String object expected, '#{content.class}' passed") unless content.is_a?(String)
|
10
|
+
@options = options
|
11
|
+
@current_slice = 1
|
12
|
+
@document = HTML::Document.new(HtmlSlicer::Process.iterate(content, options[:processors]))
|
13
|
+
if @options[:slice]
|
14
|
+
@slicing = Slicing.new(document, @options[:slice])
|
15
|
+
end
|
16
|
+
if @options[:resize]
|
17
|
+
@resizing = Resizing.new(document, @options[:resize])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Resturn number of slices.
|
22
|
+
def slice_number
|
23
|
+
sliced? ? @slicing.slice_number : 1
|
24
|
+
end
|
25
|
+
|
26
|
+
# General slicing method. Passing the argument changes the slice.
|
27
|
+
def slice!(slice = nil)
|
28
|
+
raise(Exception, "Slicing unavailable!") unless sliced?
|
29
|
+
if slice.present?
|
30
|
+
if slice.to_i.in?(1..slice_number)
|
31
|
+
@current_slice = slice.to_i
|
32
|
+
else
|
33
|
+
raise(ArgumentError, "Slice number must be Fixnum in (1..#{slice_number}). #{slice.inspect} passed.")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
# Textual representation according to a current slice.
|
40
|
+
def to_s
|
41
|
+
if sliced? && map = @slicing.map[current_slice-1]
|
42
|
+
view(root, map, @slicing.options.text_break)
|
43
|
+
else
|
44
|
+
root
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def inspect
|
49
|
+
to_s
|
50
|
+
end
|
51
|
+
|
52
|
+
def method_missing(*args, &block)
|
53
|
+
to_s.send(*args, &block)
|
54
|
+
end
|
55
|
+
|
56
|
+
def sliced?
|
57
|
+
@slicing.present?
|
58
|
+
end
|
59
|
+
|
60
|
+
def resized?
|
61
|
+
@resizing.present?
|
62
|
+
end
|
63
|
+
|
64
|
+
# Return the current slice is a last or not?
|
65
|
+
def last_slice?
|
66
|
+
current_slice == slice_number
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
# Return a textual representation of the node including all children assigned to a +map+.
|
72
|
+
def view(node, map = {}, text_break = nil)
|
73
|
+
case node
|
74
|
+
when HTML::Tag then
|
75
|
+
children_view = node.children.collect {|child| view(child, map, text_break)}.compact.join
|
76
|
+
if map[node.object_id] || children_view.present?
|
77
|
+
if node.closing == :close
|
78
|
+
"</#{node.name}>"
|
79
|
+
else
|
80
|
+
s = "<#{node.name}"
|
81
|
+
node.attributes.each do |k,v|
|
82
|
+
s << " #{k}"
|
83
|
+
s << "=\"#{v}\"" if String === v
|
84
|
+
end
|
85
|
+
s << " /" if node.closing == :self
|
86
|
+
s << ">"
|
87
|
+
s += children_view
|
88
|
+
s << "</#{node.name}>" if node.closing != :self && !node.children.empty?
|
89
|
+
s
|
90
|
+
end
|
91
|
+
end
|
92
|
+
when HTML::Text then
|
93
|
+
if range = map[node.object_id]
|
94
|
+
"#{node.content[range]}#{text_break unless range.last == -1}"
|
95
|
+
end
|
96
|
+
when HTML::CDATA then
|
97
|
+
node.to_s
|
98
|
+
when HTML::Node then
|
99
|
+
node.children.collect {|child| view(child, map, text_break)}.compact.join
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'html_slicer/installer'
|
2
|
+
|
3
|
+
module HtmlSlicer
|
4
|
+
|
5
|
+
module ActiveRecordExtension
|
6
|
+
def self.included(base)
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
class_eval do
|
12
|
+
include HtmlSlicer::Installer
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module InstanceMethods
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module HtmlSlicer
|
2
|
+
|
3
|
+
# Make options adjective and convinient for processing needs.
|
4
|
+
|
5
|
+
class Options #:nodoc:
|
6
|
+
# Superclass
|
7
|
+
attr_reader :only, :except
|
8
|
+
def initialize(options)
|
9
|
+
options ||= {}
|
10
|
+
@only = options[:only]
|
11
|
+
@except = options[:except]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class SliceOptions < Options #:nodoc:
|
16
|
+
attr_reader :unit, :maximum, :complete, :text_break, :limit
|
17
|
+
def initialize(options)
|
18
|
+
super(options)
|
19
|
+
@unit = case options[:unit]
|
20
|
+
when Hash, Regexp then options[:unit]
|
21
|
+
when String then /#{options[:unit]}/
|
22
|
+
when nil then /&#?\w+;|\S/
|
23
|
+
else raise "Invalid :unit definition '#{options[:unit].inspect}'"
|
24
|
+
end
|
25
|
+
@maximum = case options[:maximum]
|
26
|
+
when Fixnum then
|
27
|
+
if options[:maximum] > 0
|
28
|
+
options[:maximum]
|
29
|
+
else
|
30
|
+
raise "Invalid :maximum definition. Has to be more than zero, '#{options[:unit].inspect}' passed"
|
31
|
+
end
|
32
|
+
when nil then case unit
|
33
|
+
when String, Regexp then 300
|
34
|
+
when Hash then 10
|
35
|
+
else 2000
|
36
|
+
end
|
37
|
+
else raise "Invalid :maximum definition '#{options[:maximum].inspect}'"
|
38
|
+
end
|
39
|
+
@complete = case options[:complete]
|
40
|
+
when Regexp then options[:complete]
|
41
|
+
when nil then nil
|
42
|
+
else raise "Invalid :complete option definition '#{options[:complete].inspect}'"
|
43
|
+
end
|
44
|
+
@limit = case options[:limit]
|
45
|
+
when Fixnum, nil then options[:limit]
|
46
|
+
else raise "Invalid :limit option definition '#{options[:limit].inspect}'"
|
47
|
+
end
|
48
|
+
@text_break = options[:text_break]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class ResizeOptions < Options
|
53
|
+
attr_reader :width
|
54
|
+
def initialize(options)
|
55
|
+
super(options)
|
56
|
+
@width = options[:width]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module HtmlSlicer
|
2
|
+
class Processor
|
3
|
+
|
4
|
+
attr_accessor :content
|
5
|
+
|
6
|
+
def initialize(stuff = nil)
|
7
|
+
@content = case stuff
|
8
|
+
when String then stuff
|
9
|
+
else
|
10
|
+
if stuff.respond_to?(:to_s)
|
11
|
+
stuff.to_s
|
12
|
+
else
|
13
|
+
raise(TypeError, "String or responsible :to_s object expected, #{stuff.class} passed.")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def make
|
19
|
+
end
|
20
|
+
|
21
|
+
def export
|
22
|
+
make
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.load_processor!(name)
|
28
|
+
if defined?(Rails.root) && Rails.root
|
29
|
+
require File.expand_path(Rails.root.join("lib", "html_slicer_processors", "#{name.to_s.underscore}.rb"))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module Process
|
34
|
+
def self.iterate(content, processors = nil)
|
35
|
+
if processors.present?
|
36
|
+
Array.wrap(processors).each do |processor_name|
|
37
|
+
processor = processor_name.to_s.classify.constantize
|
38
|
+
raise(TypeError, "HtmlSlicer::Processor expected, #{processor.name} passed.") unless processor.superclass == HtmlSlicer::Processor
|
39
|
+
content = processor.new(content).export
|
40
|
+
end
|
41
|
+
end
|
42
|
+
content
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
module HtmlSlicer
|
4
|
+
class Railtie < ::Rails::Railtie
|
5
|
+
config.before_initialize do
|
6
|
+
ActiveSupport.on_load :active_record do
|
7
|
+
require 'html_slicer/models/active_record_extension'
|
8
|
+
ActiveRecord::Base.send(:include, HtmlSlicer::ActiveRecordExtension)
|
9
|
+
end
|
10
|
+
ActiveSupport.on_load :action_view do
|
11
|
+
ActionView::Base.send(:include, HtmlSlicer::ActionViewExtension)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module HtmlSlicer
|
2
|
+
|
3
|
+
class Resizing # Resizing engine
|
4
|
+
attr_reader :options
|
5
|
+
|
6
|
+
def initialize(document, options = {})
|
7
|
+
raise(TypeError, "HTML::Document expected, '#{document.class}' passed") unless document.is_a?(HTML::Document)
|
8
|
+
@options = ResizeOptions.new(options)
|
9
|
+
resize_document!(document.root)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
include HtmlSlicer::Utilities::ParseNode
|
15
|
+
include HtmlSlicer::Utilities::NodeMatchExtension
|
16
|
+
|
17
|
+
def resize_document!(root)
|
18
|
+
parse(root) do |node|
|
19
|
+
resize!(node) if node.is_a?(HTML::Tag) && resizeable?(node)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def resizeable?(node)
|
24
|
+
able_to?(node, @options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def resize!(node)
|
28
|
+
parent_width = node.parent.is_a?(HTML::Tag) ? absolute_resolution(node.parent.attributes["width"]) : nil
|
29
|
+
target_width = parent_width.present? ? parent_width.to_i : @options.width
|
30
|
+
if target_width.present? && node_width = absolute_resolution(node.attributes["width"])
|
31
|
+
node_height = absolute_resolution(node.attributes["height"])
|
32
|
+
if node_width > target_width
|
33
|
+
ratio = node_width.to_f/target_width
|
34
|
+
node.attributes["width"] = target_width.to_s
|
35
|
+
node.attributes["height"] = (node_height/ratio).round.to_s if node_height
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def absolute_resolution(value)
|
41
|
+
(value.present? && value.last != "%") ? value.to_i : nil
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module HtmlSlicer
|
2
|
+
|
3
|
+
class Slicing # Slicing engine
|
4
|
+
attr_reader :options, :map
|
5
|
+
|
6
|
+
def initialize(document, options = {})
|
7
|
+
raise(TypeError, "HTML::Document expected, '#{document.class}' passed") unless document.is_a?(HTML::Document)
|
8
|
+
@options = SliceOptions.new(options)
|
9
|
+
@map = [Hash.new]
|
10
|
+
@options.unit.is_a?(Hash) ? slice_document_by_node!(document.root) : slice_document_by_text!(document.root)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Resturn number of slices.
|
14
|
+
def slice_number
|
15
|
+
@map.size
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
include HtmlSlicer::Utilities::ParseNode
|
21
|
+
include HtmlSlicer::Utilities::NodeMatchExtension
|
22
|
+
|
23
|
+
def slice_document_by_text!(root)
|
24
|
+
units_count = 0
|
25
|
+
parse(root) do |node|
|
26
|
+
if node.is_a?(HTML::Text)
|
27
|
+
if sliceable?(node)
|
28
|
+
sanitize_content!(node)
|
29
|
+
content = node.to_s
|
30
|
+
index = 0
|
31
|
+
begin
|
32
|
+
while (match = content.match(@options.unit, index)) && index < content.size
|
33
|
+
units_count += 1
|
34
|
+
last_index ||= 0
|
35
|
+
if units_count == @options.maximum
|
36
|
+
units_count = 0
|
37
|
+
index = complete!(content, match.end(0))
|
38
|
+
@map.last[node.object_id] = Range.new(last_index, index-1)
|
39
|
+
last_index = index
|
40
|
+
limited? ? raise(Exception) : @map << Hash.new
|
41
|
+
else
|
42
|
+
index = match.end(0)
|
43
|
+
end
|
44
|
+
if units_count > 0
|
45
|
+
@map.last[node.object_id] = Range.new(last_index, -1)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
rescue Exception
|
49
|
+
break
|
50
|
+
end
|
51
|
+
else
|
52
|
+
@map.last[node.object_id] = Range.new(0, -1)
|
53
|
+
end
|
54
|
+
else
|
55
|
+
@map.last[node.object_id] = true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def slice_document_by_node!(root)
|
61
|
+
units_count = 0
|
62
|
+
parse(root) do |node|
|
63
|
+
if node.is_a?(HTML::Text)
|
64
|
+
@map.last[node.object_id] = Range.new(0, -1)
|
65
|
+
else
|
66
|
+
@map.last[node.object_id] = true
|
67
|
+
end
|
68
|
+
if node.match(@options.unit) && sliceable?(node)
|
69
|
+
units_count += 1
|
70
|
+
if units_count == @options.maximum
|
71
|
+
units_count = 0
|
72
|
+
limited? ? break : @map << Hash.new
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def limited?
|
79
|
+
@options.limit && slice_number >= @options.limit
|
80
|
+
end
|
81
|
+
|
82
|
+
def sanitize_content!(node)
|
83
|
+
content = HTML::FullSanitizer.new.sanitize(node.to_s)
|
84
|
+
node.instance_variable_set(:@content, content)
|
85
|
+
end
|
86
|
+
|
87
|
+
def complete!(content, index)
|
88
|
+
if regexp = @options.complete
|
89
|
+
content.match(regexp, index).try(:begin, 0)||index
|
90
|
+
else
|
91
|
+
index
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def sliceable?(node)
|
96
|
+
able_to?(node, @options)
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module HtmlSlicer
|
2
|
+
|
3
|
+
module Utilities
|
4
|
+
|
5
|
+
module ParseNode
|
6
|
+
def parse(node, &block)
|
7
|
+
node.children.each do |node|
|
8
|
+
yield node if block_given?
|
9
|
+
parse(node, &block) if node.is_a?(HTML::Tag)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Deepcopy
|
15
|
+
# Return the 'deep' brand new copy of Hash or Array. All nested hashes/arrays rebuilded at the same way.
|
16
|
+
def deepcopy(object)
|
17
|
+
array_copy = Proc.new do |a|
|
18
|
+
duplicate = Array.new
|
19
|
+
a.each do |value|
|
20
|
+
duplicate << case value
|
21
|
+
when Hash then hash_copy.call(value)
|
22
|
+
when Array then array_copy.call(value)
|
23
|
+
else value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
duplicate
|
27
|
+
end
|
28
|
+
hash_copy = Proc.new do |h|
|
29
|
+
duplicate = Hash.new
|
30
|
+
h.each do |key, value|
|
31
|
+
duplicate[key] = case value
|
32
|
+
when Hash then hash_copy.call(value)
|
33
|
+
when Array then array_copy.call(value)
|
34
|
+
else value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
duplicate
|
38
|
+
end
|
39
|
+
case object
|
40
|
+
when Hash then hash_copy.call(object)
|
41
|
+
when Array then array_copy.call(object)
|
42
|
+
else object
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
module HashupArray
|
48
|
+
# Return a nested Hash object from Array's elements sequence, where elements used as names of +hash+ keys.
|
49
|
+
# The last element of array would be the last nested value.
|
50
|
+
#
|
51
|
+
# === Example:
|
52
|
+
#
|
53
|
+
# [:vehicle, :car, :ford, :mustang, "2 please"].hashup
|
54
|
+
#
|
55
|
+
# #=> {:vehicle=>{:car=>{:ford=>{:mustang=>"2 please"}}}}
|
56
|
+
def hashup(array)
|
57
|
+
raise(TypeError, "Array expected!") unless array.is_a?(Array)
|
58
|
+
raise(Exception, "At least 2 elements needed!") if array.size < 2
|
59
|
+
value = array.delete_at(-1)
|
60
|
+
hash = {}
|
61
|
+
index = 0
|
62
|
+
last_hash = hash
|
63
|
+
while index < array.size
|
64
|
+
last_hash = last_hash[array.at(index)] = (index + 1 == array.size) ? value : {}
|
65
|
+
index += 1
|
66
|
+
end
|
67
|
+
hash
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
module NestedMergeHash
|
72
|
+
|
73
|
+
include Deepcopy
|
74
|
+
|
75
|
+
# Return the merged Hash with another +hash+, where the possible child hashes are also merged.
|
76
|
+
#
|
77
|
+
# === Example:
|
78
|
+
#
|
79
|
+
# h1 = {:breakfast => {:eggs => 2, :bread => 1}, :lunch => {:steak => 1, :salad => 1}}
|
80
|
+
# h2 = {:breakfast => {:coffee => :espresso, :juice => 1}, :lunch => {:tea => 2}, :dinner => :none}
|
81
|
+
# h1.nested_merge(h2)
|
82
|
+
# #=> {:breakfast=>{:eggs=>2, :bread=>1, :coffee=>:espresso, :juice=>1}, :lunch=>{:steak=>1, :salad=>1, :tea=>2}, :dinner=>:none}
|
83
|
+
#
|
84
|
+
def nested_merge(hash, other_hash = {})
|
85
|
+
raise(TypeError, "Hash expected!") unless hash.is_a?(Hash)
|
86
|
+
a = Proc.new do |original, change|
|
87
|
+
change.each do |key, value|
|
88
|
+
if !original.has_key?(key) || !original[key].is_a?(Hash)
|
89
|
+
original[key] = value
|
90
|
+
elsif original[key].is_a?(Hash) && value.is_a?(Hash)
|
91
|
+
a.call(original[key], value)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
original
|
95
|
+
end
|
96
|
+
a.call(deepcopy(hash), other_hash)
|
97
|
+
end
|
98
|
+
|
99
|
+
# .nested_merge replaces the source hash.
|
100
|
+
def nested_merge!(hash, other_hash = {})
|
101
|
+
hash.replace(nested_merge(hash, other_hash = {}))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
module NodeMatchExtension
|
106
|
+
|
107
|
+
# Checking if node is included in +:only+ parameter and/or excluded of +:except+ parameeter.
|
108
|
+
def able_to?(node, options)
|
109
|
+
if options.only.present?
|
110
|
+
general_match(node, options.only)
|
111
|
+
elsif options.except.present?
|
112
|
+
!general_match(node, options.except)
|
113
|
+
else
|
114
|
+
true
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Checking if node is a member of other node's tree. Accepts +hashes+ as conditions.
|
119
|
+
# Returns +true+ if node or it's parent matches at least one condition, or +false+ otherwise.
|
120
|
+
def general_match(node, hashes = [])
|
121
|
+
conditions = Array.wrap(hashes)
|
122
|
+
while node
|
123
|
+
break true if conditions.each {|condition| break true if node.match(condition)} == true
|
124
|
+
node = node.parent
|
125
|
+
end||false
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
data/lib/html_slicer.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "html_slicer/version"
|
4
|
+
|
5
|
+
module HtmlSlicer
|
6
|
+
|
7
|
+
def self.load!
|
8
|
+
require 'html_slicer/utilities'
|
9
|
+
require 'html_slicer/config'
|
10
|
+
require 'html_slicer/options'
|
11
|
+
require 'html_slicer/processor'
|
12
|
+
require 'html_slicer/slicing'
|
13
|
+
require 'html_slicer/resizing'
|
14
|
+
require 'html_slicer/interface'
|
15
|
+
require 'html_slicer/engine'
|
16
|
+
require 'html_slicer/helpers/action_view_extension'
|
17
|
+
require 'html_slicer/helpers/slicer'
|
18
|
+
require 'html_slicer/railtie'
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
HtmlSlicer.load!
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: html_slicer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Valery Kvon
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: actionpack
|
16
|
+
requirement: &70154298274740 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.0.0
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70154298274740
|
25
|
+
description: A "smart" way to slice HTMLsed text to pages, also it can optionally
|
26
|
+
resize included "width/height" attributes of HTML tags like <iframe>, <object>,
|
27
|
+
<img> etc.
|
28
|
+
email:
|
29
|
+
- addagger@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- .gitignore
|
35
|
+
- CHANGELOG
|
36
|
+
- Gemfile
|
37
|
+
- MIT-LICENSE
|
38
|
+
- README.rdoc
|
39
|
+
- Rakefile
|
40
|
+
- app/views/html_slicer/_first_slice.html.erb
|
41
|
+
- app/views/html_slicer/_first_slice.html.haml
|
42
|
+
- app/views/html_slicer/_first_slice.html.slim
|
43
|
+
- app/views/html_slicer/_gap.html.erb
|
44
|
+
- app/views/html_slicer/_gap.html.haml
|
45
|
+
- app/views/html_slicer/_gap.html.slim
|
46
|
+
- app/views/html_slicer/_last_slice.html.erb
|
47
|
+
- app/views/html_slicer/_last_slice.html.haml
|
48
|
+
- app/views/html_slicer/_last_slice.html.slim
|
49
|
+
- app/views/html_slicer/_next_slice.html.erb
|
50
|
+
- app/views/html_slicer/_next_slice.html.haml
|
51
|
+
- app/views/html_slicer/_next_slice.html.slim
|
52
|
+
- app/views/html_slicer/_prev_slice.html.erb
|
53
|
+
- app/views/html_slicer/_prev_slice.html.haml
|
54
|
+
- app/views/html_slicer/_prev_slice.html.slim
|
55
|
+
- app/views/html_slicer/_slice.html.erb
|
56
|
+
- app/views/html_slicer/_slice.html.haml
|
57
|
+
- app/views/html_slicer/_slice.html.slim
|
58
|
+
- app/views/html_slicer/_slicer.html.erb
|
59
|
+
- app/views/html_slicer/_slicer.html.haml
|
60
|
+
- app/views/html_slicer/_slicer.html.slim
|
61
|
+
- config/locales/html_slicer.yml
|
62
|
+
- html_slicer.gemspec
|
63
|
+
- lib/html_slicer.rb
|
64
|
+
- lib/html_slicer/config.rb
|
65
|
+
- lib/html_slicer/engine.rb
|
66
|
+
- lib/html_slicer/helpers/action_view_extension.rb
|
67
|
+
- lib/html_slicer/helpers/slicer.rb
|
68
|
+
- lib/html_slicer/helpers/smart_params.rb
|
69
|
+
- lib/html_slicer/helpers/tags.rb
|
70
|
+
- lib/html_slicer/installer.rb
|
71
|
+
- lib/html_slicer/interface.rb
|
72
|
+
- lib/html_slicer/models/active_record_extension.rb
|
73
|
+
- lib/html_slicer/options.rb
|
74
|
+
- lib/html_slicer/processor.rb
|
75
|
+
- lib/html_slicer/railtie.rb
|
76
|
+
- lib/html_slicer/resizing.rb
|
77
|
+
- lib/html_slicer/slicing.rb
|
78
|
+
- lib/html_slicer/utilities.rb
|
79
|
+
- lib/html_slicer/version.rb
|
80
|
+
homepage: http://github.com/addagger/HtmlSlicer
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project: html_slicer
|
101
|
+
rubygems_version: 1.8.16
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: HTML text slicer
|
105
|
+
test_files: []
|