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.
Files changed (47) hide show
  1. data/.gitignore +5 -0
  2. data/CHANGELOG +16 -0
  3. data/Gemfile +4 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.rdoc +336 -0
  6. data/Rakefile +1 -0
  7. data/app/views/html_slicer/_first_slice.html.erb +10 -0
  8. data/app/views/html_slicer/_first_slice.html.haml +8 -0
  9. data/app/views/html_slicer/_first_slice.html.slim +9 -0
  10. data/app/views/html_slicer/_gap.html.erb +7 -0
  11. data/app/views/html_slicer/_gap.html.haml +7 -0
  12. data/app/views/html_slicer/_gap.html.slim +8 -0
  13. data/app/views/html_slicer/_last_slice.html.erb +10 -0
  14. data/app/views/html_slicer/_last_slice.html.haml +8 -0
  15. data/app/views/html_slicer/_last_slice.html.slim +9 -0
  16. data/app/views/html_slicer/_next_slice.html.erb +10 -0
  17. data/app/views/html_slicer/_next_slice.html.haml +8 -0
  18. data/app/views/html_slicer/_next_slice.html.slim +9 -0
  19. data/app/views/html_slicer/_prev_slice.html.erb +10 -0
  20. data/app/views/html_slicer/_prev_slice.html.haml +8 -0
  21. data/app/views/html_slicer/_prev_slice.html.slim +9 -0
  22. data/app/views/html_slicer/_slice.html.erb +11 -0
  23. data/app/views/html_slicer/_slice.html.haml +9 -0
  24. data/app/views/html_slicer/_slice.html.slim +10 -0
  25. data/app/views/html_slicer/_slicer.html.erb +22 -0
  26. data/app/views/html_slicer/_slicer.html.haml +17 -0
  27. data/app/views/html_slicer/_slicer.html.slim +18 -0
  28. data/config/locales/html_slicer.yml +8 -0
  29. data/html_slicer.gemspec +27 -0
  30. data/lib/html_slicer/config.rb +85 -0
  31. data/lib/html_slicer/engine.rb +4 -0
  32. data/lib/html_slicer/helpers/action_view_extension.rb +92 -0
  33. data/lib/html_slicer/helpers/slicer.rb +184 -0
  34. data/lib/html_slicer/helpers/smart_params.rb +35 -0
  35. data/lib/html_slicer/helpers/tags.rb +100 -0
  36. data/lib/html_slicer/installer.rb +118 -0
  37. data/lib/html_slicer/interface.rb +105 -0
  38. data/lib/html_slicer/models/active_record_extension.rb +22 -0
  39. data/lib/html_slicer/options.rb +60 -0
  40. data/lib/html_slicer/processor.rb +46 -0
  41. data/lib/html_slicer/railtie.rb +15 -0
  42. data/lib/html_slicer/resizing.rb +46 -0
  43. data/lib/html_slicer/slicing.rb +101 -0
  44. data/lib/html_slicer/utilities.rb +132 -0
  45. data/lib/html_slicer/version.rb +3 -0
  46. data/lib/html_slicer.rb +23 -0
  47. metadata +105 -0
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ require "html_slicer/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "html_slicer"
8
+ s.version = HtmlSlicer::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Valery Kvon"]
11
+ s.email = ["addagger@gmail.com"]
12
+ s.homepage = %q{http://github.com/addagger/HtmlSlicer}
13
+ s.summary = %q{HTML text slicer}
14
+ s.description = %q{A "smart" way to slice HTMLsed text to pages, also it can optionally resize included "width/height" attributes of HTML tags like <iframe>, <object>, <img> etc.}
15
+
16
+ s.add_development_dependency "actionpack", ['>= 3.0.0']
17
+
18
+ s.rubyforge_project = "html_slicer"
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
+ s.require_paths = ["lib"]
24
+
25
+ s.licenses = ['MIT']
26
+
27
+ end
@@ -0,0 +1,85 @@
1
+ require 'active_support/configurable'
2
+
3
+ module HtmlSlicer
4
+ # Configures global settings for HtmlSlicer
5
+ #
6
+ # === Default global configuration options
7
+ #
8
+ # window = 4
9
+ # outer_window = 0
10
+ # left = 0
11
+ # right = 0
12
+ # param_name = :slice
13
+ #
14
+ # === Override/complete global configuration
15
+ #
16
+ # HtmlSlicer.configure do |config|
17
+ # config.slice = {:complete => /\s+|\z/, :maximum => 2000}
18
+ # config.resize = {:width => 300, :only => {:tag => 'iframe'}}
19
+ # config.window = 5
20
+ # config.param_name = :any_other_param_name
21
+ # end
22
+ #
23
+ # === Passing an argument (:symbol) creates stylized configuration, which can be used like that:
24
+ #
25
+ # HtmlSlicer.configure(:paged) do |config|
26
+ # config.as = :page
27
+ # config.param_name = :page
28
+ # end
29
+ #
30
+ # class Post < ActiveRecord::Base
31
+ # slice :content, :config => :paged
32
+ # end
33
+ #
34
+ # * Missing required parameters pick up automatically from global configuration set before.
35
+ #
36
+ def self.configure(style = nil, &block)
37
+ yield eval("@config#{"_#{style}" if style} ||= #{style ? "@config.duplicate" : "Configuration.new"}")
38
+ end
39
+
40
+ # Config accessor for HtmlSlicer. Accepts argument as a +style+.
41
+ def self.config(style = nil)
42
+ eval("@config#{"_#{style}" if style}")
43
+ end
44
+
45
+ # need a Class for 3.0
46
+ class Configuration #:nodoc:
47
+
48
+ include ActiveSupport::Configurable
49
+ include HtmlSlicer::Utilities::Deepcopy
50
+
51
+ config_accessor :as
52
+ config_accessor :slice
53
+ config_accessor :resize
54
+ config_accessor :processors
55
+ config_accessor :window
56
+ config_accessor :outer_window
57
+ config_accessor :left
58
+ config_accessor :right
59
+ config_accessor :param_name
60
+
61
+ def slice # Ugly coding. Override Hash::slice method
62
+ config[:slice]
63
+ end
64
+
65
+ def param_name
66
+ config.param_name.respond_to?(:call) ? config.param_name.call : config.param_name
67
+ end
68
+
69
+ def duplicate
70
+ dup = Configuration.new
71
+ dup.config.replace(deepcopy(config))
72
+ dup
73
+ end
74
+
75
+ end
76
+
77
+ configure do |config| # Setup default global configuration
78
+ config.window = 4
79
+ config.outer_window = 0
80
+ config.left = 0
81
+ config.right = 0
82
+ config.param_name = :slice
83
+ end
84
+
85
+ end
@@ -0,0 +1,4 @@
1
+ module HtmlSlicer #:nodoc:
2
+ class Engine < ::Rails::Engine #:nodoc:
3
+ end
4
+ end
@@ -0,0 +1,92 @@
1
+ # This part of code is almost completely ported from +Kaminari+ gem by Akira Matsuda.
2
+ # Look at http://github.com/amatsuda/kaminari/tree/master/lib/kaminari/helpers
3
+ module HtmlSlicer
4
+
5
+ # The part of code, processing the +:param_name+ was rewritten by me.
6
+ # Now you can define +:param_name+ as a +symbol+ or +string+, or as an +array of any object that responses +.to_s+ method and returns +string+.
7
+ # Passing +array+ is the way to define nested :param_name.
8
+ #
9
+ # === Examples:
10
+ #
11
+ # :param_name => :page
12
+ # # means you define params[:page] as a slice key.
13
+ #
14
+ # :param_name => [:article, :page]
15
+ # # means you define params[:article][:page] as a slice key.
16
+ #
17
+
18
+ module ActionViewExtension
19
+ # A helper that renders the pagination links.
20
+ #
21
+ # <%= slicer @article.paged %>
22
+ #
23
+ # ==== Options
24
+ # * <tt>:window</tt> - The "inner window" size (4 by default).
25
+ # * <tt>:outer_window</tt> - The "outer window" size (0 by default).
26
+ # * <tt>:left</tt> - The "left outer window" size (0 by default).
27
+ # * <tt>:right</tt> - The "right outer window" size (0 by default).
28
+ # * <tt>:params</tt> - url_for parameters for the links (:controller, :action, etc.)
29
+ # * <tt>:param_name</tt> - parameter name for slice number in the links. Accepts +symbol+, +string+, +array+.
30
+ # * <tt>:remote</tt> - Ajax? (false by default)
31
+ # * <tt>:ANY_OTHER_VALUES</tt> - Any other hash key & values would be directly passed into each tag as :locals value.
32
+ def slice(object, options = {}, &block)
33
+ slicer = HtmlSlicer::Helpers::Slicer.new self, object.options.reverse_merge(options).reverse_merge(:current_slice => object.current_slice, :slice_number => object.slice_number, :remote => false)
34
+ slicer.to_s
35
+ end
36
+
37
+ # A simple "Twitter like" pagination link that creates a link to the next slice.
38
+ #
39
+ # ==== Examples
40
+ # Basic usage:
41
+ #
42
+ # <%= link_to_next_slice @article.paged, 'Next page' %>
43
+ #
44
+ # Ajax:
45
+ #
46
+ # <%= link_to_next_slice @article.paged, 'Next page', :remote => true %>
47
+ #
48
+ # By default, it renders nothing if there are no more results on the next slice.
49
+ # You can customize this output by passing a block.
50
+ #
51
+ # <%= link_to_next_slice @article.paged, 'Next page' do %>
52
+ # <span>No More slices</span>
53
+ # <% end %>
54
+ def link_to_next_slice(object, name, options = {}, &block)
55
+ params = options[:params] ? self.params.merge(options.delete :params) : self.params
56
+ param_name = options.delete(:param_name) || object.options.param_name
57
+ link_to_unless object.last_slice?, name, HtmlSlicer::SmartParams.new(params, param_name, (object.current_slice + 1)), options.reverse_merge(:rel => 'next') do
58
+ block.call if block
59
+ end
60
+ end
61
+
62
+ # Renders a helpful message with numbers of displayed vs. total entries.
63
+ # Ported from mislav/will_paginate
64
+ #
65
+ # ==== Examples
66
+ # Basic usage:
67
+ #
68
+ # <%= slice_entries_info @article.paged %>
69
+ # #-> Displaying paged 6 of 26
70
+ #
71
+ # By default, the message will use the stringified +method_name (+:as+ option)+ implemented as slicer method.
72
+ # Override this with the <tt>:entry_name</tt> parameter:
73
+ #
74
+ # <%= slice_entries_info @article.paged, :entry_name => 'page' %>
75
+ # #-> Displaying page 6 of 26
76
+ def slice_entries_info(object, options = {})
77
+ entry_name = options[:entry_name] || object.options.as
78
+ output = ""
79
+ if object.slice_number < 2
80
+ output = case object.slice_number
81
+ when 0 then "No #{entry_name} found"
82
+ when 1 then "Displaying <b>1</b> #{entry_name}"
83
+ else; "Displaying <b>all #{object.slice_number}</b> #{entry_name.to_s.pluralize}"
84
+ end
85
+ else
86
+ output = %{Displaying #{entry_name} <b>#{object.current_slice}</b> of <b>#{object.slice_number}</b>}
87
+ end
88
+ output.html_safe
89
+ end
90
+ end
91
+
92
+ end
@@ -0,0 +1,184 @@
1
+ # This part of code is almost completely ported from +Kaminari+ gem by Akira Matsuda.
2
+ # Look at http://github.com/amatsuda/kaminari/tree/master/lib/kaminari/helpers
3
+
4
+ require 'active_support/inflector'
5
+ require 'action_view'
6
+ require 'action_view/log_subscriber'
7
+ require 'action_view/context'
8
+ require 'html_slicer/helpers/smart_params'
9
+ require 'html_slicer/helpers/tags'
10
+
11
+ module HtmlSlicer
12
+
13
+ module Helpers
14
+ # The main container tag
15
+
16
+ # Configure ActiveSupport inflections to pluralize 'slice' in a correct way = 'slices'. # By default would be 'slouse'.
17
+ ActiveSupport::Inflector.inflections do |inflect|
18
+ inflect.plural 'slice', 'slices'
19
+ inflect.singular 'slice', 'slice'
20
+ end
21
+
22
+ class Slicer < Tag
23
+ # so that this instance can actually "render"
24
+ include ::ActionView::Context
25
+
26
+ def initialize(template, options) #:nodoc:
27
+ @window_options = {}.tap do |h|
28
+ h[:window] = options.delete(:window) || options.delete(:inner_window)
29
+ outer_window = options.delete(:outer_window)
30
+ h[:left] = options.delete(:left)
31
+ h[:left] = outer_window if h[:left] == 0
32
+ h[:right] = options.delete(:right)
33
+ h[:right] = outer_window if h[:right] == 0
34
+ end
35
+ @template, @options = template, options
36
+ @theme = @options[:theme] ? "#{@options[:theme]}/" : ''
37
+ @options[:current_slice] = SliceProxy.new @window_options.merge(@options), @options[:current_slice], nil
38
+ # initialize the output_buffer for Context
39
+ @output_buffer = ActionView::OutputBuffer.new
40
+ end
41
+
42
+ # render given block as a view template
43
+ def render(&block)
44
+ instance_eval &block if @options[:slice_number] > 1
45
+ @output_buffer
46
+ end
47
+
48
+ # enumerate each slice providing sliceProxy object as the block parameter
49
+ # Because of performance reason, this doesn't actually enumerate all slices but slices that are seemingly relevant to the paginator.
50
+ # "Relevant" slices are:
51
+ # * slices inside the left outer window plus one for showing the gap tag
52
+ # * slices inside the inner window plus one on the left plus one on the right for showing the gap tags
53
+ # * slices inside the right outer window plus one for showing the gap tag
54
+ def each_relevant_slice
55
+ return to_enum(:each_relevant_slice) unless block_given?
56
+
57
+ relevant_slices(@window_options.merge(@options)).each do |i|
58
+ yield SliceProxy.new(@window_options.merge(@options), i, @last)
59
+ end
60
+ end
61
+ alias each_slice each_relevant_slice
62
+
63
+ def relevant_slices(options)
64
+ left_window_plus_one = 1.upto(options[:left] + 1).to_a
65
+ right_window_plus_one = (options[:slice_number] - options[:right]).upto(options[:slice_number]).to_a
66
+ inside_window_plus_each_sides = (options[:current_slice] - options[:window] - 1).upto(options[:current_slice] + options[:window] + 1).to_a
67
+
68
+ (left_window_plus_one + inside_window_plus_each_sides + right_window_plus_one).uniq.sort.reject {|x| (x < 1) || (x > options[:slice_number])}
69
+ end
70
+ private :relevant_slices
71
+
72
+ def slice_tag(slice)
73
+ @last = Slice.new @template, @options.merge(:slice => slice)
74
+ end
75
+
76
+ %w[first_slice prev_slice next_slice last_slice gap].each do |tag|
77
+ eval <<-DEF
78
+ def #{tag}_tag
79
+ @last = #{tag.classify}.new @template, @options
80
+ end
81
+ DEF
82
+ end
83
+
84
+ def to_s #:nodoc:
85
+ subscriber = ActionView::LogSubscriber.log_subscribers.detect {|ls| ls.is_a? ActionView::LogSubscriber}
86
+ return super @window_options.merge(@options).merge :slicer => self unless subscriber
87
+
88
+ # dirty hack to suppress logging render_partial
89
+ class << subscriber
90
+ alias_method :render_partial_with_logging, :render_partial
91
+ # do nothing
92
+ def render_partial(event); end
93
+ end
94
+
95
+ ret = super @window_options.merge(@options).merge :slicer => self
96
+
97
+ class << subscriber
98
+ alias_method :render_partial, :render_partial_with_logging
99
+ undef :render_partial_with_logging
100
+ end
101
+ ret
102
+ end
103
+
104
+ # Wraps a "slice number" and provides some utility methods
105
+ class SliceProxy
106
+ include Comparable
107
+
108
+ def initialize(options, slice, last) #:nodoc:
109
+ @options, @slice, @last = options, slice, last
110
+ end
111
+
112
+ # the slice number
113
+ def number
114
+ @slice
115
+ end
116
+
117
+ # current slice or not
118
+ def current?
119
+ @slice == @options[:current_slice]
120
+ end
121
+
122
+ # the first slice or not
123
+ def first?
124
+ @slice == 1
125
+ end
126
+
127
+ # the last slice or not
128
+ def last?
129
+ @slice == @options[:slice_number]
130
+ end
131
+
132
+ # the previous slice or not
133
+ def prev?
134
+ @slice == @options[:current_slice] - 1
135
+ end
136
+
137
+ # the next slice or not
138
+ def next?
139
+ @slice == @options[:current_slice] + 1
140
+ end
141
+
142
+ # within the left outer window or not
143
+ def left_outer?
144
+ @slice <= @options[:left]
145
+ end
146
+
147
+ # within the right outer window or not
148
+ def right_outer?
149
+ @options[:slice_number] - @slice < @options[:right]
150
+ end
151
+
152
+ # inside the inner window or not
153
+ def inside_window?
154
+ (@options[:current_slice] - @slice).abs <= @options[:window]
155
+ end
156
+
157
+ # The last rendered tag was "truncated" or not
158
+ def was_truncated?
159
+ @last.is_a? Gap
160
+ end
161
+
162
+ def to_i
163
+ number
164
+ end
165
+
166
+ def to_s
167
+ number.to_s
168
+ end
169
+
170
+ def +(other)
171
+ to_i + other.to_i
172
+ end
173
+
174
+ def -(other)
175
+ to_i - other.to_i
176
+ end
177
+
178
+ def <=>(other)
179
+ to_i <=> other.to_i
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,35 @@
1
+ module HtmlSlicer
2
+
3
+ class SmartParams < Hash
4
+ # Implements smart and flexible +params+ merging.
5
+ # Method accepts passed +params+ hash and merge it with a new +param_name+ and it's value.
6
+ # In the case when you passed +param_name+ option as an Array, method returns merged new
7
+ # instance of hashed params where all subhashes merged into the same way.
8
+ #
9
+ # === Example:
10
+ #
11
+ # params = {:controller => "comments", :action => "show", :id => 34, :article_id => 3, :page => {:article => 2}}
12
+ #
13
+ # :slice_params => [:page, :comment]
14
+ #
15
+ # HtmlSlicer::SmartParams.new(params, slice_params, 34)
16
+ # # => {:controller => "comments", :action => "show", :id => 34, :article_id => 3, :page => {:article => 2, :comment => 34}}
17
+ #
18
+ def initialize(params = {}, param_name = nil, value = nil)
19
+ super()
20
+ param_subhash = case param_name
21
+ when Array then hashup(param_name.collect {|e| e.to_s} << value)
22
+ when String, Symbol then {param_name.to_s => value}
23
+ else {}
24
+ end
25
+ update(nested_merge(params, param_subhash))
26
+ end
27
+
28
+ private
29
+
30
+ include HtmlSlicer::Utilities::HashupArray
31
+ include HtmlSlicer::Utilities::NestedMergeHash
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,100 @@
1
+ # This part of code is almost completely ported from +Kaminari+ gem by Akira Matsuda.
2
+ # Look at http://github.com/amatsuda/kaminari/tree/master/lib/kaminari/helpers
3
+ module HtmlSlicer
4
+ module Helpers
5
+
6
+ # A tag stands for an HTML tag inside the paginator.
7
+ # Basically, a tag has its own partial template file, so every tag can be
8
+ # rendered into String using its partial template.
9
+ #
10
+ # The template file should be placed in your app/views/html_slicer/ directory
11
+ # with underscored class name (besides the "Tag" class. Tag is an abstract
12
+ # class, so _tag parital is not needed).
13
+ # e.g.) PrevLink -> app/views/html_slicer/_prev_link.html.erb
14
+ #
15
+ # When no matching template were found in your app, the engine's pre
16
+ # installed template will be used.
17
+ # e.g.) Paginator -> $GEM_HOME/html_slicer-x.x.x/app/views/html_slicer/_paginator.html.erb
18
+
19
+ class Tag
20
+ def initialize(template, options = {}) #:nodoc:
21
+ @template, @options = template, options.dup
22
+ @param_name = @options.delete(:param_name)
23
+ @theme = @options[:theme] ? "#{@options.delete(:theme)}/" : ''
24
+ @params = @options[:params] ? template.params.merge(@options.delete :params) : template.params
25
+ end
26
+
27
+ def to_s(locals = {}) #:nodoc:
28
+ @template.render :partial => "html_slicer/#{@theme}#{self.class.name.demodulize.underscore}", :locals => @options.merge(locals)
29
+ end
30
+
31
+ def slice_url_for(slice)
32
+ # +HtmlSlicer::SmartParams+: return deep merged params with a new slice number value.
33
+ @template.url_for HtmlSlicer::SmartParams.new(@params, @param_name, (slice <= 1 ? nil : slice))
34
+ end
35
+ end
36
+
37
+ # Tag that contains a link
38
+ module Link
39
+ # target slice number
40
+ def slice
41
+ raise 'Override slice with the actual slice value to be a slice.'
42
+ end
43
+ # the link's href
44
+ def url
45
+ slice_url_for slice
46
+ end
47
+ def to_s(locals = {}) #:nodoc:
48
+ super locals.merge(:url => url)
49
+ end
50
+ end
51
+
52
+ # A slice
53
+ class Slice < Tag
54
+ include Link
55
+ # target slice number
56
+ def slice
57
+ @options[:slice]
58
+ end
59
+ def to_s(locals = {}) #:nodoc:
60
+ super locals.merge(:slice => slice)
61
+ end
62
+ end
63
+
64
+ # Link with slice number that appears at the leftmost
65
+ class FirstSlice < Tag
66
+ include Link
67
+ def slice #:nodoc:
68
+ 1
69
+ end
70
+ end
71
+
72
+ # Link with slice number that appears at the rightmost
73
+ class LastSlice < Tag
74
+ include Link
75
+ def slice #:nodoc:
76
+ @options[:slice_number]
77
+ end
78
+ end
79
+
80
+ # The "previous" slice of the current slice
81
+ class PrevSlice < Tag
82
+ include Link
83
+ def slice #:nodoc:
84
+ @options[:current_slice] - 1
85
+ end
86
+ end
87
+
88
+ # The "next" slice of the current slice
89
+ class NextSlice < Tag
90
+ include Link
91
+ def slice #:nodoc:
92
+ @options[:current_slice] + 1
93
+ end
94
+ end
95
+
96
+ # Non-link tag that stands for skipped slices...
97
+ class Gap < Tag
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,118 @@
1
+ module HtmlSlicer
2
+
3
+ module Installer
4
+
5
+ # The basic implementation method.
6
+ #
7
+ # slice <method_name>, <configuration>, [:config => <:style>]*
8
+ #
9
+ # where:
10
+ # * <method_name> - any method or local variable which returns source String (can be called with .send()).
11
+ # * <configuration> - Hash of configuration options and/or +:config+ parameter.
12
+ #
13
+ # === Example:
14
+ #
15
+ # class Article < ActiveRecord::Base
16
+ # slice :content, :as => :paged, :slice => {:maximum => 2000}, :resize => {:width => 600}
17
+ # end
18
+ #
19
+ # === Where:
20
+ # * <tt>:content</tt> is a method name or local variable, that return a target String object.
21
+ # * <tt>:as</tt> is a name of basic accessor for result.
22
+ # * <tt>:slice</tt> is a hash of +slicing options+.
23
+ # * <tt>:resize</tt> is a hash of +resizing options+.
24
+ #
25
+ # You can define any key of configuration you want. Otherwise, default configuration
26
+ # will be picked up automatically.
27
+ #
28
+ # === All configuration keys:
29
+ # * <tt>:as</tt> is a name of basic accessor for sliced +object+.
30
+ # * <tt>:slice</tt> is a hash of slicing options*.
31
+ # * <tt>:resize</tt> is a hash of resizing options*.
32
+ # * <tt>:processors</tt> - processors names*.
33
+ # * <tt>:window</tt> - parameter for ActionView: The "inner window" size (4 by default).
34
+ # * <tt>:outer_window</tt> - parameter for ActionView: The "outer window" size (0 by default).
35
+ # * <tt>:left</tt> - parameter for ActionView: The "left outer window" size (0 by default).
36
+ # * <tt>:right</tt> - parameter for ActionView: The "right outer window" size (0 by default).
37
+ # * <tt>:params</tt> - parameter for ActionView: url_for parameters for the links (:controller, :action, etc.)
38
+ # * <tt>:param_name</tt> - parameter for ActionView: parameter name for slice number in the links. Accepts +symbol+, +string+, +array+.
39
+ # * <tt>:remote</tt> - parameter for ActionView: Ajax? (false by default)
40
+ #
41
+ # === Block-style configuration example:
42
+ #
43
+ # slice *args do |config|
44
+ # config.as = :paged
45
+ # config.slice.merge! {:maximum => 1500}
46
+ # config.resize = nil
47
+ # end
48
+ #
49
+ # # *args = method name or local variable, and/or +:config+ parameter.
50
+ #
51
+ #
52
+ # === Premature configuration (+:config+ parameter):
53
+ # Stylizied general configuration can be used for many implementations, such as:
54
+ #
55
+ # # For example, we set the global stylized config:
56
+ #
57
+ # HtmlSlicer.configure(:paged_config) do |config|
58
+ # config.as = :page
59
+ # config.slice = {:maximum => 300}
60
+ # config.window = 4
61
+ # config.outer_window = 0
62
+ # config.left = 0
63
+ # config.right = 0
64
+ # config.param_name = :slice
65
+ # end
66
+ #
67
+ # # Now we can use it as next:
68
+ #
69
+ # slice *args, :config => :paged_config
70
+ #
71
+ # You can also pass another configuration options directrly as arguments
72
+ # and/or the block to clarify the config along with used global:
73
+ #
74
+ # slice *args, :as => :chapter, :config => :paged_config do |config|
75
+ # config.slice.merge! {:unit => {:tag => 'h1', :class => 'chapter'}, :maximum => 1}
76
+ # end
77
+ #
78
+ # === Skipping slicing:
79
+ #
80
+ # To skip slicing (for example, if you want to use only resizing feature)
81
+ # you can nilify +slice+ option at all:
82
+ #
83
+ # slice :content, :slice => nil, :resize => {:width => 300}
84
+ #
85
+ # Notice: without +:slice+ neither +:resize+ options, using HtmlSlicer becomes meaningless. :)
86
+ #
87
+ # === See README.rdoc for details about +:slice+ and +:resize+ options etc.
88
+ #
89
+ def slice(*args, &block)
90
+ attr_name = args.first
91
+ raise(NameError, "Attribute name expected!") unless attr_name
92
+
93
+ options = args.extract_options!
94
+ config = HtmlSlicer.config(options.delete(:config)).duplicate # Configuration instance for each single one implementation
95
+ if options.present? # Accepts options from args
96
+ options.each do |key, value|
97
+ config.send("#{key}=", value)
98
+ end
99
+ end
100
+ if block_given? # Accepts options from block
101
+ yield config
102
+ end
103
+ if config.processors
104
+ Array.wrap(config.processors).each do |name|
105
+ HtmlSlicer.load_processor!(name)
106
+ end
107
+ end
108
+ method_name = config.as||"#{attr_name}_slice"
109
+ class_exec do
110
+ define_method method_name do
111
+ var_name = "@_#{method_name}"
112
+ instance_variable_get(var_name)||instance_variable_set(var_name, HtmlSlicer::Interface.new(send(attr_name), config.config))
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ end