1 | module Blueprint |
---|
2 | # parses a hash of key/value pairs, key being output CSS selectors, value |
---|
3 | # being a list of CSS selectors to draw from |
---|
4 | class SemanticClassNames |
---|
5 | attr_accessor :class_assignments |
---|
6 | attr_reader :namespace, :source_file |
---|
7 | |
---|
8 | # ==== Options |
---|
9 | # * <tt>options</tt> |
---|
10 | # * <tt>:namespace</tt> -- Namespace to be used when matching CSS selectors to draw from |
---|
11 | # * <tt>:source_file</tt> -- Source file to use as reference of CSS selectors. Defaults to Blueprint's generated screen.css |
---|
12 | # * <tt>:class_assignments</tt> -- Hash of key/value pairs, key being output CSS selectors, value being a list of CSS selectors to draw from |
---|
13 | def initialize(options = {}) |
---|
14 | @namespace = options[:namespace] || "" |
---|
15 | @source_file = options[:source_file] || File.join(Blueprint::BLUEPRINT_ROOT_PATH, "screen.css") |
---|
16 | self.class_assignments = options[:class_assignments] || {} |
---|
17 | end |
---|
18 | |
---|
19 | # Returns a CSS string of semantic selectors and associated styles |
---|
20 | # ==== Options |
---|
21 | # * <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 |
---|
22 | def css_from_assignments(assignments = {}) |
---|
23 | assignments ||= self.class_assignments |
---|
24 | |
---|
25 | # define a wrapper hash to hold all the new CSS assignments |
---|
26 | output_css = {} |
---|
27 | |
---|
28 | #loads full stylesheet into an array of hashes |
---|
29 | blueprint_assignments = CSSParser.new(File.path_to_string(self.source_file)).parse |
---|
30 | |
---|
31 | # iterates through each class assignment ('#footer' => '.span-24', '#header' => '.span-24') |
---|
32 | assignments.each do |semantic_class, blueprint_classes| |
---|
33 | # gathers all BP classes we're going to be mimicing |
---|
34 | blueprint_classes = blueprint_classes.split(/,|\s/).select {|c| !c.blank? }.flatten.map {|c| c.strip } |
---|
35 | classes = [] |
---|
36 | # loop through each BP class, grabbing the full hash (containing tags, index, and CSS rules) |
---|
37 | blueprint_classes.each do |bp_class| |
---|
38 | match = if bp_class.include?(".") |
---|
39 | bp_class.gsub(".", ".#{self.namespace}") |
---|
40 | else |
---|
41 | ".#{self.namespace}#{bp_class}" |
---|
42 | end |
---|
43 | classes << blueprint_assignments.select do |line| |
---|
44 | line[:tags] =~ Regexp.new(/^([\w\.\-\:]+, ?)*#{match}(, ?[\w\.\-\:]+)*$/) |
---|
45 | end.uniq |
---|
46 | end |
---|
47 | |
---|
48 | # clean up the array |
---|
49 | classes = classes.flatten.uniq |
---|
50 | |
---|
51 | # set the semantic class to the rules gathered in classes, sorted by index |
---|
52 | # this way, the styles will be applied in the correct order from top of file to bottom |
---|
53 | output_css[semantic_class] = "#{classes.sort_by {|i| i[:idx] }.map {|i| i[:rules] }}" |
---|
54 | end |
---|
55 | |
---|
56 | # return the css in proper format |
---|
57 | css = "" |
---|
58 | output_css.each do |tags, rules| |
---|
59 | css += "#{tags} {#{rules}}\n" |
---|
60 | end |
---|
61 | css |
---|
62 | end |
---|
63 | end |
---|
64 | end |
---|