Skip to content
Snippets Groups Projects
Commit 3b7dc074 authored by Taddeüs Kroes's avatar Taddeüs Kroes
Browse files

Extended 'Simple' selector type to algebraic data types

parent 34391515
No related branches found
No related tags found
No related merge requests found
RESULT := mincss RESULT := mincss
PRE_TGTS := types PRE_TGTS := types
MODULES := color_names util stringify parser lexer parse color shorthand main MODULES := color_names util stringify parser lexer parse color \
shorthand main
ALL_NAMES := $(PRE_TGTS) $(MODULES) ALL_NAMES := $(PRE_TGTS) $(MODULES)
OCAMLCFLAGS := -g OCAMLCFLAGS := -g
......
...@@ -37,6 +37,18 @@ ...@@ -37,6 +37,18 @@
| Unary ("-", Number (n, u)) -> Number (-.n, u) | Unary ("-", Number (n, u)) -> Number (-.n, u)
| Unary ("+", (Number _ as n)) -> n | Unary ("+", (Number _ as n)) -> n
| value -> value | value -> value
let rec append_addons base = function
| [] ->
base
| `Id id :: tl ->
append_addons (Id (base, id)) tl
| `Class cls :: tl ->
append_addons (Class (base, cls)) tl
| `Attribute (attr, value) :: tl ->
append_addons (Attribute (base, attr, value)) tl
| `Pseudo (f, args) :: tl ->
append_addons (Pseudo (base, f, args)) tl
%} %}
(* Tokens *) (* Tokens *)
...@@ -207,39 +219,44 @@ ruleset: ...@@ -207,39 +219,44 @@ ruleset:
selector: selector:
| simple=simple_selector S* | simple=simple_selector S*
{ Simple simple } { simple }
| left=simple_selector S+ right=selector | left=simple_selector S+ right=selector
{ Combinator (Simple left, " ", right) } { Combinator (left, " ", right) }
| left=simple_selector S* com=combinator right=selector | left=simple_selector S* com=combinator right=selector
{ Combinator (Simple left, com, right) } { Combinator (left, com, right) }
%inline combinator: %inline combinator:
| PLUS S* { "+" } | PLUS S* { "+" }
| c=COMBINATOR S* { c } | c=COMBINATOR S* { c }
simple_selector: simple_selector:
| elem=element_name addons=element_addon* | elem=element_name addons=element_addon*
{ elem ^ String.concat "" addons } { append_addons elem addons }
| addons=element_addon+ | addons=element_addon+
{ String.concat "" addons } { append_addons No_element addons }
%inline element_addon: a=HASH | a=cls | a=attrib | a=pseudo { a } %inline element_addon:
| id=HASH { `Id id }
| addon=cls
| addon=attrib
| addon=pseudo { addon }
element_name: element_name:
| tag=IDENT { String.lowercase tag } | tag=IDENT { Element (String.lowercase tag) }
| STAR { "*" } | STAR { All_elements }
cls: cls:
| DOT name=IDENT | DOT name=IDENT
{ "." ^ name } { `Class name }
attrib: attrib:
| LBRACK S* left=IDENT S* right=pair(RELATION, rel_value)? RBRACK | LBRACK S* left=IDENT S* RBRACK
{ let right = match right with None -> "" | Some (op, term) -> op ^ term in { `Attribute (String.lowercase left, None) }
"[" ^ String.lowercase left ^ right ^ "]" } | LBRACK S* left=IDENT S* op=RELATION right=rel_value RBRACK
{ `Attribute (String.lowercase left, Some (op, right)) }
%inline rel_value: %inline rel_value:
| S* id=IDENT S* { id } | S* id=IDENT S* { Ident id }
| S* s=STRING S* { "\"" ^ s ^ "\"" } | S* s=STRING S* { Strlit s }
pseudo: pseudo:
| COLON id=IDENT | COLON id=IDENT
{ ":" ^ (String.lowercase id) } { `Pseudo (String.lowercase id, None) }
| COLON f=FUNCTION args=wslist(COMMA, simple_selector) RPAREN | COLON f=FUNCTION args=wslist(COMMA, simple_selector) RPAREN
{ ":" ^ String.lowercase f ^ "(" ^ String.concat "," args ^ ")" } { `Pseudo (String.lowercase f, Some args) }
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*))
......
...@@ -39,12 +39,30 @@ let string_of_declaration (name, value, important) = ...@@ -39,12 +39,30 @@ let string_of_declaration (name, value, important) =
let imp = if important then " !important" else "" in let imp = if important then " !important" else "" in
name ^ ": " ^ string_of_expr value ^ imp ^ ";" name ^ ": " ^ string_of_expr value ^ imp ^ ";"
let rec string_of_selector = function let rec stringify_selector w selector =
| Simple simple -> simple let str = stringify_selector w in
match selector with
| No_element -> ""
| All_elements -> "*"
| Element elem -> elem
| Id (base, id) ->
str base ^ "#" ^ id
| Class (base, cls) ->
str base ^ "." ^ cls
| Attribute (base, attr, None) ->
str base ^ "[" ^ attr ^ "]"
| Attribute (base, attr, Some (op, value)) ->
str base ^ "[" ^ attr ^ w ^ op ^ w ^ string_of_expr value ^ "]"
| Pseudo (base, sel, None) ->
str base ^ ":" ^ sel
| Pseudo (base, fn, Some args) ->
str base ^ ":" ^ fn ^ "(" ^ cat ("," ^ w) str args ^ ")"
| Combinator (left, " ", right) -> | Combinator (left, " ", right) ->
string_of_selector left ^ " " ^ string_of_selector right str left ^ " " ^ str right
| Combinator (left, com, right) -> | Combinator (left, com, right) ->
string_of_selector left ^ " " ^ com ^ " " ^ string_of_selector right str left ^ w ^ com ^ w ^ str right
let string_of_selector = stringify_selector " "
let string_of_media_expr = function let string_of_media_expr = function
| (feature, None) -> "(" ^ feature ^ ")" | (feature, None) -> "(" ^ feature ^ ")"
...@@ -140,10 +158,7 @@ let minify_declaration (name, value, important) = ...@@ -140,10 +158,7 @@ let minify_declaration (name, value, important) =
let imp = if important then "!important" else "" in let imp = if important then "!important" else "" in
name ^ ":" ^ minify_expr value ^ imp name ^ ":" ^ minify_expr value ^ imp
let rec minify_selector = function let rec minify_selector = stringify_selector ""
| Simple simple -> simple
| Combinator (left, com, right) ->
minify_selector left ^ com ^ minify_selector right
let minify_media_feature = function let minify_media_feature = function
| (feature, None) -> "(" ^ feature ^ ")" | (feature, None) -> "(" ^ feature ^ ")"
......
...@@ -11,9 +11,21 @@ type expr = ...@@ -11,9 +11,21 @@ type expr =
type declaration = string * expr * bool type declaration = string * expr * bool
type selector =
| No_element
| All_elements
| Element of string
| Id of selector * string
| Class of selector * string
| Pseudo of selector * string * selector list option
| Attribute of selector * string * (string * expr) option
| Combinator of selector * string * selector
(*
type selector = 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_expr = string * expr option
type media_query = string option * string option * media_expr list type media_query = string option * string option * media_expr list
......
...@@ -132,12 +132,26 @@ let transform_stylesheet f stylesheet = ...@@ -132,12 +132,26 @@ let transform_stylesheet f stylesheet =
in in
let TRAV_ALL(declaration, Declaration) in let TRAV_ALL(declaration, Declaration) in
let trav_selector = function let rec trav_selector = function
| Simple _ as s -> f (Selector s) | (No_element | All_elements | Element _) as elem ->
f (Selector elem)
| Id (base, id) ->
f (Selector (Id (expect_selector base, id)))
| Class (base, cls) ->
f (Selector (Class (expect_selector base, cls)))
| Attribute (base, attr, value) ->
f (Selector (Attribute (expect_selector base, attr, value)))
| Pseudo (base, sel, None) ->
f (Selector (Pseudo (expect_selector base, sel, None)))
| Pseudo (base, fn, Some args) ->
let args = trav_all_selector args in
f (Selector (Pseudo (expect_selector base, fn, Some args)))
| Combinator (left, com, right) -> | Combinator (left, com, right) ->
let left = expect_selector left in
let right = expect_selector right in
f (Selector (Combinator (left, com, right))) f (Selector (Combinator (left, com, right)))
in and EXPECT(selector, Selector)
let TRAV_ALL(selector, Selector) in and TRAV_ALL(selector, Selector) in
let trav_media_expr = function let trav_media_expr = function
| (_, None) as value -> | (_, None) as value ->
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment