listify 0.1.0 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e02be46eb90c0bf7f85e55772515b7c7aef935fa
4
- data.tar.gz: a6296464e606c1da0752c64cf8a630f6920bcb14
3
+ metadata.gz: e9c8128654aa0b3ed2a9816520b8137360979433
4
+ data.tar.gz: cb4c0d3134dbdb0b22b491f87db505ef3373bbac
5
5
  SHA512:
6
- metadata.gz: c704d3f2ba216dc479da151704082eb15351294e2ded2e6f98adefc46c1d2cc37fb21cb395e2dedc9efca6168de20b5d92fd2646c442366b43c6ee1b55672758
7
- data.tar.gz: fed6d8b7d6c8a1d34e53f296364a08520b695d891e86f504ce59dac4a765078a4d93f222adbb3f58b90eef9c895c24000fec8d72393fce4d6d1807c44c7414e7
6
+ metadata.gz: 4f185be355bd9833cdd4514d0ecf78ece027e8145ba5b889f07f612e60a8e41e9881c8c2c24d3a41f8c8d6d032eab124841f1ea750b5177a02613fb1a1c7cf39
7
+ data.tar.gz: 0ffcd9fd3ae656eef7e714dde433b868b63950404c54807f262e16c0f6b2944b6f52223340148cc0f851bf9b2e0cd20fc3510df9aeb1173dfdc8829f36eb3c0a
data/README.md CHANGED
@@ -1,4 +1,8 @@
1
1
  #Listify Rails Plugin
