blueprintr 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +35 -0
  5. data/Rakefile +53 -0
  6. data/VERSION +1 -0
  7. data/bin/blueprintr +3 -0
  8. data/blueprintr.gemspec +119 -0
  9. data/lib/blueprint-css/.gitignore +5 -0
  10. data/lib/blueprint-css/AUTHORS.textile +42 -0
  11. data/lib/blueprint-css/CHANGELOG +159 -0
  12. data/lib/blueprint-css/LICENSE +314 -0
  13. data/lib/blueprint-css/README.textile +81 -0
  14. data/lib/blueprint-css/TUTORIAL.textile +206 -0
  15. data/lib/blueprint-css/blueprint/ie.css +35 -0
  16. data/lib/blueprint-css/blueprint/plugins/buttons/icons/cross.png +0 -0
  17. data/lib/blueprint-css/blueprint/plugins/buttons/icons/key.png +0 -0
  18. data/lib/blueprint-css/blueprint/plugins/buttons/icons/tick.png +0 -0
  19. data/lib/blueprint-css/blueprint/plugins/buttons/readme.txt +32 -0
  20. data/lib/blueprint-css/blueprint/plugins/buttons/screen.css +97 -0
  21. data/lib/blueprint-css/blueprint/plugins/fancy-type/readme.txt +14 -0
  22. data/lib/blueprint-css/blueprint/plugins/fancy-type/screen.css +71 -0
  23. data/lib/blueprint-css/blueprint/plugins/link-icons/icons/doc.png +0 -0
  24. data/lib/blueprint-css/blueprint/plugins/link-icons/icons/email.png +0 -0
  25. data/lib/blueprint-css/blueprint/plugins/link-icons/icons/external.png +0 -0
  26. data/lib/blueprint-css/blueprint/plugins/link-icons/icons/feed.png +0 -0
  27. data/lib/blueprint-css/blueprint/plugins/link-icons/icons/im.png +0 -0
  28. data/lib/blueprint-css/blueprint/plugins/link-icons/icons/pdf.png +0 -0
  29. data/lib/blueprint-css/blueprint/plugins/link-icons/icons/visited.png +0 -0
  30. data/lib/blueprint-css/blueprint/plugins/link-icons/icons/xls.png +0 -0
  31. data/lib/blueprint-css/blueprint/plugins/link-icons/readme.txt +18 -0
  32. data/lib/blueprint-css/blueprint/plugins/link-icons/screen.css +40 -0
  33. data/lib/blueprint-css/blueprint/plugins/rtl/readme.txt +10 -0
  34. data/lib/blueprint-css/blueprint/plugins/rtl/screen.css +110 -0
  35. data/lib/blueprint-css/blueprint/print.css +29 -0
  36. data/lib/blueprint-css/blueprint/screen.css +258 -0
  37. data/lib/blueprint-css/blueprint/src/forms.css +65 -0
  38. data/lib/blueprint-css/blueprint/src/grid.css +280 -0
  39. data/lib/blueprint-css/blueprint/src/grid.png +0 -0
  40. data/lib/blueprint-css/blueprint/src/ie.css +76 -0
  41. data/lib/blueprint-css/blueprint/src/print.css +85 -0
  42. data/lib/blueprint-css/blueprint/src/reset.css +45 -0
  43. data/lib/blueprint-css/blueprint/src/typography.css +106 -0
  44. data/lib/blueprint-css/lib/blueprint/blueprint.rb +39 -0
  45. data/lib/blueprint-css/lib/blueprint/compressor.rb +265 -0
  46. data/lib/blueprint-css/lib/blueprint/core_ext.rb +39 -0
  47. data/lib/blueprint-css/lib/blueprint/css_parser.rb +69 -0
  48. data/lib/blueprint-css/lib/blueprint/custom_layout.rb +71 -0
  49. data/lib/blueprint-css/lib/blueprint/grid.css.erb +146 -0
  50. data/lib/blueprint-css/lib/blueprint/grid_builder.rb +54 -0
  51. data/lib/blueprint-css/lib/blueprint/namespace.rb +38 -0
  52. data/lib/blueprint-css/lib/blueprint/semantic_class_names.rb +57 -0
  53. data/lib/blueprint-css/lib/blueprint/validate/COPYRIGHT.html +93 -0
  54. data/lib/blueprint-css/lib/blueprint/validate/JIGSAW_COPYRIGHT +64 -0
  55. data/lib/blueprint-css/lib/blueprint/validate/README.html +83 -0
  56. data/lib/blueprint-css/lib/blueprint/validate/XERCES_COPYING.txt +56 -0
  57. data/lib/blueprint-css/lib/blueprint/validate/css-validator-javadoc.jar +0 -0
  58. data/lib/blueprint-css/lib/blueprint/validate/css-validator.jar +0 -0
  59. data/lib/blueprint-css/lib/blueprint/validate/jigsaw.jar +0 -0
  60. data/lib/blueprint-css/lib/blueprint/validate/xerces.jar +0 -0
  61. data/lib/blueprint-css/lib/blueprint/validator.rb +49 -0
  62. data/lib/blueprint-css/lib/compress.rb +149 -0
  63. data/lib/blueprint-css/lib/settings.example.yml +33 -0
  64. data/lib/blueprint-css/lib/validate.rb +15 -0
  65. data/lib/blueprint-css/templates/psd/fixed-width.psd +0 -0
  66. data/lib/blueprint-css/tests/index.html +83 -0
  67. data/lib/blueprint-css/tests/parts/elements.html +247 -0
  68. data/lib/blueprint-css/tests/parts/forms.html +191 -0
  69. data/lib/blueprint-css/tests/parts/grid.html +163 -0
  70. data/lib/blueprint-css/tests/parts/sample.html +75 -0
  71. data/lib/blueprint-css/tests/parts/test-small.jpg +0 -0
  72. data/lib/blueprint-css/tests/parts/test.jpg +0 -0
  73. data/lib/blueprint-css/tests/parts/valid.png +0 -0
  74. data/lib/blueprintr.rb +23 -0
  75. data/test/helper.rb +9 -0
  76. data/test/test_blueprintr.rb +14 -0
  77. metadata +139 -0
