blueprintr 0.1.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.
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