2
+ [![Gem Version](https://badge.fury.io/rb/listify.png)](http://badge.fury.io/rb/listify)
3
+ [![Build Status](https://travis-ci.org/bappelt/listify.png)](https://travis-ci.org/bappelt/listify)
4
+ [![Coverage Status](https://coveralls.io/repos/bappelt/listify/badge.png?branch=master)](https://coveralls.io/r/bappelt/listify?branch=master)
5
+ [![Code Climate](https://codeclimate.com/github/bappelt/listify.png)](https://codeclimate.com/github/bappelt/listify)
2
6
 
3
7
  The Listify rails plugin provides a simple method to use in views and helpers to render an HTML list from a ruby array or hash.
4
8
 
@@ -58,6 +62,26 @@ listify( {'First Category' => ['item one', 'item two'], 'Second Category' => ['i
58
62
  </ul>"
59
63
  ```
60
64
 
65
+ ###Multi-Column lists
66
+
67
+ If you specify a number of columns > 1, the list will be broken up into multiple unordered lists intended for use as separate columns
68
+ ```
69
+ listify( %w[first second third fourth fifth sixth seventh], columns: 3 )
70
+ => "<ul>
71
+ <li>first</li>
72
+ <li>second</li>
73
+ </ul>
74
+ <ul>
75
+ <li>third</li>
76
+ <li>fourth</li>
77
+ </ul>
78
+ <ul>
79
+ <li>fifth</li>
80
+ <li>sixth</li>
81
+ <li>seventh</li>
82
+ </ul>"
83
+ ```
84
+
61
85
  ###Complex lists
62
86
 
63
87
  And you can get more complex, though maybe you shouldn't:
@@ -104,5 +128,3 @@ listify( {'First-Category' => ['item-one', 'item-two'],
104
128
  <li>Fourth-Item</li>
105
129
  </ul>"
106
130
  ```
107
-
108
- [![Code Climate](https://codeclimate.com/github/bappelt/listify.png)](https://codeclimate.com/github/bappelt/listify)
@@ -0,0 +1,112 @@
1
+ class Columnizer
2
+
3
+ def initialize(list, number_of_columns)
4
+ @list = Columnizer.convert_to_array(list)
5
+ @column_count = number_of_columns
6
+ @items_by_column = []
7
+ columnize!
8
+ end
9
+
10
+ def columnize!
11
+ (1..@column_count).each do |column_number|
12
+ @items_by_column[column_number] = find_items_for_column(column_number)
13
+ end
14
+ end
15
+
16
+ def items_for_column(column_number)
17
+ @items_by_column[column_number]
18
+ end
19
+
20
+ def find_items_for_column(column_number)
21
+ zero_based_column_number = column_number-1
22
+ return [] if item_count_by_column[zero_based_column_number]==0
23
+ first_item_index = 0 if zero_based_column_number==0
24
+ first_item_index ||= (item_count_by_column[0..zero_based_column_number-1]).inject(:+)
25
+ last_item_index = first_item_index+item_count_by_column[zero_based_column_number]-1
26
+ Columnizer.truncate_list(@list, first_item_index..last_item_index)
27
+ end
28
+
29
+ def item_count_by_column
30
+ item_count_by_column = []
31
+ total_item_count = total_item_count_for_collection(@list)
32
+ balanced_item_count = total_item_count / @column_count
33
+ unbalanced_item_count = total_item_count % @column_count
34
+ @column_count.times { item_count_by_column << balanced_item_count }
35
+ item_count_by_column[-unbalanced_item_count..-1] = item_count_by_column[-unbalanced_item_count..-1].collect { |n| n+1 } if unbalanced_item_count > 0
36
+ item_count_by_column
37
+ end
38
+
39
+ def total_item_count_for_collection(list)
40
+ item_count = 0
41
+ list.each do |item|
42
+ if item.is_a?(Enumerable)
43
+ item_count += total_item_count_for_collection(item)
44
+ else
45
+ item_count += 1
46
+ end
47
+ end
48
+ item_count
49
+ end
50
+
51
+ def self.truncate_list(list, range)
52
+
53
+ list = convert_to_array(list)
54
+
55
+ first_index, last_index = range.begin, range.end
56
+ first_item, last_item = list.flatten[first_index], list.flatten[last_index]
57
+
58
+ list.each { |o| o.extend(IsOrIncludes) }
59
+ list.flatten(1).each { |o| o.extend(IsOrIncludes) }
60
+ list.flatten(2).each { |o| o.extend(IsOrIncludes) }
61
+
62
+ first_item_index = list.index { |o| o.is_or_includes?(first_item) }
63
+ last_item_index = list.index { |o| o.is_or_includes?(last_item) }
64
+
65
+ last_item_container = list[last_item_index]
66
+ if last_item_container.is_a?(Array)
67
+ unless last_item_container[1].eql?(last_item) || last_item_container[1].last.eql?(last_item) || last_item_container[1].empty?
68
+ last_item_index -= 1
69
+ end
70
+ end
71
+
72
+ list[first_item_index..last_item_index]
73
+
74
+ end
75
+
76
+ def self.convert_to_array(list)
77
+ truncated_list = []
78
+ if list.respond_to?(:keys)
79
+ keys = list.keys
80
+ keys.each do |key|
81
+ list[key.to_s] = list.delete(key)
82
+ end
83
+ list.each do |key, value|
84
+ validate_depth(value)
85
+ truncated_list << [key.dup, value]
86
+ end
87
+ else
88
+ truncated_list = list
89
+ end
90
+ truncated_list
91
+ end
92
+
93
+ def self.validate_depth(value)
94
+ if value.respond_to?(:each) then
95
+ value.each { |item| raise "Columns not supported for lists nested more than one level" if item.respond_to?(:keys) }
96
+ end
97
+ end
98
+
99
+
100
+ end
101
+
102
+ module IsOrIncludes
103
+
104
+ def is_or_includes?(object)
105
+ if self.is_a?(Array)
106
+ return self.index { |o| o.is_or_includes?(object) }
107
+ else
108
+ return object.equal?(self)
109
+ end
110
+ end
111
+
112
+ end
@@ -1,14 +1,19 @@
1
+ require_relative 'columnizer'
2
+
1
3
  module Listify
2
4
 
3
5
  module Helper
4
6
 
5
7
  # Generate an HTML list from a ruby collection
6
8
  # @param [Array, Hash{sublist_name => sublist[Array, Hash]}] collection the collection to render as a list
9
+ # @param [Hash] options
10
+ # @option options [String] :class HTML class to apply to the <ul> elements
11
+ # @option options [Integer] :columns (1) When specified, break list into multiple lists. Breaks will occur at top level only if list is nested. Not supported for lists nested more than one level deep.
7
12
  # @return ActiveSupport::SafeBuffer
8
13
  #
9
14
  # @example Simple List
10
- # listify( ['first item', 'second item', 'third item'] )
11
- # => "<ul>
15
+ # listify( ['first item', 'second item', 'third item'], class: 'parts-list' )
16
+ # => "<ul class='parts-list'>
12
17
  # <li>first item</li>
13
18
  # <li>second item</li>
14
19
  # <li>third item</li>
@@ -30,10 +35,44 @@ module Listify
30
35
  # </ul>
31
36
  # </li>
32
37
  # </ul>"
38
+ #
39
+ # @example Multiple Column List
40
+ # listify( ['first item', 'second item', 'third item', 'fourth item', 'fifth item'], columns: 2 )
41
+ # => "<ul>
42
+ # <li>first item</li>
43
+ # <li>second item</li>
44
+ # </ul>
45
+ # <ul>
46
+ # <li>third item</li>
47
+ # <li>fourth item</li>
48
+ # <li>fifth item</li>
49
+ # </ul>"
33
50
  def listify(collection, options = {})
34
- content_tag :ul, options do
35
- list_items_for(collection)
51
+ number_of_columns = options.fetch(:columns, 1)
52
+
53
+ if number_of_columns > 1
54
+ options.delete(:columns)
55
+ columnizer = Columnizer.new(collection, number_of_columns)
56
+
57
+ elements = []
58
+ (1..number_of_columns).each do |column|
59
+ items_for_column = columnizer.items_for_column(column)
60
+ next if items_for_column.empty?
61
+ column_element = content_tag :ul, options do
62
+ list_items_for(items_for_column)
63
+ end
64
+ elements << column_element
65
+ end
66
+
67
+
68
+ return elements.inject(:+)
69
+
70
+ else
71
+ content_tag :ul, options do
72
+ list_items_for(collection)
73
+ end
36
74
  end
75
+
37
76
  end
38
77
 
39
78
  private
@@ -1,3 +1,3 @@
1
1
  module Listify
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: listify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 'Byron Appelt '
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-13 00:00:00.000000000 Z
11
+ date: 2013-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -31,6 +31,7 @@ executables: []
31
31
  extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
+ - lib/columnizer.rb
34
35
  - lib/listify/version.rb
35
36
  - lib/listify.rb
36
37
  - MIT-LICENSE