html_slicer 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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