Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mincss
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
mincss
Commits
f7c7c13c
Commit
f7c7c13c
authored
Aug 10, 2015
by
Taddeüs Kroes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for :nth-child formula syntax
parent
8d36a788
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
141 additions
and
25 deletions
+141
-25
lexer.mll
lexer.mll
+13
-0
main.ml
main.ml
+1
-1
parser.mly
parser.mly
+25
-7
simple.ml
simple.ml
+25
-4
stringify.ml
stringify.ml
+23
-2
test/pseudo-class.css
test/pseudo-class.css
+31
-0
types.ml
types.ml
+9
-7
util.ml
util.ml
+14
-4
No files found.
lexer.mll
View file @
f7c7c13c
...
@@ -114,12 +114,25 @@ rule token = parse
...
@@ -114,12 +114,25 @@ rule token = parse
| (s | comment)* s comment* O R comment* s (s | comment)*
| (s | comment)* s comment* O R comment* s (s | comment)*
{ advance_pos lexbuf; WS_OR }
{ advance_pos lexbuf; WS_OR }
| (['-' '+'] as a_sign)? (['0'-'9']* as a) N
(w (['-' '+'] as b_sign) w (['0'-'9']+ as b))?
{
let a = if a = "" then 1 else int_of_string a in
let b = match b with None -> 0 | Some n -> int_of_string n in
let apply_sign n = function Some '-' -> -n | _ -> n in
let a = apply_sign a a_sign in
let b = apply_sign b b_sign in
FORMULA (a, b)
}
| O N L Y { ONLY }
| O N L Y { ONLY }
| N O T { NOT }
| N O T { NOT }
| A N D { AND }
| A N D { AND }
(*| O R { OR } removed in favor of WS_OR *)
(*| O R { OR } removed in favor of WS_OR *)
| F R O M { FROM }
| F R O M { FROM }
| T O { TO }
| T O { TO }
| O D D { ODD }
| E V E N { EVEN }
| ident as id { IDENT id }
| ident as id { IDENT id }
...
...
main.ml
View file @
f7c7c13c
...
@@ -27,7 +27,7 @@ let parse_args () =
...
@@ -27,7 +27,7 @@ let parse_args () =
Optimization flags (if none are specified, all are enabled):
\n
\
Optimization flags (if none are specified, all are enabled):
\n
\
-w, --whitespace Eliminate unnecessary whitespaces (has the greatest \
-w, --whitespace Eliminate unnecessary whitespaces (has the greatest \
effect, omit for pretty-printing)
\n
\
effect, omit for pretty-printing)
\n
\
-c, --simple Shorten colors
and font weights
\n
\
-c, --simple Shorten colors
, font weights and nth-child
\n
\
-s, --shorthands Generate shorthand properties
\n
\
-s, --shorthands Generate shorthand properties
\n
\
-d, --duplicates Prune duplicate properties (WARNING: may affect \
-d, --duplicates Prune duplicate properties (WARNING: may affect \
cross-browser hacks)
\n
\
cross-browser hacks)
\n
\
...
...
parser.mly
View file @
f7c7c13c
...
@@ -62,7 +62,8 @@
...
@@ -62,7 +62,8 @@
%
token
<
string
>
URI
FUNCTION
%
token
<
string
>
URI
FUNCTION
%
token
LPAREN
RPAREN
LBRACE
RBRACE
LBRACK
RBRACK
SEMICOL
COLON
DOUBLE_COLON
%
token
LPAREN
RPAREN
LBRACE
RBRACE
LBRACK
RBRACK
SEMICOL
COLON
DOUBLE_COLON
%
token
COMMA
DOT
PLUS
MINUS
SLASH
STAR
ONLY
AND
(*OR*)
NOT
FROM
TO
EOF
%
token
COMMA
DOT
PLUS
MINUS
SLASH
STAR
ONLY
AND
(*OR*)
NOT
FROM
TO
EOF
%
token
WS_AND
WS_OR
%
token
WS_AND
WS_OR
ODD
EVEN
%
token
<
int
*
int
>
FORMULA
(* Start symbol *)
(* Start symbol *)
%
type
<
Types
.
stylesheet
>
stylesheet
%
type
<
Types
.
stylesheet
>
stylesheet
...
@@ -242,9 +243,7 @@ simple_selector:
...
@@ -242,9 +243,7 @@ simple_selector:
{
append_addons
No_element
addons
}
{
append_addons
No_element
addons
}
%
inline
element_addon
:
%
inline
element_addon
:
|
id
=
HASH
{
`Id
id
}
|
id
=
HASH
{
`Id
id
}
|
addon
=
cls
|
addon
=
cls
|
addon
=
attrib
|
addon
=
pseudo_class
{
addon
}
|
addon
=
attrib
|
addon
=
pseudo
{
addon
}
element_name
:
element_name
:
|
tag
=
IDENT
{
Element
(
String
.
lowercase
tag
)
}
|
tag
=
IDENT
{
Element
(
String
.
lowercase
tag
)
}
|
STAR
{
All_elements
}
|
STAR
{
All_elements
}
...
@@ -259,13 +258,32 @@ attrib:
...
@@ -259,13 +258,32 @@ attrib:
%
inline
rel_value
:
%
inline
rel_value
:
|
S
*
id
=
IDENT
S
*
{
Ident
id
}
|
S
*
id
=
IDENT
S
*
{
Ident
id
}
|
S
*
s
=
STRING
S
*
{
Strlit
s
}
|
S
*
s
=
STRING
S
*
{
Strlit
s
}
pseudo
:
pseudo
_class
:
|
COLON
id
=
IDENT
|
COLON
id
=
IDENT
{
`Pseudo_class
(
String
.
lowercase
id
,
None
)
}
{
`Pseudo_class
(
String
.
lowercase
id
,
None
)
}
|
COLON
f
=
FUNCTION
args
=
wslist
(
COMMA
,
simple_selector
)
RPAREN
|
COLON
f
=
FUNCTION
args
=
wslist
(
COMMA
,
function_arg
)
RPAREN
{
`Pseudo_class
(
String
.
lowercase
f
,
Some
args
)
}
{
`Pseudo_class
(
String
.
lowercase
f
,
Some
args
)
}
|
DOUBLE_COLON
id
=
IDENT
|
DOUBLE_COLON
id
=
IDENT
{
`Pseudo_element
(
String
.
lowercase
id
)
}
{
`Pseudo_element
(
String
.
lowercase
id
)
}
function_arg
:
|
s
=
selector
{
Nested_selector
s
}
|
EVEN
{
Nth
Even
}
|
ODD
{
Nth
Odd
}
|
f
=
FORMULA
{
let
a
,
b
=
f
in
Nth
(
Formula
(
a
,
b
))
}
|
sign
=
sign
?
n
=
NUMBER
{
if
is_int
n
then
begin
let
b
=
int_of_float
(
match
sign
with
Some
MINUS
->
-.
n
|
_
->
n
)
in
Nth
(
Formula
(
0
,
b
))
end
else
raise
(
Syntax_error
(
"unexpected float '"
^
string_of_float
n
^
"', expected int"
))
}
%
inline
sign
:
PLUS
{
PLUS
}
|
MINUS
{
MINUS
}
declaration
:
declaration
:
|
name
=
property
S
*
COLON
S
*
value
=
expr
important
=
boption
(
ig2
(
IMPORTANT_SYM
,
S
*
))
|
name
=
property
S
*
COLON
S
*
value
=
expr
important
=
boption
(
ig2
(
IMPORTANT_SYM
,
S
*
))
...
...
simple.ml
View file @
f7c7c13c
open
Str
open
Types
open
Types
let
hex6
=
Str
.
regexp
"
\\
([0-9a-f]
\\
)
\\
1
\\
([0-9a-f]
\\
)
\\
2
\\
([0-9a-f]
\\
)
\\
3"
let
hex6
=
regexp
"
\\
([0-9a-f]
\\
)
\\
1
\\
([0-9a-f]
\\
)
\\
2
\\
([0-9a-f]
\\
)
\\
3"
let
is_num
=
function
let
is_num
=
function
|
Number
(
n
,
(
None
|
Some
"%"
))
->
true
|
Number
(
n
,
(
None
|
Some
"%"
))
->
true
...
@@ -14,8 +15,8 @@ let clip = function
...
@@ -14,8 +15,8 @@ let clip = function
let
rec
shorten_expr
=
function
let
rec
shorten_expr
=
function
(* #aabbcc -> #abc *)
(* #aabbcc -> #abc *)
|
Hexcolor
h
when
Str
.
string_match
hex6
h
0
->
|
Hexcolor
h
when
string_match
hex6
h
0
->
let
gr
n
=
Str
.
matched_group
n
h
in
let
gr
n
=
matched_group
n
h
in
shorten_expr
(
Hexcolor
(
gr
1
^
gr
2
^
gr
3
))
shorten_expr
(
Hexcolor
(
gr
1
^
gr
2
^
gr
3
))
(* rgb(r,g,b) -> #rrggbb *)
(* rgb(r,g,b) -> #rrggbb *)
...
@@ -50,12 +51,32 @@ let shorten_font_weight = function
...
@@ -50,12 +51,32 @@ let shorten_font_weight = function
|
Ident
"bold"
->
Number
(
700
.
0
,
None
)
|
Ident
"bold"
->
Number
(
700
.
0
,
None
)
|
v
->
v
|
v
->
v
let
shorten_nth
=
function
(* even -> 2n *)
|
Even
->
Formula
(
2
,
0
)
(* 2n+1 | 2n-1 -> odd *)
|
Formula
(
2
,
(
1
|
-
1
))
->
Odd
(* -n+1 -> 1 *)
|
Formula
(
-
1
,
1
)
->
Formula
(
0
,
1
)
|
v
->
v
let
compress
=
let
compress
=
Util
.
transform_stylesheet
begin
function
Util
.
transform_stylesheet
begin
function
|
Expr
value
->
Expr
(
shorten_expr
value
)
|
Expr
value
->
Expr
(
shorten_expr
value
)
|
Declaration
(
"font-weight"
,
value
,
imp
)
->
|
Declaration
(
"font-weight"
,
value
,
imp
)
->
Declaration
(
"font-weight"
,
shorten_font_weight
value
,
imp
)
Declaration
(
"font-weight"
,
shorten_font_weight
value
,
imp
)
|
Declaration
((
"border"
|
"outline"
)
as
name
,
Ident
"none"
,
imp
)
->
|
Declaration
((
"border"
|
"outline"
)
as
name
,
Ident
"none"
,
imp
)
->
Declaration
(
name
,
Number
(
0
.,
None
)
,
imp
)
Declaration
(
name
,
Number
(
0
.,
None
)
,
imp
)
|
Pseudo_class_arg
(
Nth
nth
)
->
Pseudo_class_arg
(
Nth
(
shorten_nth
nth
))
(* Remove rulesets with :nth-child(0) selector *)
|
Selector
(
Pseudo_class
(
_
,
cls
,
Some
[
Nth
(
Formula
(
0
,
0
))]))
when
string_match
(
regexp
"nth-"
)
cls
0
->
Clear
(* Remove rulesets with no selectors or declarations *)
|
Statement
(
Ruleset
([]
,
_
))
|
Statement
(
Ruleset
(
_
,
[]
))
->
Clear
|
v
->
v
|
v
->
v
end
end
stringify.ml
View file @
f7c7c13c
...
@@ -17,7 +17,7 @@ let rec cat sep fn = function
...
@@ -17,7 +17,7 @@ let rec cat sep fn = function
*)
*)
let
string_of_num
n
=
let
string_of_num
n
=
if
float_of_int
(
int_of_float
n
)
=
n
if
is_int
n
then
string_of_int
(
int_of_float
n
)
then
string_of_int
(
int_of_float
n
)
else
string_of_float
n
else
string_of_float
n
...
@@ -57,7 +57,7 @@ let rec stringify_selector w selector =
...
@@ -57,7 +57,7 @@ let rec stringify_selector w selector =
|
Pseudo_class
(
base
,
cls
,
None
)
->
|
Pseudo_class
(
base
,
cls
,
None
)
->
str
base
^
":"
^
cls
str
base
^
":"
^
cls
|
Pseudo_class
(
base
,
fn
,
Some
args
)
->
|
Pseudo_class
(
base
,
fn
,
Some
args
)
->
str
base
^
":"
^
fn
^
"("
^
cat
(
","
^
w
)
str
args
^
")"
str
base
^
":"
^
fn
^
"("
^
cat
(
","
^
w
)
(
stringify_arg
w
)
args
^
")"
|
Pseudo_element
(
base
,
elem
)
->
|
Pseudo_element
(
base
,
elem
)
->
str
base
^
"::"
^
elem
str
base
^
"::"
^
elem
|
Combinator
(
left
,
" "
,
right
)
->
|
Combinator
(
left
,
" "
,
right
)
->
...
@@ -65,6 +65,27 @@ let rec stringify_selector w selector =
...
@@ -65,6 +65,27 @@ let rec stringify_selector w selector =
|
Combinator
(
left
,
com
,
right
)
->
|
Combinator
(
left
,
com
,
right
)
->
str
left
^
w
^
com
^
w
^
str
right
str
left
^
w
^
com
^
w
^
str
right
and
stringify_arg
w
=
function
|
Nested_selector
s
->
stringify_selector
w
s
|
Nth
nth
->
stringify_nth
w
nth
and
stringify_nth
w
=
function
|
Even
->
"even"
|
Odd
->
"odd"
|
Formula
(
0
,
b
)
->
string_of_int
b
|
Formula
(
a
,
b
)
->
begin
match
a
with
|
1
->
"n"
|
-
1
->
"-n"
|
a
->
string_of_int
a
^
"n"
end
^
begin
match
b
with
|
0
->
""
|
b
when
b
<
0
->
w
^
"-"
^
w
^
string_of_int
(
-
b
)
|
b
->
w
^
"+"
^
w
^
string_of_int
b
end
let
string_of_selector
=
stringify_selector
" "
let
string_of_selector
=
stringify_selector
" "
let
string_of_media_expr
=
function
let
string_of_media_expr
=
function
...
...
test/pseudo-class.css
0 → 100644
View file @
f7c7c13c
a
:link
{
margin
:
0
;
}
div
:nth-child
(
even
)
{
/* div:nth-child(2n) */
margin
:
0
;
}
div
:nth-child
(
2n
+
1
)
{
/* div:nth-child(odd) */
margin
:
1
;
}
div
:nth-child
(
-1n
+
2
)
{
/* div:nth-child(-n+2) */
margin
:
2
;
}
div
:nth-child
(
0n
+
1
)
{
/* div:nth-child(1) */
margin
:
3
;
}
div
:nth-child
(
0
)
{
/* removed */
margin
:
4
;
}
div
:nth-child
(
2n
)
{
/* div:nth-child(2n) */
margin
:
5
;
}
div
:nth-child
(
-n
+
0
)
{
/* div:nth-child(-n) */
margin
:
6
;
}
div
:nth-child
(+
3n
)
{
/* div:nth-child(3n) */
margin
:
7
;
}
div
:nth-child
(
-n
+
1
)
{
/* div:nth-child(1) */
margin
:
8
;
}
types.ml
View file @
f7c7c13c
...
@@ -18,16 +18,17 @@ type selector =
...
@@ -18,16 +18,17 @@ type selector =
|
Element
of
string
|
Element
of
string
|
Id
of
selector
*
string
|
Id
of
selector
*
string
|
Class
of
selector
*
string
|
Class
of
selector
*
string
|
Pseudo_class
of
selector
*
string
*
selector
list
option
|
Pseudo_class
of
selector
*
string
*
pseudo_class_arg
list
option
|
Pseudo_element
of
selector
*
string
|
Pseudo_element
of
selector
*
string
|
Attribute
of
selector
*
string
*
(
string
*
expr
)
option
|
Attribute
of
selector
*
string
*
(
string
*
expr
)
option
|
Combinator
of
selector
*
string
*
selector
|
Combinator
of
selector
*
string
*
selector
and
pseudo_class_arg
=
(*
|
Nested_selector
of
selector
type selector =
|
Nth
of
nth
| Simple of string
and
nth
=
| Combinator of selector * string * selector
|
Even
|
Odd
*)
(* a and b in an+b *)
|
Formula
of
int
*
int
type
media_expr
=
string
*
expr
option
type
media_expr
=
string
*
expr
option
type
media_query
=
string
option
*
string
option
*
media_expr
list
type
media_query
=
string
option
*
string
option
*
media_expr
list
...
@@ -73,6 +74,7 @@ type box =
...
@@ -73,6 +74,7 @@ type box =
|
Expr
of
expr
|
Expr
of
expr
|
Declaration
of
declaration
|
Declaration
of
declaration
|
Selector
of
selector
|
Selector
of
selector
|
Pseudo_class_arg
of
pseudo_class_arg
|
Media_expr
of
media_expr
|
Media_expr
of
media_expr
|
Media_query
of
media_query
|
Media_query
of
media_query
|
Descriptor_declaration
of
descriptor_declaration
|
Descriptor_declaration
of
descriptor_declaration
...
...
util.ml
View file @
f7c7c13c
...
@@ -142,7 +142,7 @@ let transform_stylesheet f stylesheet =
...
@@ -142,7 +142,7 @@ let transform_stylesheet f stylesheet =
|
Pseudo_class
(
base
,
cls
,
None
)
->
|
Pseudo_class
(
base
,
cls
,
None
)
->
f
(
Selector
(
Pseudo_class
(
expect_selector
base
,
cls
,
None
)))
f
(
Selector
(
Pseudo_class
(
expect_selector
base
,
cls
,
None
)))
|
Pseudo_class
(
base
,
fn
,
Some
args
)
->
|
Pseudo_class
(
base
,
fn
,
Some
args
)
->
let
args
=
trav_all_
selector
args
in
let
args
=
trav_all_
pseudo_class_arg
args
in
f
(
Selector
(
Pseudo_class
(
expect_selector
base
,
fn
,
Some
args
)))
f
(
Selector
(
Pseudo_class
(
expect_selector
base
,
fn
,
Some
args
)))
|
Pseudo_element
(
base
,
elem
)
->
|
Pseudo_element
(
base
,
elem
)
->
f
(
Selector
(
Pseudo_element
(
expect_selector
base
,
elem
)))
f
(
Selector
(
Pseudo_element
(
expect_selector
base
,
elem
)))
...
@@ -151,7 +151,14 @@ let transform_stylesheet f stylesheet =
...
@@ -151,7 +151,14 @@ let transform_stylesheet f stylesheet =
let
right
=
expect_selector
right
in
let
right
=
expect_selector
right
in
f
(
Selector
(
Combinator
(
left
,
com
,
right
)))
f
(
Selector
(
Combinator
(
left
,
com
,
right
)))
and
EXPECT
(
selector
,
Selector
)
and
EXPECT
(
selector
,
Selector
)
and
TRAV_ALL
(
selector
,
Selector
)
in
and
TRAV_ALL
(
selector
,
Selector
)
and
trav_pseudo_class_arg
=
function
|
Nested_selector
s
->
f
(
Pseudo_class_arg
(
Nested_selector
(
expect_selector
s
)))
|
Nth
_
as
elem
->
f
(
Pseudo_class_arg
elem
)
and
TRAV_ALL
(
pseudo_class_arg
,
Pseudo_class_arg
)
in
let
trav_media_expr
=
function
let
trav_media_expr
=
function
|
(
_
,
None
)
as
value
->
|
(
_
,
None
)
as
value
->
...
@@ -230,11 +237,11 @@ let transform_stylesheet f stylesheet =
...
@@ -230,11 +237,11 @@ let transform_stylesheet f stylesheet =
trav_all_statement
stylesheet
trav_all_statement
stylesheet
(* Expression identification *)
(*
*
Expression identification *)
let
is_color
=
Color_names
.
is_color
let
is_color
=
Color_names
.
is_color
(* Sorting declarations *)
(*
*
Sorting declarations *)
let
sort_stylesheet
=
let
sort_stylesheet
=
transform_stylesheet
begin
function
transform_stylesheet
begin
function
...
@@ -247,3 +254,6 @@ let sort_stylesheet =
...
@@ -247,3 +254,6 @@ let sort_stylesheet =
Statement
(
Ruleset
(
selectors
,
List
.
stable_sort
cmp
decls
))
Statement
(
Ruleset
(
selectors
,
List
.
stable_sort
cmp
decls
))
|
v
->
v
|
v
->
v
end
end
(** Misc *)
let
is_int
n
=
float_of_int
(
int_of_float
n
)
=
n
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment