Skip to content
This repository was archived by the owner on Mar 1, 2022. It is now read-only.

Commit c84981f

Browse files
committed
1 parent 6d97c85 commit c84981f

File tree

6 files changed

+161
-14
lines changed

6 files changed

+161
-14
lines changed

lib/csscss.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@
2727
require "csscss/parser/border_side"
2828
require "csscss/parser/border"
2929
require "csscss/parser/outline"
30+
require "csscss/parser/font"
3031

lib/csscss/parser/common.rb

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,25 @@ module Common
55

66
UNITS = %w(px em ex in cm mm pt pc)
77

8-
rule(:space) { match["\s"].repeat(1) }
9-
rule(:space?) { space.maybe }
10-
rule(:number) { match["0-9"] }
11-
rule(:numbers) { number.repeat(1) }
12-
rule(:decimal) { numbers >> str(".").maybe >> numbers.maybe }
13-
rule(:percent) { decimal >> stri("%") >> space? }
14-
rule(:length) { decimal >> stri_list(UNITS) >> space? }
15-
rule(:inherit) { stri("inherit") }
16-
rule(:eof) { any.absent? }
17-
rule(:nada) { any.repeat.as(:nada) }
8+
rule(:space) { match["\s"].repeat(1) }
9+
rule(:space?) { space.maybe }
10+
rule(:number) { match["0-9"] }
11+
rule(:numbers) { number.repeat(1) }
12+
rule(:decimal) { numbers >> str(".").maybe >> numbers.maybe }
13+
rule(:percent) { decimal >> stri("%") >> space? }
14+
rule(:length) { decimal >> stri_list(UNITS) >> space? }
15+
rule(:identifier) { match["a-zA-Z"].repeat(1) }
16+
rule(:inherit) { stri("inherit") }
17+
rule(:eof) { any.absent? }
18+
rule(:nada) { any.repeat.as(:nada) }
1819

1920
rule(:http) {
2021
(match['a-zA-Z.:/'] | str('\(') | str('\)')).repeat >> space?
2122
}
2223

2324
rule(:url) {
2425
stri("url") >> parens do
25-
(double_quoted { http } >> space?) |
26-
(single_quoted { http } >> space?) |
26+
(any_quoted { http } >> space?) |
2727
http
2828
end
2929
}
@@ -65,6 +65,10 @@ def single_quoted(&block)
6565
between("'", "'", &block)
6666
end
6767

68+
def any_quoted(&block)
69+
double_quoted(&block) | single_quoted(&block)
70+
end
71+
6872
def stri_list(list)
6973
list.map {|u| stri(u) }.reduce(:|)
7074
end