@@ -0,0 +1,39 @@
1
+ class String
2
+ # see if string has any content
3
+ def blank?; self.length.zero?; end
4
+
5
+ # strip space after :, remove newlines, replace multiple spaces with only one space, remove comments
6
+ def strip_space!
7
+ replace self.gsub(/:\s*/, ':').gsub(/\n/, '').gsub(/\s+/, ' ').gsub(/(\/\*).*?(\*\/)/, '')
8
+ end
9
+
10
+ # remove newlines, insert space after comma, replace two spaces with one space after comma
11
+ def strip_selector_space!
12
+ replace self.gsub(/(\n)/, '').gsub(',', ', ').gsub(', ', ', ')
13
+ end
14
+
15
+ # remove leading whitespace, remove end whitespace
16
+ def strip_side_space!
17
+ replace self.gsub(/^\s+/, '').gsub(/\s+$/, $/)
18
+ end
19
+ end
20
+
21
+ class NilClass
22
+ def blank?
23
+ true
24
+ end
25
+ end
26
+
27
+ class File
28
+ # string output from file
29
+ def self.path_to_string(path)
30
+ File.new(path).read
31
+ end
32
+
33
+ # saves a string to a specified file path
34
+ def self.string_to_file(string, path)
35
+ directory = File.dirname(path)
36
+ FileUtils.mkdir_p directory unless File.directory?(directory)
37
+ File.open(path, 'w') { |f| f << string }
38
+ end
39
+ end
@@ -0,0 +1,69 @@
1
+ module Blueprint
2
+ # Strips out most whitespace and can return a hash or string of parsed data
3
+ class CSSParser
4
+ attr_accessor :namespace
5
+ attr_reader :css_output, :raw_data
6
+
7
+ # ==== Options
8
+ # * <tt>css_string</tt> String of CSS data
9
+ # * <tt>options</tt>
10
+ # * <tt>:namespace</tt> -- Namespace to use when generating output
11
+ def initialize(css_string = "", options = {})
12
+ @raw_data = css_string
13
+ @namespace = options[:namespace] || ""
14
+ compress(@raw_data)
15
+ end
16
+
17
+ # returns string of CSS which can be saved to a file or otherwise
18
+ def to_s
19
+ @css_output
20
+ end
21
+
22
+ # returns a hash of all CSS data passed
23
+ #
24
+ # ==== Options
25
+ # * <tt>data</tt> -- CSS string; defaults to string passed into the constructor
26
+ def parse(data = nil)
27
+ data ||= @raw_data
28
+
29
+ # wrapper array holding hashes of css tags/rules
30
+ css_out = []
31
+ # clear initial spaces
32
+ data.strip_side_space!.strip_space!
33
+
34
+ # split on end of assignments
35
+ data.split('}').each_with_index do |assignments, index|
36
+ # split again to separate tags from rules
37
+ tags, styles = assignments.split('{').map{|a| a.strip_side_space!}
38
+ unless styles.blank?
39
+ # clean up tags and apply namespaces as needed
40
+ tags.strip_selector_space!
41
+ tags.gsub!(/\./, ".#{namespace}") unless namespace.blank?
42
+
43
+ # split on semicolon to iterate through each rule
44
+ rules = []
45
+ styles.split(';').each do |key_val_pair|
46
+ unless key_val_pair.nil?
47
+ # split by property/val and append to rules array with correct declaration
48
+ property, value = key_val_pair.split(':', 2).map{|kv| kv.strip_side_space!}
49
+ break unless property && value
50
+ rules << "#{property}:#{value};"
51
+ end
52
+ end
53
+ # now keeps track of index as hashes don't keep track of position (which will be fixed in Ruby 1.9)
54
+ css_out << {:tags => tags, :rules => rules.join, :idx => index} unless tags.blank? || rules.to_s.blank?
55
+ end
56
+ end
57
+ css_out
58
+ end
59
+
60
+ private
61
+
62
+ def compress(data)
63
+ @css_output = ""
64
+ parse(data).flatten.sort_by {|i| i[:idx]}.each do |line|
65
+ @css_output += "#{line[:tags]} {#{line[:rules]}}\n"
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,71 @@
1
+ require 'erb'
2
+ module Blueprint
3
+ # Generates a custom grid file, using ERB to evaluate custom settings
4
+ class CustomLayout
5
+ # path to ERB file used for CSS template
6
+ CSS_ERB_FILE = File.join(Blueprint::LIB_PATH, 'grid.css.erb')
7
+
8
+ attr_writer :column_count, :column_width, :gutter_width, :input_padding, :input_border
9
+
10
+ # Column count of generated CSS. Returns itself or Blueprint's default
11
+ def column_count
12
+ (@column_count || Blueprint::COLUMN_COUNT).to_i
13
+ end
14
+
15
+ # Column width (in pixels) of generated CSS. Returns itself or Blueprint's default
16
+ def column_width
17
+ (@column_width || Blueprint::COLUMN_WIDTH).to_i
18
+ end
19
+
20
+ # Gutter width (in pixels) of generated CSS. Returns itself or Blueprint's default
21
+ def gutter_width
22
+ (@gutter_width || Blueprint::GUTTER_WIDTH).to_i
23
+ end
24
+
25
+ def input_padding
26
+ (@input_padding || Blueprint::INPUT_PADDING).to_i
27
+ end
28
+
29
+ def input_border
30
+ (@input_border || Blueprint::INPUT_BORDER).to_i
31
+ end
32
+
33
+ # Returns page width (in pixels)
34
+ def page_width
35
+ column_count * (column_width + gutter_width) - gutter_width
36
+ end
37
+
38
+ # ==== Options
39
+ # * <tt>options</tt>
40
+ # * <tt>:column_count</tt> -- Sets the column count of generated CSS
41
+ # * <tt>:column_width</tt> -- Sets the column width (in pixels) of generated CSS
42
+ # * <tt>:gutter_width</tt> -- Sets the gutter width (in pixels) of generated CSS
43
+ # * <tt>:input_padding</tt> -- Sets the input padding width (in pixels) of generated CSS
44
+ # * <tt>:input_border</tt> -- Sets the border width (in pixels) of generated CSS
45
+ def initialize(options = {})
46
+ @column_count = options[:column_count]
47
+ @column_width = options[:column_width]
48
+ @gutter_width = options[:gutter_width]
49
+ @input_padding = options[:input_padding]
50
+ @input_border = options[:input_border]
51
+ end
52
+
53
+ # Boolean value if current settings are Blueprint's defaults
54
+ def default?
55
+ self.column_width == Blueprint::COLUMN_WIDTH &&
56
+ self.column_count == Blueprint::COLUMN_COUNT &&
57
+ self.gutter_width == Blueprint::GUTTER_WIDTH &&
58
+ self.input_padding == Blueprint::INPUT_PADDING &&
59
+ self.input_border == Blueprint::INPUT_BORDER
60
+ end
61
+
62
+ # Loads grid.css.erb file, binds it to current instance, and returns output
63
+ def generate_grid_css
64
+ # loads up erb template to evaluate custom widths
65
+ css = ERB::new(File.path_to_string(CustomLayout::CSS_ERB_FILE))
66
+
67
+ # bind it to this instance
68
+ css.result(binding)
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,146 @@
1
+ /* --------------------------------------------------------------
2
+
3
+ grid.css
4
+ * Sets up an easy-to-use grid of 24 columns.
5
+
6
+ By default, the grid is 950px wide, with 24 columns
7
+ spanning 30px, and a 10px margin between columns.
8
+
9
+ If you need fewer or more columns, namespaces or semantic
10
+ element names, use the compressor script (lib/compress.rb)
11
+
12
+ -------------------------------------------------------------- */
13
+
14
+ /* A container should group all your columns. */
15
+ .container {
16
+ width: <%= page_width %>px;
17
+ margin: 0 auto;
18
+ }
19
+
20
+ /* Use this class on any .span-# / .container to see the grid. */
21
+ .showgrid {
22
+ background: url(src/grid.png);
23
+ }
24
+
25
+
26
+ /* Columns
27
+ -------------------------------------------------------------- */
28
+
29
+ /* Sets up basic grid floating and margin. */
30
+ .column, <%= (1..column_count).map {|c| ".span-#{c}" }.join(", ") %> {
31
+ float: left;
32
+ margin-right: <%= gutter_width %>px;
33
+ }
34
+
35
+ /* The last column in a row needs this class. */
36
+ .last { margin-right: 0; }
37
+
38
+ /* Use these classes to set the width of a column. */
39
+ .span-1 {width: <%= column_width %>px;}
40
+ <% (2..column_count-1).each do |column| %>
41
+ .span-<%= column %> {width: <%= (column_width + ((column - 1) * (column_width + gutter_width))).to_i %>px;<%= "margin-right: 0;" if column == column_count %>}<% end %>
42
+ .span-<%= column_count %> {width:<%= page_width %>px; margin-right:0;}
43
+
44
+ /* Use these classes to set the width of an input. */
45
+ <%= (1..column_count).map {|column| "input.span-#{column}, textarea.span-#{column}"}.join(", ") %> {
46
+ border-left-width: <%= input_border %>px;
47
+ border-right-width: <%= input_border %>px;
48
+ padding-left: <%= input_padding %>px;
49
+ padding-right: <%= input_padding %>px;
50
+ }
51
+ <% (1..column_count).each do |column| %>
52
+ input.span-<%= column %>, textarea.span-<%= column %> { width: <%= ((column_width + gutter_width) * (column - 1) + column_width - 2*(input_padding + input_border))%>px; }<% end %>
53
+
54
+ /* Add these to a column to append empty cols. */
55
+ <% (1..(column_count-1)).each do |column| %>
56
+ .append-<%= column %> { padding-right: <%= (column * (column_width + gutter_width)).to_i %>px;}<% end %>
57
+
58
+ /* Add these to a column to prepend empty cols. */
59
+ <% (1..(column_count-1)).each do |column| %>
60
+ .prepend-<%= column %> { padding-left: <%= (column * (column_width + gutter_width)).to_i %>px;}<% end %>
61
+
62
+
63
+ /* Border on right hand side of a column. */
64
+ .border {
65
+ padding-right: <%= (gutter_width * 0.5 - 1).to_i %>px;
66
+ margin-right: <%= (gutter_width * 0.5).to_i %>px;
67
+ border-right: 1px solid #eee;
68
+ }
69
+
70
+ /* Border with more whitespace, spans one column. */
71
+ .colborder {
72
+ padding-right: <%= (column_width + 2*gutter_width - 1)/2.to_i %>px;
73
+ margin-right: <%= (column_width + 2 * gutter_width)/2.to_i %>px;
74
+ border-right: 1px solid #eee;
75
+ }
76
+
77
+
78
+ /* Use these classes on an element to push it into the
79
+ next column, or to pull it into the previous column. */
80
+
81
+ <% (1..column_count).each do |column| %>
82
+ .pull-<%= column %> { margin-left: -<%= (column * (column_width + gutter_width)).to_i %>px; }<% end %>
83
+
84
+ <%= (1..column_count).map {|c| ".pull-#{c}" }.join(", ") %> {float: left; position:relative;}
85
+
86
+ <% (1..(column_count)).each do |column| %>
87
+ .push-<%= column %> { margin: 0 -<%= (column * (column_width + gutter_width)).to_i %>px 1.5em <%= (column * (column_width + gutter_width)).to_i %>px; }<% end %>
88
+
89
+ <%= (1..column_count).map {|c| ".push-#{c}" }.join(", ") %> {float: right; position:relative;}
90
+
91
+
92
+ /* Misc classes and elements
93
+ -------------------------------------------------------------- */
94
+
95
+ /* In case you need to add a gutter above/below an element */
96
+ .prepend-top {
97
+ margin-top:1.5em;
98
+ }
99
+ .append-bottom {
100
+ margin-bottom:1.5em;
101
+ }
102
+
103
+ /* Use a .box to create a padded box inside a column. */
104
+ .box {
105
+ padding: 1.5em;
106
+ margin-bottom: 1.5em;
107
+ background: #E5ECF9;
108
+ }
109
+
110
+ /* Use this to create a horizontal ruler across a column. */
111
+ hr {
112
+ background: #ddd;
113
+ color: #ddd;
114
+ clear: both;
115
+ float: none;
116
+ width: 100%;
117
+ height: .1em;
118
+ margin: 0 0 1.45em;
119
+ border: none;
120
+ }
121
+
122
+ hr.space {
123
+ background: #fff;
124
+ color: #fff;
125
+ visibility: hidden;
126
+ }
127
+
128
+
129
+ /* Clearing floats without extra markup
130
+ Based on How To Clear Floats Without Structural Markup by PiE
131
+ [http://www.positioniseverything.net/easyclearing.html] */
132
+
133
+ .clearfix:after, .container:after {
134
+ content: "\0020";
135
+ display: block;
136
+ height: 0;
137
+ clear: both;
138
+ visibility: hidden;
139
+ overflow:hidden;
140
+ }
141
+ .clearfix, .container {display: block;}
142
+
143
+ /* Regular clearing
144
+ apply to column that should drop below previous ones. */
145
+
146
+ .clear { clear:both; }
@@ -0,0 +1,54 @@
1
+ begin
2
+ require 'rubygems'
3
+ gem 'rmagick'
4
+ require 'rvg/rvg'
5
+ rescue Exception => e
6
+ end
7
+
8
+ module Blueprint
9
+ # Uses ImageMagick and RMagick to generate grid.png file
10
+ class GridBuilder
11
+ begin
12
+ include Magick
13
+ rescue Exception => e
14
+ end
15
+
16
+ attr_reader :column_width, :gutter_width, :output_path, :able_to_generate
17
+
18
+ # ==== Options
19
+ # * <tt>options</tt>
20
+ # * <tt>:column_width</tt> -- Width (in pixels) of current grid column
21
+ # * <tt>:gutter_width</tt> -- Width (in pixels) of current grid gutter
22
+ # * <tt>:output_path</tt> -- Output path of grid.png file
23
+ def initialize(options={})
24
+ @able_to_generate = Magick::Long_version rescue false
25
+ return unless @able_to_generate
26
+ @column_width = options[:column_width] || Blueprint::COLUMN_WIDTH
27
+ @gutter_width = options[:gutter_width] || Blueprint::GUTTER_WIDTH
28
+ @output_path = options[:output_path] || Blueprint::SOURCE_PATH
29
+ end
30
+
31
+ # generates (overwriting if necessary) grid.png image to be tiled in background
32
+ def generate!
33
+ return false unless self.able_to_generate
34
+ total_width = self.column_width + self.gutter_width
35
+ height = 18
36
+ RVG::dpi = 100
37
+
38
+ rvg = RVG.new((total_width.to_f/RVG::dpi).in, (height.to_f/RVG::dpi).in).viewbox(0, 0, total_width, height) do |canvas|
39
+ canvas.background_fill = 'white'
40
+
41
+ canvas.g do |column|
42
+ column.rect(self.column_width - 1, height).styles(:fill => "#e8effb")
43
+ end
44
+
45
+ canvas.g do |baseline|
46
+ baseline.line(0, (height - 1), total_width, (height- 1)).styles(:fill => "#e9e9e9")
47
+ end
48
+ end
49
+
50
+ FileUtils.mkdir self.output_path unless File.exists? self.output_path
51
+ rvg.draw.write(File.join(self.output_path, "grid.png"))
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,38 @@
1
+ module Blueprint
2
+ class Namespace
3
+
4
+ # Read html to string, remove namespace if any,
5
+ # set the new namespace, and update the test file.
6
+ def initialize(path, namespace)
7
+ html = File.path_to_string(path)
8
+ remove_current_namespace(html)
9
+ add_namespace(html, namespace)
10
+ File.string_to_file(html, path)
11
+ end
12
+
13
+ # adds namespace to BP classes in a html file
14
+ def add_namespace(html, namespace)
15
+ html.gsub!(/(class=")([a-zA-Z0-9\-_ ]*)(")/) do |m|
16
+ classes = m.to_s.split('"')[1].split(' ')
17
+ classes.map! { |c| c = namespace + c }
18
+ 'class="' + classes.join(' ') + '"'
19
+ end
20
+ html
21
+ end
22
+
23
+ # removes a namespace from a string of html
24
+ def remove_current_namespace(html)
25
+ current = current_namespace(html)
26
+ html.gsub!(current, '')
27
+ html
28
+ end
29
+
30
+ # returns current namespace in test files
31
+ # based on container class
32
+ def current_namespace(html)
33
+ html =~ /class="([\S]+)container/
34
+ current_namespace = $1 if $1
35
+ current_namespace || ''
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,57 @@
1
+ module Blueprint
2
+ # parses a hash of key/value pairs, key being output CSS selectors, value being a list of CSS selectors to draw from
3
+ class SemanticClassNames
4
+ attr_accessor :class_assignments
5
+ attr_reader :namespace, :source_file
6
+
7
+ # ==== Options
8
+ # * <tt>options</tt>
9
+ # * <tt>:namespace</tt> -- Namespace to be used when matching CSS selectors to draw from
10
+ # * <tt>:source_file</tt> -- Source file to use as reference of CSS selectors. Defaults to Blueprint's generated screen.css
11
+ # * <tt>:class_assignments</tt> -- Hash of key/value pairs, key being output CSS selectors, value being a list of CSS selectors to draw from
12
+ def initialize(options = {})
13
+ @namespace = options[:namespace] || ""
14
+ @source_file = options[:source_file] || File.join(Blueprint::BLUEPRINT_ROOT_PATH, 'screen.css')
15
+ self.class_assignments = options[:class_assignments] || {}
16
+ end
17
+
18
+ # Returns a CSS string of semantic selectors and associated styles
19
+ # ==== Options
20
+ # * <tt>assignments</tt> -- Hash of key/value pairs, key being output CSS selectors, value being a list of CSS selectors to draw from; defaults to what was passed in constructor or empty hash
21
+ def css_from_assignments(assignments = {})
22
+ assignments ||= self.class_assignments
23
+
24
+ # define a wrapper hash to hold all the new CSS assignments
25
+ output_css = {}
26
+
27
+ #loads full stylesheet into an array of hashes
28
+ blueprint_assignments = CSSParser.new(File.path_to_string(self.source_file)).parse
29
+
30
+ # iterates through each class assignment ('#footer' => '.span-24', '#header' => '.span-24')
31
+ assignments.each do |semantic_class, blueprint_classes|
32
+ # gathers all BP classes we're going to be mimicing
33
+ blueprint_classes = blueprint_classes.split(/,|\s/).find_all {|c| !c.blank? }.flatten.map {|c| c.strip }
34
+ classes = []
35
+ # loop through each BP class, grabbing the full hash (containing tags, index, and CSS rules)
36
+ blueprint_classes.each do |bp_class|
37
+ match = bp_class.include?('.') ? bp_class.gsub(".", ".#{self.namespace}") : ".#{self.namespace}#{bp_class}"
38
+ classes << blueprint_assignments.find_all {|line| line[:tags] =~ Regexp.new(/^([\w\.\-\:]+, ?)*#{match}(, ?[\w\.\-\:]+)*$/) }.uniq
39
+ end
40
+
41
+ # clean up the array
42
+ classes = classes.flatten.uniq
43
+
44
+ # set the semantic class to the rules gathered in classes, sorted by index
45
+ # this way, the styles will be applied in the correct order from top of file to bottom
46
+ output_css[semantic_class] = "#{classes.sort_by {|i| i[:idx]}.map {|i| i[:rules]}}"
47
+ end
48
+
49
+ # return the css in proper format
50
+ css = ""
51
+ output_css.each do |tags, rules|
52
+ css += "#{tags} {#{rules}}\n"
53
+ end
54
+ css
55
+ end
56
+ end
57
+ end