From: Vsevolod Stakhov Date: Wed, 20 Jan 2021 21:17:32 +0000 (+0000) Subject: [Project] Add css syntax (adopted from ebnf) X-Git-Tag: 3.0~744 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e422091bab8dd0acc917439e8c0515ee1df1a740;p=rspamd.git [Project] Add css syntax (adopted from ebnf) --- diff --git a/src/libserver/css/css_syntax.rl b/src/libserver/css/css_syntax.rl new file mode 100644 index 000000000..93da44b45 --- /dev/null +++ b/src/libserver/css/css_syntax.rl @@ -0,0 +1,110 @@ +%%{ + # CSS3 EBNF derived + machine css_syntax; + + # Primitive Atoms + COMMENT = ( + '/*' ( any )* :>> '*/' + ); + QUOTED_STRING = ('"' ( [^"\\] | /\\./ )* "'"); + BARE_URL_CHARS = ((0x21 + | 0x23..0x26 + | 0x2A..0xFF)+); + BARE_URL = BARE_URL_CHARS; + URL = 'url(' ( QUOTED_STRING | space* BARE_URL space* ) ')'; + nonascii = [^0x00-0x7F]; + nmstart = ([_a-zA-Z] | nonascii); + nmchar = ([_a-zA-Z0-9] | 0x2D | nonascii); + name = nmchar+; + num = ([0-9]+ | ([0-9]* '.' [0-9]+)); + CRLF = "\r\n" | ("\r" [^\n]) | ([^\r] "\n"); + IDENT = ([\-]? nmstart nmchar*); + ATTR = 'attr(' IDENT ')'; + + DIMENSION = '-'? num space? ( 'ch' | 'cm' | 'em' | 'ex' | 'fr' | 'in' | 'mm' | 'pc' | 'pt' | 'px' | 'Q' | 'rem' | 'vh' | 'vmax' | 'vmin' | 'vw' | 'dpi' ); + NUMBER = '-'? num; + HASH = '#' name; + HEX = '#' [0-9a-fA-F]{1,6}; + PERCENTAGE = '-'? num '%'; + INCLUDES = '~='; + DASHMATCH = '|='; + PREFIXMATCH = '^='; + SUFFIXMATCH = '$='; + SUBSTRINGMATCH = '*='; + PLUS = '+'; + GREATER = '>'; + COMMA = ','; + TILDE = '~'; + S = space; + + # Property name + property = ( QUOTED_STRING | IDENT ); + + # Values + important = space* '!' space* 'important'; + expression = ( ( '+' | PERCENTAGE | URL | ATTR | HEX | '-' | DIMENSION | NUMBER | QUOTED_STRING | IDENT | ',') S* )+; + functional_pseudo = (IDENT - ('attr'|'url')) '(' space* expression? ')'; + value = ( URL | ATTR | PLUS | HEX | PERCENTAGE | '-' | DIMENSION | NUMBER | QUOTED_STRING | IDENT | functional_pseudo); + values = value (space value | '/' value )* ( space* ',' space* value (space value | '/' value )* )* important?; + + # Declaration definition + declaration = (property space? ':' (property ':')* space? values); + + # Selectors + class = '.' IDENT; + element_name = IDENT; + namespace_prefix = ( IDENT | '*' )? '|'; + type_selector = namespace_prefix? element_name; + universal = namespace_prefix? '*'; + attrib = '[' space* namespace_prefix? IDENT space* ( ( PREFIXMATCH | SUFFIXMATCH | SUBSTRINGMATCH | '=' | INCLUDES | DASHMATCH ) space* ( IDENT | QUOTED_STRING ) space* )? ']'; + pseudo = ':' ':'? ( IDENT | functional_pseudo ); + atrule = '@' IDENT; + mediaquery_selector = '(' declaration ')'; + negation_arg = type_selector + | universal + | HASH + | class + | attrib + | pseudo; + negation = 'NOT'|'not' space* negation_arg space* ')'; + # Haha, so simple... + # there should be also mediaquery_selector but it makes grammar too large, so rip it off + simple_selector_sequence = ( type_selector | universal ) ( HASH | class | attrib | pseudo | negation | atrule )* + | ( HASH | class | attrib | pseudo | negation | atrule )+; + combinator = space* PLUS space* + | space* GREATER space* + | space* TILDE space* + | space+; + # Combine simple stuff and obtain just... an ordinary selector, bingo + selector = simple_selector_sequence ( combinator simple_selector_sequence )*; + # Multiple beasts + selectors_group = selector ( COMMENT? ',' space* selector )*; + + # Rules + # This is mostly used stuff + rule = selectors_group space? "{" space* + (COMMENT? space* declaration ( space? ";" space? declaration?)* ";"? space?)* COMMENT* space* '}'; + query_declaration = rule; + + # Areas used in css + arearule = '@'('bottom-left'|'bottom-right'|'top-left'|'top-right'); + areaquery = arearule space? '{' space* (COMMENT? space* declaration ( S? ';' S? declaration?)* ';'? space?)* COMMENT* space* '}'; + # Printed media stuff, useless but we have to parse it :( + printcssrule = '@media print'; + pagearea = ':'('left'|'right'); + pagerule = '@page' space? pagearea?; + pagequery = pagerule space? '{' space* (areaquery| (COMMENT? space* declaration ( space? ';' space? declaration?)* ';'? S?)*) COMMENT* space* '}'; + printcssquery = printcssrule S? '{' ( S? COMMENT* S? (pagequery| COMMENT|query_declaration) S*)* S? '}'; + # Something that defines media + conditions = ('and'|'screen'|'or'|'only'|'not'|'amzn-mobi'|'amzn-kf8'|'amzn-mobi7'|','); + mediarule = '@media' space conditions ( space? conditions| space? mediaquery_selector )*; + mediaquery = mediarule space? '{' ( space? COMMENT* query_declaration)* S? '}'; + + simple_atrule = ("@charset"|"@namespace") space+ QUOTED_STRING space* ";"; + + import_rule = "@import" space+ ( QUOTED_STRING | URL ) space* ";"; + + # Final css definition + css_style = space* ( ( rule | simple_atrule | import_rule | mediaquery | printcssquery | COMMENT) space* )*; + +}%% \ No newline at end of file