lib/csscss/parser/font.rb

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
module Csscss
2+
module Parser
3+
module Font
4+
extend Parser::Base
5+
6+
class Parser < Parslet::Parser
7+
include Common
8+
9+
rule(:literal_font) {
10+
symbol_list(%w(caption icon menu message-box
11+
small-caption status-bar))
12+
}
13+
14+
rule(:font_style) { symbol_list(%w(normal italic oblique)) }
15+
rule(:font_variant) { symbol_list(%w(normal small-caps)) }
16+
rule(:font_weight) {
17+
symbol_list(%w(normal bold bolder lighter 100 200 300 400 500 600 700 800 900))
18+
}
19+
20+
rule(:font_size_absolute) {
21+
symbol_list(%w(xx-small x-small small medium
22+
large x-large xx-large))
23+
}
24+
25+
rule(:font_size_relative) { symbol_list(%w(larger smaller)) }
26+
27+
rule(:font_size) {
28+
font_size_absolute | font_size_relative | length | percent
29+
}
30+
31+
rule(:line_height) {
32+
symbol("/") >> (
33+
symbol("normal") | (length | percent | numbers) >> space?
34+
).as(:line_height_value)
35+
}
36+
37+
rule(:font_family) {
38+
family = identifier | any_quoted { identifier >> (space? >> identifier).repeat }
39+
family >> (symbol(",") >> font_family).maybe
40+
}
41+
42+
rule(:font) {
43+
(
44+
symbol("inherit") >> eof | (
45+
(
46+
literal_font.maybe.as(:literal_font) |
47+
font_style.maybe.as(:font_style) >>
48+
font_variant.maybe.as(:font_variant) >>
49+
font_weight.maybe.as(:font_weight) >>
50+
51+
font_size.as(:font_size) >>
52+
line_height.maybe.as(:line_height) >>
53+
font_family.as(:font_family)
54+
)
55+
)
56+
).as(:font)
57+
}
58+
root(:font)
59+
end
60+
61+
class Transformer < Parslet::Transform
62+
rule(font: simple(:inherit)) {[]}
63+
rule(font: {literal_font:simple(:literal)}) {[]}
64+
65+
rule(line_height_value: simple(:value)) { value }
66+
67+
rule(font: {
68+
font_style: simple(:font_style),
69+
font_variant: simple(:font_variant),
70+
font_weight: simple(:font_weight),
71+
font_size: simple(:font_size),
72+
line_height: simple(:line_height),
73+
font_family: simple(:font_family)
74+
}) {|context|
75+
[].tap do |declarations|
76+
context.each do |property, value|
77+
declarations << Declaration.from_parser(property.to_s.gsub("_", "-"), value, property != :font_family) if value
78+
end
79+
end
80+
}
81+
82+
#rule(outline: {
83+
#outline_width:simple(:width),
84+
#outline_style:simple(:style),
85+
#outline_color:simple(:color)
86+
#}) {
87+
#[].tap do |declarations|
88+
#declarations << Declaration.from_parser("outline-width", width) if width
89+
#declarations << Declaration.from_parser("outline-style", style) if style
90+
#declarations << Declaration.from_parser("outline-color", color) if color
91+
#end
92+
#}
93+
end
94+
end
95+
end
96+
end

lib/csscss/redundancy_analyzer.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ def shorthand_parser(property)
119119
when "border-style" then Parser::BorderStyle
120120
when "border-color" then Parser::BorderColor
121121
when "outline" then Parser::Outline
122+
when "font" then Parser::Font
122123
when "border-top", "border-right", "border-bottom", "border-left"
123124
Parser::BorderSide
124125
end

lib/csscss/types.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ def self.from_csspool(dec)
44
new(dec.property.to_s.downcase, dec.expressions.join(" ").downcase)
55
end
66

7-
def self.from_parser(property, value)
8-
new(property.to_s, value.to_s.downcase.strip)
7+
def self.from_parser(property, value, clean = true)
8+
value = value.to_s
9+
value = value.downcase if clean
10+
new(property.to_s, value.strip)
911
end
1012

1113
def derivative?

test/csscss/parser/font_test.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
require "test_helper"
2+
3+
module Csscss::Parser
4+
module Font
5+
describe self do
6+
include CommonParserTests
7+
8+
before do
9+
@parser = Parser.new
10+
@trans = Transformer.new
11+
end
12+
13+
it "converts shorthand rules to longhand" do
14+
trans("10% Gill, 'Lucida Sans'").must_equal([
15+
dec("font-size", "10%"),
16+
dec("font-family", "Gill, 'Lucida Sans'")
17+
])
18+
19+
trans("normal small-caps 100 10% / 33 Gill, Helvetica, \"Lucida Sans\", cursive").must_equal([
20+
dec("font-style", "normal"),
21+
dec("font-variant", "small-caps"),
22+
dec("font-weight", "100"),
23+
dec("font-size", "10%"),
24+
dec("line-height", "33"),
25+
dec("font-family", 'Gill, Helvetica, "Lucida Sans", cursive')
26+
])
27+
end
28+
29+
it "parses font family" do
30+
@parser.font_family.must_parse("\"Lucida\"")
31+
@parser.font_family.must_parse("\"Lucida Sans\"")
32+
@parser.font_family.must_parse("Gill")
33+
@parser.font_family.must_parse('Gill, Helvetica, "Lucida Sans", cursive')
34+
end
35+
36+
it "ignores literal fonts" do
37+
trans("caption").must_equal([])
38+
trans("icon").must_equal([])
39+
trans("menu").must_equal([])
40+
end
41+
end
42+
end
43+
end

0 commit comments

Comments
 (0)