csswaxer 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/README.md +4 -3
  2. data/VERSION +1 -1
  3. data/lib/csswaxer.rb +70 -54
  4. data/lib/example.css +2 -33
  5. metadata +5 -5
data/README.md CHANGED
@@ -9,18 +9,19 @@ Ruby command that prettifies CSS files grouping lines by property rather than by
9
9
  ## Examples ##
10
10
 
11
11
  csswaxer http://rubygems.org/stylesheets/all.css
12
- csswaxer http://vlex.cachefly.net/stylesheets/new.css
12
+ csswaxer http://vlex.com/stylesheets/new.css
13
13
 
14
14
  ## To do ##
15
15
 
16
16
  * Accept CSS files with commands split on multiple lines
17
- * Accept local CSS files, not only remote ones
18
17
  * Accept different media types, not only screen
19
18
  * Contain every possible CSS property
20
- * Re-organize families of properties in the output (first font, then text...)
21
19
 
22
20
  ## History ##
23
21
 
22
+ v0.0.5 2010/04/32
23
+ Fixed a bug; now respects multiple property values for the same selector
24
+
24
25
  v0.0.4 2010/03/31
25
26
  Fixed a bug; now also respects !important statements
26
27
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
data/lib/csswaxer.rb CHANGED
@@ -9,7 +9,6 @@ require 'open-uri'
9
9
  module CssWaxer
10
10
  class << self
11
11
 
12
- # include CssParser
13
12
  # Return a waxed version of a dirty CSS file, either local or remote
14
13
  def wax(dirty_css)
15
14
  # Open either a local or a remote file depending on the path
@@ -19,48 +18,65 @@ module CssWaxer
19
18
  else
20
19
  parser.load_file! dirty_css
21
20
  end
22
- # Track values that appear for each property to avoid duplication
23
- appeared_values = {}
24
- unrecognized_properties = []
25
- css_properties = css_families.values.flatten
26
- css_properties.each{|property| appeared_values[property] = []}
27
- # Parse every selector and every rule in the stylesheet
28
- parser.each_selector(:screen).each do |selector|
29
- selector[:rules].each_selector do |selectors, declarations, specificity|
30
- selector[:rules].each_declaration do |property, value, importance|
31
- # Clean recognized properties, leave untouched the remaining ones
32
- if css_properties.include?(property) && !value.nil?
33
- if same_value = appeared_values[property].assoc([value, importance])
34
- same_value << selectors
35
- else
36
- appeared_values[property] << [[value, importance], selectors]
37
- end
38
- else
39
- unrecognized_properties << [property, value, importance, selectors]
21
+
22
+ properties = {}
23
+ # First make sure to take the most important property values for each selector
24
+ parser.each_selector(:screen).each do |ruleset|
25
+ declarations = ruleset[:rules].instance_variable_get(:@declarations)
26
+ ruleset[:rules].selectors.each do |selector|
27
+ declarations.each do |property, values|
28
+ triple = [selector.strip, [values[:value].strip, values[:is_important]]]
29
+ unless properties.has_key?(property)
30
+ properties[property] = []
31
+ end
32
+ previous_value = properties[property].assoc(selector.strip)
33
+ if previous_value.nil?
34
+ properties[property] << triple
35
+ # Overwrite only if more important than the existing value
36
+ elsif !previous_value[1][1] || values[:is_important]
37
+ previous_value[1] = [values[:value].strip, values[:is_important]]
40
38
  end
39
+ end
40
+ end
41
+ end
42
+
43
+ # Next merge selectors with the same values for each property to save space
44
+ merged = {}
45
+ properties.each do |property, values|
46
+ merged[property] = []
47
+ values.each do |triple|
48
+ if previous_value = merged[property].assoc(triple[1])
49
+ previous_value[1] << triple[0]
50
+ else
51
+ merged[property] << [triple[1], [triple[0]]]
41
52
  end
42
53
  end
43
54
  end
44
-
55
+
56
+ # Finally write to CSS, ordered by family
45
57
  css_families.each do |family, properties|
46
- next if properties.all?{|property| appeared_values[property].empty?}
58
+ next unless merged.keys.any?{|property| properties.include? property}
47
59
  puts titleize(family)
48
60
  properties.each do |property|
49
- next if appeared_values[property].empty?
61
+ next unless merged.has_key? property
50
62
  puts "\n/* #{property} */"
51
- appeared_values[property].each do |p|
52
- value, importance = p.shift
53
- important = " !important" if importance
54
- puts "#{p.join(", ")}\t{#{property}: #{value}#{important}}"
63
+ merged[property].each do |values, selectors|
64
+ important = " !important" if values[1]
65
+ puts "#{selectors.join(", ")}\t{#{property}: #{values[0]}#{important}}"
55
66
  end
67
+ merged.delete property
56
68
  end
57
69
  end
