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
93d338fb
Commit
93d338fb
authored
Jul 16, 2014
by
Taddeüs Kroes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented CSS @media queries
parent
e31ac97a
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
90 additions
and
21 deletions
+90
-21
lexer.mll
lexer.mll
+8
-3
parser.mly
parser.mly
+38
-15
stringify.ml
stringify.ml
+40
-2
types.ml
types.ml
+4
-1
No files found.
lexer.mll
View file @
93d338fb
...
@@ -58,8 +58,6 @@ rule token = parse
...
@@ -58,8 +58,6 @@ rule token = parse
| mystring as s { STRING (strip_quotes s) }
| mystring as s { STRING (strip_quotes s) }
| badstring { raise (SyntaxError "
bad
string
") }
| badstring { raise (SyntaxError "
bad
string
") }
| ident as id { IDENT id }
| '#' (name as nm) { HASH nm }
| '#' (name as nm) { HASH nm }
| "
@
import
" { IMPORT_SYM }
| "
@
import
" { IMPORT_SYM }
...
@@ -67,10 +65,16 @@ rule token = parse
...
@@ -67,10 +65,16 @@ rule token = parse
| "
@
media
" { MEDIA_SYM }
| "
@
media
" { MEDIA_SYM }
| "
@
charset
" { CHARSET_SYM }
| "
@
charset
" { CHARSET_SYM }
| "
only
" { ONLY }
| "
not
" { NOT }
| "
and
" { AND }
| ident as id { IDENT id }
| '!' (w | comment)* "
important
" { IMPORTANT_SYM }
| '!' (w | comment)* "
important
" { IMPORTANT_SYM }
| (num as n) ("
em
"|"
ex
"|"
px
"|"
cm
"|"
mm
"|"
in
"|"
pt
"|"
pc
"|"
deg
"|"
rad
"|"
grad
"|
| (num as n) ("
em
"|"
ex
"|"
px
"|"
cm
"|"
mm
"|"
in
"|"
pt
"|"
pc
"|"
deg
"|"
rad
"|"
grad
"|
"
ms
"|"
s
"|"
hz
"|"
khz
"|"
%
"|ident as u)
"
ms
"|"
s
"|"
hz
"|"
khz
"|"
%
"|
"
dpi
"|"
dpcm
"|
ident as u)
{ UNIT_VALUE (float_of_string n, u) }
{ UNIT_VALUE (float_of_string n, u) }
| num as n { NUMBER (float_of_string n) }
| num as n { NUMBER (float_of_string n) }
...
@@ -80,6 +84,7 @@ rule token = parse
...
@@ -80,6 +84,7 @@ rule token = parse
| (ident as fn) '(' { FUNCTION fn }
| (ident as fn) '(' { FUNCTION fn }
| '(' { LPAREN }
| ')' { RPAREN }
| ')' { RPAREN }
| '{' { LBRACE }
| '{' { LBRACE }
| '}' { RBRACE }
| '}' { RBRACE }
...
...
parser.mly
View file @
93d338fb
%
{
%
{
(* CSS grammar based on http://www.w3.org/TR/CSS2/grammar.html *)
(* CSS grammar based on:
* - http://www.w3.org/TR/CSS2/grammar.html
* - http://www.w3.org/TR/css3-mediaqueries/
*)
open
Lexing
open
Lexing
open
Types
open
Types
let
(
|>
)
a
b
=
b
a
let
(
|>
)
a
b
=
b
a
let
filter_none
l
=
(* TODO: move this to utils *)
let
rec
filter
l
=
function
let
rec
filter_none
=
function
|
[]
->
l
|
[]
->
[]
|
None
::
tl
->
filter
l
tl
|
None
::
tl
->
filter_none
tl
|
Some
hd
::
tl
->
filter
(
hd
::
l
)
tl
|
Some
hd
::
tl
->
hd
::
filter_none
tl
in
List
.
rev
(
filter
[]
l
)
type
term_t
=
Term
of
expr
|
Operator
of
string
type
term_t
=
Term
of
expr
|
Operator
of
string
...
@@ -47,8 +48,8 @@
...
@@ -47,8 +48,8 @@
%
token
<
float
>
NUMBER
%
token
<
float
>
NUMBER
%
token
<
float
*
string
>
UNIT_VALUE
%
token
<
float
*
string
>
UNIT_VALUE
%
token
<
string
>
COMBINATOR
RELATION
STRING
IDENT
HASH
URI
FUNCTION
%
token
<
string
>
COMBINATOR
RELATION
STRING
IDENT
HASH
URI
FUNCTION
%
token
RPAREN
LBRACE
RBRACE
LBRACK
RBRACK
SEMICOL
COLON
COMMA
DOT
PLUS
MIN
US
%
token
LPAREN
RPAREN
LBRACE
RBRACE
LBRACK
RBRACK
SEMICOL
COLON
COMMA
DOT
PL
US
%
token
SLASH
STAR
EOF
%
token
MINUS
SLASH
STAR
ONLY
AND
NOT
EOF
(* Start symbol *)
(* Start symbol *)
%
type
<
Types
.
stylesheet
>
stylesheet
%
type
<
Types
.
stylesheet
>
stylesheet
...
@@ -58,6 +59,7 @@
...
@@ -58,6 +59,7 @@
(* list with arbitrary whitespace between elements and separators *)
(* list with arbitrary whitespace between elements and separators *)
%
inline
wslist
(
sep
,
x
)
:
S
?
l
=
separated_list
(
sep
,
terminated
(
x
,
S
?
))
{
l
}
%
inline
wslist
(
sep
,
x
)
:
S
?
l
=
separated_list
(
sep
,
terminated
(
x
,
S
?
))
{
l
}
%
inline
wspreceded
(
prefix
,
x
)
:
p
=
preceded
(
pair
(
prefix
,
S
?
)
,
x
)
{
p
}
cd
:
CDO
S
?
|
CDC
S
?
{}
cd
:
CDO
S
?
|
CDC
S
?
{}
...
@@ -68,7 +70,8 @@ stylesheet:
...
@@ -68,7 +70,8 @@ stylesheet:
EOF
EOF
{
let
charset
=
match
charset
with
None
->
[]
|
Some
c
->
[
c
]
in
{
let
charset
=
match
charset
with
None
->
[]
|
Some
c
->
[
c
]
in
charset
@
imports
@
statements
}
charset
@
imports
@
statements
}
%
inline
statement
:
statement
:
|
s
=
ruleset
|
s
=
media
|
s
=
page
|
s
=
ruleset
|
s
=
media
|
s
=
page
{
s
}
{
s
}
...
@@ -77,15 +80,35 @@ charset:
...
@@ -77,15 +80,35 @@ charset:
{
Charset
name
}
{
Charset
name
}
import
:
import
:
|
IMPORT_SYM
S
?
tgt
=
string_or_uri
media
=
wslist
(
COMMA
,
IDENT
)
SEMICOL
S
?
|
IMPORT_SYM
S
?
tgt
=
string_or_uri
media
=
wslist
(
COMMA
,
media_type
)
SEMICOL
S
?
{
Import
(
tgt
,
media
)
}
{
Import
(
tgt
,
media
)
}
%
inline
string_or_uri
:
%
inline
string_or_uri
:
|
str
=
STRING
{
Strlit
str
}
|
str
=
STRING
{
Strlit
str
}
|
uri
=
URI
{
Uri
uri
}
|
uri
=
URI
{
Uri
uri
}
media
:
media
:
|
MEDIA_SYM
queries
=
wslist
(
COMMA
,
IDENT
)
LBRACE
S
?
rulesets
=
ruleset
*
RBRACE
S
?
|
MEDIA_SYM
queries
=
media_query_list
LBRACE
S
?
rulesets
=
ruleset
*
RBRACE
S
?
{
Media
(
queries
,
rulesets
)
}
{
Media
(
queries
,
rulesets
)
}
media_query_list
:
|
S
?
{
[]
}
|
S
?
hd
=
media_query
tl
=
wspreceded
(
COMMA
,
media_query
)
*
{
hd
::
tl
}
media_query
:
|
prefix
=
only_or_not
?
typ
=
media_type
S
?
feat
=
wspreceded
(
AND
,
media_expr
)
*
{
(
prefix
,
Some
typ
,
feat
)
}
|
hd
=
media_expr
tl
=
wspreceded
(
AND
,
media_expr
)
*
{
(
None
,
None
,
(
hd
::
tl
))
}
%
inline
only_or_not
:
|
ONLY
S
?
{
"only"
}
|
NOT
S
?
{
"not"
}
%
inline
media_type
:
|
id
=
IDENT
{
id
}
media_expr
:
|
LPAREN
S
?
feature
=
media_feature
S
?
value
=
wspreceded
(
COLON
,
expr
)
?
RPAREN
S
?
{
(
feature
,
value
)
}
%
inline
media_feature
:
|
id
=
IDENT
{
id
}
page
:
page
:
|
PAGE_SYM
S
?
pseudo
=
pseudo_page
?
decls
=
decls_block
|
PAGE_SYM
S
?
pseudo
=
pseudo_page
?
decls
=
decls_block
...
@@ -96,12 +119,12 @@ pseudo_page:
...
@@ -96,12 +119,12 @@ pseudo_page:
{
pseudo
}
{
pseudo
}
%
inline
decls_block
:
%
inline
decls_block
:
|
LBRACE
S
?
hd
=
declaration
?
tl
=
preceded
(
pair
(
SEMICOL
,
S
?
)
,
declaration
?
)
*
RBRACE
S
?
|
LBRACE
S
?
hd
=
declaration
?
tl
=
wspreceded
(
SEMICOL
,
declaration
?
)
*
RBRACE
S
?
{
filter_none
(
hd
::
tl
)
}
{
filter_none
(
hd
::
tl
)
}
ruleset
:
ruleset
:
|
selectors_hd
=
selector
|
selectors_hd
=
selector
selectors_tl
=
preceded
(
pair
(
COMMA
,
S
?
)
,
selector
)
*
selectors_tl
=
wspreceded
(
COMMA
,
selector
)
*
decls
=
decls_block
decls
=
decls_block
{
Ruleset
(
selectors_hd
::
selectors_tl
,
decls
)
}
{
Ruleset
(
selectors_hd
::
selectors_tl
,
decls
)
}
...
...
stringify.ml
View file @
93d338fb
...
@@ -4,6 +4,8 @@ let tab = " "
...
@@ -4,6 +4,8 @@ let tab = " "
let
indent
=
Str
.
global_replace
(
Str
.
regexp
"^
\\
(.
\\
)"
)
(
tab
^
"
\\
1"
)
let
indent
=
Str
.
global_replace
(
Str
.
regexp
"^
\\
(.
\\
)"
)
(
tab
^
"
\\
1"
)
let
prefix_space
=
function
""
->
""
|
s
->
" "
^
s
let
rec
cat
sep
fn
=
function
let
rec
cat
sep
fn
=
function
|
[]
->
""
|
[]
->
""
|
[
hd
]
->
fn
hd
|
[
hd
]
->
fn
hd
...
@@ -14,6 +16,12 @@ let string_of_num n =
...
@@ -14,6 +16,12 @@ let string_of_num 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
(* TODO: move this to utils *)
let
rec
filter_none
=
function
|
[]
->
[]
|
None
::
tl
->
filter_none
tl
|
Some
hd
::
tl
->
hd
::
filter_none
tl
(*
(*
* Pretty-printing
* Pretty-printing
*)
*)
...
@@ -43,6 +51,23 @@ let rec string_of_selector = function
...
@@ -43,6 +51,23 @@ let rec string_of_selector = function
|
Combinator
(
left
,
com
,
right
)
->
|
Combinator
(
left
,
com
,
right
)
->
string_of_selector
left
^
" "
^
com
^
" "
^
string_of_selector
right
string_of_selector
left
^
" "
^
com
^
" "
^
string_of_selector
right
let
string_of_media_feature
=
function
|
(
feature
,
None
)
->
"("
^
feature
^
")"
|
(
feature
,
Some
value
)
->
"("
^
feature
^
": "
^
string_of_expr
value
^
")"
let
string_of_media_query
query
=
let
features_str
=
cat
" and "
string_of_media_feature
in
match
query
with
|
(
None
,
None
,
[]
)
->
""
|
(
None
,
Some
mtype
,
[]
)
->
mtype
|
(
Some
pre
,
Some
mtype
,
[]
)
->
pre
^
" "
^
mtype
|
(
None
,
None
,
features
)
->
features_str
features
|
(
None
,
Some
mtype
,
features
)
->
mtype
^
" and "
^
features_str
features
|
(
Some
pre
,
Some
mtype
,
features
)
->
pre
^
" "
^
mtype
^
" and "
^
features_str
features
|
(
Some
pre
,
None
,
_
)
->
failwith
"unexpected media query prefix
\"
"
^
pre
^
"
\"
"
let
block
body
=
" {
\n
"
^
indent
body
^
"
\n
}"
let
block
body
=
" {
\n
"
^
indent
body
^
"
\n
}"
let
rec
string_of_statement
=
function
let
rec
string_of_statement
=
function
...
@@ -50,7 +75,7 @@ let rec string_of_statement = function
...
@@ -50,7 +75,7 @@ let rec string_of_statement = function
cat
", "
string_of_selector
selectors
^
cat
", "
string_of_selector
selectors
^
block
(
cat
"
\n
"
string_of_declaration
decls
)
block
(
cat
"
\n
"
string_of_declaration
decls
)
|
Media
(
queries
,
rulesets
)
->
|
Media
(
queries
,
rulesets
)
->
"@media
"
^
String
.
concat
", "
queries
^
"@media
"
^
prefix_space
(
cat
", "
string_of_media_query
queries
)
^
block
(
cat
"
\n\n
"
string_of_statement
rulesets
)
block
(
cat
"
\n\n
"
string_of_statement
rulesets
)
|
Import
(
target
,
[]
)
->
|
Import
(
target
,
[]
)
->
"@import "
^
string_of_expr
target
^
";"
"@import "
^
string_of_expr
target
^
";"
...
@@ -92,12 +117,25 @@ let rec minify_selector = function
...
@@ -92,12 +117,25 @@ let rec minify_selector = function
|
Combinator
(
left
,
com
,
right
)
->
|
Combinator
(
left
,
com
,
right
)
->
minify_selector
left
^
com
^
minify_selector
right
minify_selector
left
^
com
^
minify_selector
right
let
minify_media_feature
=
function
|
(
feature
,
None
)
->
"("
^
feature
^
")"
|
(
feature
,
Some
value
)
->
"("
^
feature
^
":"
^
minify_expr
value
^
")"
let
minify_media_query
query
=
let
features_str
=
cat
" and "
minify_media_feature
in
match
query
with
|
(
None
,
None
,
features
)
->
features_str
features
|
(
None
,
Some
mtype
,
features
)
->
mtype
^
" and "
^
features_str
features
|
(
Some
pre
,
Some
mtype
,
features
)
->
pre
^
" "
^
mtype
^
" and "
^
features_str
features
|
_
->
string_of_media_query
query
let
rec
minify_statement
=
function
let
rec
minify_statement
=
function
|
Ruleset
(
selectors
,
decls
)
->
|
Ruleset
(
selectors
,
decls
)
->
cat
","
minify_selector
selectors
^
cat
","
minify_selector
selectors
^
"{"
^
(
cat
";"
minify_declaration
decls
)
^
"}"
"{"
^
(
cat
";"
minify_declaration
decls
)
^
"}"
|
Media
(
queries
,
rulesets
)
->
|
Media
(
queries
,
rulesets
)
->
"@media
"
^
String
.
concat
","
queries
^
"@media
"
^
prefix_space
(
cat
","
minify_media_query
queries
)
^
"{"
^
(
cat
""
minify_statement
rulesets
)
^
"}"
"{"
^
(
cat
""
minify_statement
rulesets
)
^
"}"
|
Import
(
target
,
[]
)
->
|
Import
(
target
,
[]
)
->
"@import "
^
string_of_expr
target
^
";"
"@import "
^
string_of_expr
target
^
";"
...
...
types.ml
View file @
93d338fb
...
@@ -15,10 +15,13 @@ type selector =
...
@@ -15,10 +15,13 @@ type selector =
|
Simple
of
string
|
Simple
of
string
|
Combinator
of
selector
*
string
*
selector
|
Combinator
of
selector
*
string
*
selector
type
media_expr
=
string
*
expr
option
type
media_query
=
string
option
*
string
option
*
media_expr
list
type
statement
=
type
statement
=
|
Ruleset
of
selector
list
*
declaration
list
|
Ruleset
of
selector
list
*
declaration
list
(* <selectors> { <declarations> } *)
(* <selectors> { <declarations> } *)
|
Media
of
string
list
*
statement
list
|
Media
of
media_query
list
*
statement
list
(* @media <queries> { <rulesets> } *)
(* @media <queries> { <rulesets> } *)
|
Import
of
expr
*
string
list
|
Import
of
expr
*
string
list
(* @import <target> [<media>]; *)
(* @import <target> [<media>]; *)
...
...
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