cssensible 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ # Changelog
2
+
3
+ ## 0.2 (July 8th, 2010)
4
+
5
+ * command line interface actually usable
6
+
7
+
8
+ ## 0.1 (July 7th, 2010)
9
+
10
+ * initial release
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2010 Dominik Habersack
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,53 @@
1
+ # CSSensible
2
+
3
+ CSSensible finds sensible default values for `font-size` and `line-height` by identifying available vertical grids.
4
+
5
+
6
+ ## Usage
7
+
8
+ You can find sensible vertical grids for one or several font-sizes.
9
+
10
+ $ ruby bin/cssensible [options] font-size [font-size font-size ...]
11
+
12
+ Options:
13
+
14
+ --line-height-ratio [EM] Minimum em-value all line-heights should have
15
+ -h, --help Shop help
16
+ --version Show version
17
+
18
+
19
+ ## Examples
20
+
21
+ # finds sensible grids including a font-size of 12px
22
+ $ ruby bin/cssensible 12
23
+
24
+ # finds sensible grids including both 12px and 16px
25
+ $ ruby bin/cssensible 12 16
26
+
27
+ # finds sensible grids including both 12px and 16px where the resulting
28
+ # line-height for every font-size is at least 1.3em
29
+ $ ruby bin/cssensible --line-height-ratio 1.3 12 16
30
+
31
+
32
+ ## Documentation
33
+
34
+ View the HTML document:
35
+ $ open doc/index.html
36
+
37
+ ## Problems?
38
+
39
+ Please open [an issue][issues].
40
+
41
+
42
+ ## Author
43
+
44
+ * Dominik Habersack / <dhabersack@gmail.com>
45
+
46
+
47
+ ## License
48
+
49
+ CSSensible is released under the [MIT License][license].
50
+
51
+
52
+ [issues]: http://github.com/dhabersack/cssensible/issues
53
+ [license]: http://github.com/dhabersack/cssensible/blob/master/LICENSE
@@ -0,0 +1,3 @@
1
+ require 'rake'
2
+
3
+
@@ -0,0 +1,5 @@
1
+ # require 'cssensible/runner'
2
+ require_relative '../lib/cssensible/runner'
3
+
4
+ runner = CSSensible::Runner.new(ARGV)
5
+ runner.run
@@ -0,0 +1,7 @@
1
+ require 'cssensible/em_value'
2
+ require 'cssensible/finder'
3
+ require 'cssensible/options'
4
+ require 'cssensible/ruby_extensions'
5
+ require 'cssensible/runner'
6
+ require 'cssensible/version'
7
+ require 'cssensible/vertical_grid'
@@ -0,0 +1,36 @@
1
+ require_relative 'ruby_extensions'
2
+
3
+ # Implements em-values used in Cascading Style Sheets.
4
+ module CSSensible
5
+ class EmValue < Numeric
6
+ include Comparable
7
+
8
+ # The maximum number of decimal places allowed in an em-value.
9
+ MAX_DECIMAL_PLACES = 3
10
+
11
+ attr_reader :value
12
+
13
+ def <=>(other)
14
+ @value <=> other.value
15
+ end
16
+
17
+ # Returns a new em-value based on the value passed to new.
18
+ def initialize(value)
19
+ @value = value.to_f
20
+ end
21
+
22
+ # :call-seq:
23
+ # usable? -> true or false
24
+ #
25
+ # Returns true if the em-value has no more decimal places than specified in
26
+ # MAX_DECIMAL_PLACES.
27
+ def usable?
28
+ # shift decimal point and check if no decimal places remain
29
+ @value.shift_decimal_point(MAX_DECIMAL_PLACES).decimal_places.zero?
30
+ end
31
+
32
+ def to_s
33
+ @value.to_s
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,68 @@
1
+ require_relative 'em_value'
2
+ require_relative 'vertical_grid'
3
+
4
+ # Finds sensible vertical grids to use in Cascading Style Sheets.
5
+ module CSSensible
6
+ class Finder
7
+ # A line-height should be at least this em-value to improve readability.
8
+ # MIN_LINE_HEIGHT_EM_VALUE = EmValue.new(1.3)
9
+
10
+ # Size in pixel a font should at least be to be readable
11
+ MIN_FONT_SIZE_PX = 10
12
+
13
+ attr_reader :font_size
14
+
15
+ # Returns a new Vertical Grid Finder based on the font size passed to new.
16
+ def initialize(font_sizes, min_line_height_em)
17
+ @font_sizes = font_sizes.sort
18
+ # set minimum line-height to value passed OR 1.0 IF NIL
19
+ # TODO this is probably wrong
20
+ @min_line_height_em = min_line_height_em || 1.0
21
+ end
22
+
23
+ # Finds sensible vertical grids based on the parameters given in new.
24
+ def find
25
+ vertical_grids = []
26
+ line_heights = []
27
+
28
+ # go through all line-heights that could possibly include all font-sizes
29
+ (@font_sizes.last .. @font_sizes.last * 2).each do |line_height|
30
+ line_height_usable = true
31
+
32
+ # go through all of the required font-sizes
33
+ @font_sizes.each do |font_size|
34
+ # check if line-height for this font-size can be expressed in 'em'
35
+ line_height_em = EmValue.new(line_height / font_size.to_f)
36
+
37
+ unless line_height_em.usable?
38
+ line_height_usable = false
39
+ break
40
+ end
41
+ end
42
+
43
+ line_heights << line_height if line_height_usable
44
+ end
45
+
46
+ line_heights.each do |line_height|
47
+ font_sizes_to_line_height = {}
48
+
49
+ (MIN_FONT_SIZE_PX .. line_height).each do |font_size|
50
+ line_height_em = EmValue.new(line_height / font_size.to_f)
51
+ font_sizes_to_line_height[font_size] = line_height_em if line_height_em.usable? && line_height_em >= @min_line_height_em
52
+ end
53
+
54
+ if font_sizes_to_line_height.keys.include_all?(@font_sizes)
55
+ vertical_grids << VerticalGrid.new(@font_sizes, line_height, font_sizes_to_line_height) unless font_sizes_to_line_height.empty?
56
+ end
57
+ end
58
+
59
+ vertical_grids
60
+
61
+ # line_heights = {}
62
+ # (fontsize .. fontsize * 2).each do |lineheight|
63
+ # lineheight_ratio = EmValue.new(lineheight / fontsize.to_f)
64
+ # line_heights[lineheight] = lineheight_ratio if lineheight_ratio.usable?
65
+ # end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,62 @@
1
+ require 'optparse'
2
+ require_relative 'em_value'
3
+ require_relative 'version'
4
+
5
+ # Option parser.
6
+ module CSSensible
7
+ class Options
8
+ # Default line-height.
9
+ DEFAULT_LINE_HEIGHT = EmValue.new(1.0)
10
+
11
+ attr_reader :font_sizes_to_include
12
+ attr_reader :line_height
13
+
14
+ def initialize(argv)
15
+ @font_sizes_to_include = []
16
+ @line_height = DEFAULT_LINE_HEIGHT
17
+ parse(argv)
18
+ argv.each { |arg| @font_sizes_to_include << arg.to_i }
19
+ end
20
+
21
+ private
22
+
23
+ def parse(argv)
24
+ OptionParser.new do |opts|
25
+ opts.banner = 'Usage: cssensible [options] font-size [font-size font-size ...]'
26
+
27
+ opts.separator ''
28
+ opts.separator 'Specific options:'
29
+
30
+ opts.on('-l', '--line-height [EM]', Float, 'Minimum em-value a all line-heights should have') do |l|
31
+ @line_height = l
32
+ end
33
+
34
+ # TODO implement this
35
+ # opts.on('-v', '--verbose', 'Run verbosely') do |v|
36
+ # @verbose = v
37
+ # end
38
+
39
+ opts.separator ''
40
+ opts.separator 'Common options:'
41
+
42
+ opts.on_tail('-h', '--help', 'Show this message') do
43
+ puts opts
44
+ exit
45
+ end
46
+
47
+ opts.on_tail('--version', 'Show version') do
48
+ puts CSSensible::VERSION
49
+ exit
50
+ end
51
+
52
+ begin
53
+ argv = ['-h'] if argv.empty?
54
+ opts.parse!(argv)
55
+ rescue OptionParser::ParseError => e
56
+ STDERR.puts e.message, "\n", opts
57
+ exit(-1)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,44 @@
1
+ # Extensions to built-in Ruby classes.
2
+ class Array
3
+ # :call-seq:
4
+ # include_all?(array) -> true or false
5
+ #
6
+ # Returns true if all elements of the given array is present in self, false
7
+ # otherwise.
8
+ #
9
+ # a = ["a", "b", "c"]
10
+ # a.include_all?(["a", "c"]) # => true
11
+ # a.include_all?(["a", "b", "c", "d"]) # => false
12
+ def include_all?(array)
13
+ array.each do |element|
14
+ return false unless self.include?(element)
15
+ end
16
+ return true
17
+ end
18
+ end
19
+
20
+ # Extensions to built-in Ruby classes.
21
+ class Float
22
+ # :call-seq:
23
+ # decimal_places -> int or nil
24
+ #
25
+ # Returns all decimal places.
26
+ #
27
+ # 0.125.decimal_places # => 125
28
+ # 0.0.decimal_places # => 0
29
+ def decimal_places
30
+ self.to_s.split(".")[1].to_f
31
+ end
32
+
33
+ # :call-seq:
34
+ # shift_decimal_point(decimal_places) -> a_float
35
+ #
36
+ # Returns a copy of self with the decimal point shifted _decimal_places_
37
+ # places to the right (left for negative numbers).
38
+ #
39
+ # 0.125.shift_decimal_point(3) # => 125.0
40
+ # 0.125.shift_decimal_point(-3) # => 0.000125
41
+ def shift_decimal_point(decimal_places)
42
+ self * (10 ** decimal_places)
43
+ end
44
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'finder'
2
+ require_relative 'options'
3
+
4
+ module CSSensible
5
+ class Runner
6
+ def initialize(argv)
7
+ @options = Options.new(argv)
8
+ end
9
+
10
+ def run
11
+ finder = Finder.new(@options.font_sizes_to_include, @options.line_height)
12
+ vertical_grids = finder.find
13
+
14
+ if vertical_grids
15
+ vertical_grids.each { |vertical_grid| puts "#{vertical_grid}\n" }
16
+ else
17
+ puts "No grids found."
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ module CSSensible
2
+ # The current version of CSSensible.
3
+ VERSION = "0.2.0"
4
+ end
@@ -0,0 +1,28 @@
1
+ # Implements a vertical grid to use in Cascading Style Sheets.
2
+ module CSSensible
3
+ class VerticalGrid
4
+ # Returns a new vertical grid.
5
+ def initialize(base_font_sizes, line_height, font_sizes_to_line_height)
6
+ @base_font_sizes = base_font_sizes
7
+ @line_height = line_height
8
+ @font_sizes_to_line_height = font_sizes_to_line_height
9
+ end
10
+
11
+ # Returns em-value to calculate 10px based on font_size or nil if the value
12
+ # is not usable (see EmValue.usable?)
13
+ def ten_pixel
14
+ ten_pixel.usable? ? ten_pixel : nil
15
+ end
16
+
17
+ def to_s
18
+ vertical_grid = "line-height: #{@line_height}px\n"
19
+ vertical_grid += "#{@font_sizes_to_line_height.size} font-size(s):\n"
20
+
21
+ @font_sizes_to_line_height.each do |font_size, line_height_em|
22
+ vertical_grid += " font-size: #{font_size}px#{'*' if @base_font_sizes.include?(font_size)}\tline-height: #{line_height_em}em\n"
23
+ end
24
+
25
+ vertical_grid
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ require 'test/unit'
2
+ require_relative '../lib/cssensible/em_value'
3
+
4
+ class TestEmValue < Test::Unit::TestCase
5
+ # Test inclusion of 'Comparable'
6
+ def test_compare_values
7
+ assert 1, CSSensible::EmValue.new(1.5) > CSSensible::EmValue.new(1.0)
8
+ end
9
+
10
+ # Tests if em-values with up to three decimal places are considered _usable_.
11
+ def test_values_with_no_more_than_three_decimal_places_are_usable
12
+ assert CSSensible::EmValue.new(1).usable?
13
+ assert CSSensible::EmValue.new(1.5).usable?
14
+ assert CSSensible::EmValue.new(1.25).usable?
15
+ assert CSSensible::EmValue.new(1.025).usable?
16
+ end
17
+
18
+ # Tests if em-values with more than three decimal places are considered
19
+ # _unusable_.
20
+ def test_values_with_more_than_three_decimal_places_are_not_usable
21
+ assert !CSSensible::EmValue.new(1.0125).usable?
22
+ assert !CSSensible::EmValue.new(1.125675).usable?
23
+ end
24
+
25
+ # Tests if trailing zeros in decimal places impact if an em-value is
26
+ # considered _usable_.
27
+ def test_trailing_zeros_do_not_impact_usability
28
+ assert CSSensible::EmValue.new(1.0000).usable?
29
+ assert CSSensible::EmValue.new(1.1250000).usable?
30
+ end
31
+
32
+ end
@@ -0,0 +1,17 @@
1
+ require 'test/unit'
2
+ require_relative '../lib/cssensible/finder'
3
+
4
+ class TestFinder < Test::Unit::TestCase
5
+
6
+ # Test optional initialization parameter line_height.
7
+ # def test_initialize_optional_line_height_parameter
8
+ # assert_nil VerticalGridFinder.new(12).line_height, 'initialize without line_height'
9
+ # assert_equal 18, VerticalGridFinder.new(12, 18).line_height, 'initialize with line_height'
10
+ # end
11
+
12
+ # TODO test find-method
13
+ # def test_find_vertical_grids
14
+ # vertical_grids = VerticalGridFinder.new(16).find
15
+ # end
16
+
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'optparse'
2
+ require 'test/unit'
3
+ require_relative '../lib/cssensible/options'
4
+
5
+ class TestOptions < Test::Unit::TestCase
6
+
7
+ def test_specifying_a_line_height
8
+ opts = CSSensible::Options.new(['-l', "1.3"])
9
+ assert_equal 1.3, opts.line_height
10
+ end
11
+
12
+ def test_return_line_heights
13
+ opts = CSSensible::Options.new(["15", "16"])
14
+ assert_equal [15, 16], opts.font_sizes_to_include
15
+ end
16
+
17
+ end
@@ -0,0 +1,27 @@
1
+ require 'test/unit'
2
+ require_relative '../lib/cssensible/ruby_extensions'
3
+
4
+ class TestRubyExtensions < Test::Unit::TestCase
5
+
6
+ # Tests the include_all? method.
7
+ # Seriously, what else am I supposed to write here?
8
+ def test_array_include_all
9
+ a = ["a", "b", "c"]
10
+ assert a.include_all?(["a", "b"])
11
+ assert !a.include_all?(["a", "b", "c", "d"])
12
+ end
13
+
14
+ # Tests extraction of decimal places from Floats.
15
+ def test_float_get_decimal_places
16
+ assert_equal 125, 0.125.decimal_places
17
+ assert_equal 0, 0.0.decimal_places
18
+ assert_equal 0, 1.0000.decimal_places
19
+ end
20
+
21
+ # Tests shifting the decimal point arount in Floats.
22
+ def test_float_shift_decimal_point_in_floats
23
+ assert_equal 125.0, 0.125.shift_decimal_point(3)
24
+ assert_equal 0.125, 125.0.shift_decimal_point(-3)
25
+ end
26
+
27
+ end
@@ -0,0 +1,6 @@
1
+ require 'test/unit'
2
+ require_relative '../lib/cssensible/vertical_grid'
3
+
4
+ class TestVerticalGrid < Test::Unit::TestCase
5
+
6
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cssensible
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
+ platform: ruby
12
+ authors:
13
+ - Dominik Habersack
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-13 00:00:00 +12:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: CSSensible finds sensible CSS default values for font-size and line-height by identifying available vertical grids.
23
+ email: dhabersack@gmail.com
24
+ executables:
25
+ - cssensible
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - lib/cssensible/em_value.rb
32
+ - lib/cssensible/finder.rb
33
+ - lib/cssensible/options.rb
34
+ - lib/cssensible/ruby_extensions.rb
35
+ - lib/cssensible/runner.rb
36
+ - lib/cssensible/version.rb
37
+ - lib/cssensible/vertical_grid.rb
38
+ - lib/cssensible.rb
39
+ - bin/cssensible
40
+ - LICENSE
41
+ - README.md
42
+ - Rakefile
43
+ - CHANGELOG.md
44
+ - test/test_em_value.rb
45
+ - test/test_finder.rb
46
+ - test/test_options.rb
47
+ - test/test_ruby_extensions.rb
48
+ - test/test_vertical_grid.rb
49
+ has_rdoc: true
50
+ homepage: http://github.com/dhabersack/cssensible
51
+ licenses: []
52
+
53
+ post_install_message:
54
+ rdoc_options: []
55
+
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ hash: 29
64
+ segments:
65
+ - 1
66
+ - 9
67
+ version: "1.9"
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 21
74
+ segments:
75
+ - 1
76
+ - 3
77
+ - 7
78
+ version: 1.3.7
79
+ requirements: []
80
+
81
+ rubyforge_project:
82
+ rubygems_version: 1.3.7
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: Find sensible CSS defaults.
86
+ test_files:
87
+ - test/test_em_value.rb
88
+ - test/test_finder.rb
89
+ - test/test_options.rb
90
+ - test/test_ruby_extensions.rb
91
+ - test/test_vertical_grid.rb