58
-
59
- unless unrecognized_properties.empty?
60
- puts titleize("others")
61
- unrecognized_properties.each do |property, value, importance, selectors|
62
- important = " !important" if importance
63
- puts "#{selectors}\t{#{property}: #{value}#{important}}"
70
+ # Write the remaining (unrecognized) properties at the end
71
+ unless merged.empty?
72
+ puts titleize("Unrecognized properties")
73
+ merged.each do |property, values_and_selectors|
74
+ puts "\n/* #{property} */"
75
+ values_and_selectors.each do |values, selectors|
76
+ important = " !important" if values[1]
77
+ puts "#{selectors.join(", ")}\t{#{property}: #{values[0]}#{important}}"
78
+ end
79
+ merged.delete property
64
80
  end
65
81
  end
66
82
  end
@@ -73,28 +89,28 @@ module CssWaxer
73
89
 
74
90
  def css_families
75
91
  # Based on the list from http://www.eskimo.com/~bloo/indexdot/css/
76
- {
77
- 'Typography' => %w{font-family font-size font-style font-variant font-weight font font-size-adjust font-stretch},
78
- 'Text' => %w{word-spacing letter-spacing white-space word-wrap text-align text-align-last text-decoration text-transform text-shadow text-indent text-underline-position},
79
- 'Colors' => %w{color background-color layer-background-color border-top-color border-right-color border-bottom-color border-left-color border-color scrollbar-face-color scrollbar-arrow-color scrollbar-base-color scrollbar-shadow-color scrollbar-darkshadow-color scrollbar-highlight-color scrollbar-3dlight-color scrollbar-track-color outline-color},
80
- 'Backgrounds' => %w{layer-background-image background-image background-repeat background-attachment background-position background-position-x background-position-y background},
81
- 'Outlines' => %w{outline-style outline-width outline},
82
- 'Lists' => %w{marker-offset list-style-type list-style-position list-style-image list-style},
83
- 'Tables' => %w{border-collapse border-spacing caption-side empty-cells speak-header table-layout},
84
- 'Layout' => %w{display visibility position float clear},
85
- 'Sizes' => %w{width min-width max-width line-height height min-height max-height},
86
- 'Positions' => %w{top right bottom left vertical-align overflow overflow-x overflow-y text-overflow clip z-index},
87
- 'Margins' => %w{margin-top margin-right margin-bottom margin-left margin},
88
- 'Paddings' => %w{padding-top padding-right padding-bottom padding-left padding},
89
- 'Borders' => %w{border-top border-right border-bottom border-left border-top-width border-right-width border-bottom-width border-left-width border-width border-top-style border-right-style border-bottom-style border-left-style border-style border},
90
- 'Dynamic' => %w{accelerator cursor filter behavior zoom},
91
- 'Generated' =>%w{content counter-reset counter-increment include-source quotes},
92
- 'International' => %w{unicode-bidi direction ruby-align ruby-overhang ruby-position line-break word-break writing-mode ime-mode text-justify text-autospace text-kashida-space layout-flow layout-grid-mode layout-grid-type layout-grid-line layout-grid-char layout-grid-char-spacing layout-grid },
93
- 'Printing' => %w{page-break-before page-break-inside page-break-after page size marks widows orphans},
94
- 'Aural' => %w{volume stress richness azimuth elevation voice-family speak-punctuation speak-numeral speak pitch-range pitch speech-rate play-during pause-before pause-after pause cue-before cue-after cue},
95
- 'Opera' => %w{-replace -set-link-source -use-link-source},
96
- 'Mozilla' => %w{-moz-binding -moz-border-radius -moz-border-radius-topleft -moz-border-radius-topright -moz-border-radius-bottomright -moz-border-radius-bottomleft -moz-border-top-colors -moz-border-right-colors -moz-border-bottom-colors -moz-border-left-colors -moz-opacity -moz-outline -moz-outline-color -moz-outline-style -moz-outline-width -moz-user-focus -moz-user-input -moz-user-modify -moz-user-select},
97
- }
92
+ [
93
+ ['Typography', %w{font-family font-size font-style font-variant font-weight font font-size-adjust font-stretch}],
94
+ ['Text', %w{word-spacing letter-spacing white-space word-wrap text-align text-align-last text-decoration text-transform text-shadow text-indent text-underline-position}],
95
+ ['Colors', %w{color background-color layer-background-color border-top-color border-right-color border-bottom-color border-left-color border-color scrollbar-face-color scrollbar-arrow-color scrollbar-base-color scrollbar-shadow-color scrollbar-darkshadow-color scrollbar-highlight-color scrollbar-3dlight-color scrollbar-track-color outline-color}],
96
+ ['Backgrounds', %w{layer-background-image background-image background-repeat background-attachment background-position background-position-x background-position-y background}],
97
+ ['Outlines', %w{outline-style outline-width outline}],
98
+ ['Lists', %w{marker-offset list-style-type list-style-position list-style-image list-style}],
99
+ ['Tables', %w{border-collapse border-spacing caption-side empty-cells speak-header table-layout}],
100
+ ['Layout', %w{display visibility position float clear}],
101
+ ['Sizes', %w{width min-width max-width line-height height min-height max-height}],
102
+ ['Positions', %w{top right bottom left vertical-align overflow overflow-x overflow-y text-overflow clip z-index}],
103
+ ['Margins', %w{margin-top margin-right margin-bottom margin-left margin}],
104
+ ['Paddings', %w{padding-top padding-right padding-bottom padding-left padding}],
105
+ ['Borders', %w{border-top border-right border-bottom border-left border-top-width border-right-width border-bottom-width border-left-width border-width border-top-style border-right-style border-bottom-style border-left-style border-style border}],
106
+ ['Dynamic', %w{accelerator cursor filter behavior zoom}],
107
+ ['Generated', %w{content counter-reset counter-increment include-source quotes}],
108
+ ['International', %w{unicode-bidi direction ruby-align ruby-overhang ruby-position line-break word-break writing-mode ime-mode text-justify text-autospace text-kashida-space layout-flow layout-grid-mode layout-grid-type layout-grid-line layout-grid-char layout-grid-char-spacing layout-grid }],
109
+ ['Printing', %w{page-break-before page-break-inside page-break-after page size marks widows orphans}],
110
+ ['Aural', %w{volume stress richness azimuth elevation voice-family speak-punctuation speak-numeral speak pitch-range pitch speech-rate play-during pause-before pause-after pause cue-before cue-after cue}],
111
+ ['Opera', %w{-replace -set-link-source -use-link-source}],
112
+ ['Mozilla', %w{-moz-binding -moz-border-radius -moz-border-radius-topleft -moz-border-radius-topright -moz-border-radius-bottomright -moz-border-radius-bottomleft -moz-border-top-colors -moz-border-right-colors -moz-border-bottom-colors -moz-border-left-colors -moz-opacity -moz-outline -moz-outline-color -moz-outline-style -moz-outline-width -moz-user-focus -moz-user-input -moz-user-modify -moz-user-select}]
113
+ ]
98
114
  end
99
115
  end
100
116
  end
data/lib/example.css CHANGED
@@ -1,35 +1,4 @@
1
- a {line-height:12px}
1
+ a {line-height:12px; font-size: 12px;}
2
+ b,c {font-size:40px;}
2
3
  b {font-size:12px;}
3
4
  c, d {line-height: 12px}
4
- .e#f {line-height: 12px; font-weight: bold}
5
- g h {line-height: 12px; font-weight: bold;}
6
- i {line-height: .1em; font-weight: bold}
7
- j[k] {line-height: normal}
8
- lmn {line-height: 12px }
9
- o > p {line-heigddht: 12px }
10
-
11
- /* Outputs to:
12
- /* ************************************************************************** *
13
- /* TYPOGRAPHY *
14
- /* ************************************************************************** *
15
-
16
- /* font-size *
17
- b {font-size: 12px}
18
-
19
- /* font-weight *
20
- .e#f, g h, i {font-weight: bold}
21
-
22
- /* ************************************************************************** *
23
- /* SIZES *
24
- /* ************************************************************************** *
25
-
26
- /* line-height *
27
- a, c, d, .e#f, g h, lmn {line-height: 12px}
28
- i {line-height: .1em}
29
- j[k] {line-height: normal}
30
-
31
- /* ************************************************************************** *
32
- /* OTHERS *
33
- /* ************************************************************************** *
34
- o > p {line-heigddht: 12px}
35
- */
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 4
9
- version: 0.0.4
8
+ - 5
9
+ version: 0.0.5
10
10
  platform: ruby
11
11
  authors:
12
12
  - Claudio Baccigalupo
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-31 00:00:00 +02:00
17
+ date: 2010-04-02 00:00:00 +02:00
18
18
  default_executable: csswaxer
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -31,7 +31,7 @@ dependencies:
31
31
  version: 1.0.1
32
32
  type: :runtime
33
33
  version_requirements: *id001
34
- description: CSS files are written with a focus on selectors, so that all properties related to a tag, class or id are grouped together. This makes it hard to a have a clear overview of the style; for instance which colors and fonts are used in the whole site. CSS Waxer reorganizes CSS files focusing on properties, so that every font-related property is packed together, followed by colors, backgrounds, layouts and so on.
34
+ description: "CSS Waxer refactors CSS files bringing the focus on properties, rather than on selectors. Typically, CSS files are written by groups of selectors, you first specify all the properties of <body>, then those of <h1>, #header, and so on. This makes it hard to catch a glimpse of the overall style of a site, such as the entire list of colors used, the fonts, or the dimensions. CSS Waxer reorders the lines of a CSS files so that properties are grouped together by family. In this way, you can rapidly check together all the fonts used, the colors, backgrounds, layouts and so on for the whole site."
35
35
  email: claudiob@gmail.com
36
36
  executables:
37
37
  - csswaxer
@@ -77,6 +77,6 @@ rubyforge_project:
77
77
  rubygems_version: 1.3.6
78
78
  signing_key:
79
79
  specification_version: 3
80
- summary: "Command-line tool that makes stylesheet files more readable, grouping lines by property (typography, color, layout, \xE2\x80\xA6) rather than by selector"
80
+ summary: Command-line tool that makes stylesheet files more readable, grouping lines by property (typography, color, layout, etc.) rather than by selector
81
81
  test_files: []
82
82