Skip to content

Commit

Permalink
switch to REx parser
Browse files Browse the repository at this point in the history
  • Loading branch information
gimsieke committed May 28, 2017
1 parent d12acf7 commit 9e62b1d
Show file tree
Hide file tree
Showing 8 changed files with 2,505 additions and 2,602 deletions.
97 changes: 36 additions & 61 deletions ebnf-scheme/CSS3.ebnf
Original file line number Diff line number Diff line change
@@ -1,71 +1,58 @@
css ::= ( ( rule | simple_atrule | mediaquery ) )*
simple_atrule ::= ('@charset'|'@import'|'@namespace') (STRING|IDENT) ';'
rule ::= selectors_group '{' ( declaration ( ';' declaration)* ';'? )* '}'
mediaquery ::= mediarule '{' query_declaration ( query_declaration)* '}'
css ::= S* ( ( rule | simple_atrule | mediaquery | COMMENT) S* )*
simple_atrule ::= ('@charset'|'@import'|'@namespace') S+ STRING S* ';'
rule ::= selectors_group S? '{' S? (COMMENT? declaration ( S? ';' S? declaration)* ';'? S?)* COMMENT* '}'
mediaquery ::= mediarule S? '{' S? COMMENT* query_declaration ( S? COMMENT* query_declaration)* S? '}'
query_declaration ::= rule
declaration ::= property ':' (property ':')* values
declaration ::= property S? ':' (property ':')* S? values
selectors_group
::= selector ( COMMA selector )*
selector ::= simple_selector_sequence ( combinator? simple_selector_sequence)*
::= selector ( COMMENT? COMMA S* selector )*
selector ::= simple_selector_sequence ( combinator simple_selector_sequence )*
mediaquery_selector::= '(' declaration ')'
combinator
::= PLUS
| GREATER
| TILDE
/* ws: explicit */
::= PLUS S*
| GREATER S*
| TILDE S*
| S+
simple_selector_sequence
::= type_selector ( HASH | class | attrib | pseudo | negation | atrule | mediaquery_selector )*
::= ( type_selector | universal ) ( HASH | class | attrib | pseudo | negation | atrule | mediaquery_selector )*
| ( HASH | class | attrib | pseudo | negation | atrule| mediaquery_selector )+
/* ws: explicit */
type_selector
::= namespace_prefix? ( element_name | '*' )
/* ws: explicit */
::= namespace_prefix? element_name
namespace_prefix
::= ( IDENT | '*' )? '|'
/* ws: explicit */
element_name
::= IDENT
/* ws: explicit */
universal
::= namespace_prefix? '*'
class ::= '.' IDENT
/* ws: explicit */
mediarule ::= '@media' conditions ( conditions| mediaquery_selector )*
mediarule ::= '@media' S conditions ( S? conditions| S? mediaquery_selector )*
atrule ::= '@' IDENT
/* ws: explicit */
conditions ::= ('and'|'screen'|'or'|'only'|'not'|'amzn-mobi'|'amzn-kf8'|',')
attrib ::= '[' namespace_prefix? IDENT ( ( PREFIXMATCH | SUFFIXMATCH | SUBSTRINGMATCH | '=' | INCLUDES | DASHMATCH ) ( IDENT | STRING ) )? ']'
/* ws: explicit */
attrib ::= '[' S* namespace_prefix? IDENT S* ( ( PREFIXMATCH | SUFFIXMATCH | SUBSTRINGMATCH | '=' | INCLUDES | DASHMATCH ) S* ( IDENT | STRING ) S* )? ']'
pseudo ::= ':' ':'? ( IDENT | functional_pseudo )
/* ws: explicit */
functional_pseudo
::= FUNCTION expression ')'
/* ws: explicit */
::= FUNCTION S* expression ')'

property ::= ( STRING | IDENT )
values ::= value ( value | '/' value )* important?
value ::= ( URL | PLUS | HEX | PERCENTAGE | '-' | DIMENSION | NUMBER | STRING | IDENT | COMMA | functional_pseudo) /*(COMMA IDENT)?*/
/* ws: explicit */
expression ::= ( ( PLUS | PERCENTAGE | URL | HEX | '-' | DIMENSION | NUMBER | STRING | IDENT | COMMA) )+
negation ::= NOT negation_arg ')'
/* ws: explicit */
values ::= value (S value | '/' value )* ( S* COMMA S* value (S value | '/' value )* )* important?
value ::= ( URL | PLUS | HEX | PERCENTAGE | '-' | DIMENSION | NUMBER | STRING | IDENT | functional_pseudo)
expression ::= ( ( PLUS | PERCENTAGE | URL | HEX | '-' | DIMENSION | NUMBER | STRING | IDENT | COMMA) S* )+
negation ::= NOT S* negation_arg S* ')'
negation_arg
::= type_selector
| universal
| HASH
| class
| attrib
| pseudo
/* ws: explicit */

Ignore ::= S^WS | COMMENT
/* ws: definition */
COMMENT ::= '/*' CommentContents '*/'

STRING ::= '"' STRING_CONTENT1 '"' | "'" STRING_CONTENT2 "'"

<?TOKENS?>
EOF ::= $
URL ::= 'url(' ("'"|#x0027|nmchar|'/'|'.')+ ')'
/* ws: explicit */
important ::= '!important'
important ::= S '!important'
ident ::= [-]? nmstart nmchar*
/* ws: explicit */
name ::= nmchar+
nmstart ::= [_a-zA-Z]
| nonascii
Expand All @@ -79,14 +66,13 @@ nmchar ::= [_a-zA-Z0-9#x2D]
| escape
num ::= [0-9]+
| [0-9]* '.' [0-9]+
string ::= string1
| string2
string1 ::= '"' ( [^#x000A#x000D#x000C\"] | '\' nl | nonascii | escape )* '"'
string2 ::= "'" ( [^#x000A#x000D#x000C\'] | '\' nl | nonascii | escape )* "'"
nl ::= #x000A
| #x000D #x000A
| #x000D
| #x000C
STRING_CONTENT1 ::= ( [^#x000A#x000D#x000C\"] | '\' nl | nonascii | escape )*
STRING_CONTENT2 ::= ( [^#x000A#x000D#x000C\'] | '\' nl | nonascii | escape )*
w ::= [ #x0009#x000D#x000A#x000C]*
N ::= 'n'
| '\' zero-to-four-zeroes ( '4e' | '6e' ) ( #x000D #x000A | [ #x0009#x000D#x000A#x000C] )?
| '\n'
Expand All @@ -96,8 +82,7 @@ O ::= 'o'
T ::= 't'
| '\' zero-to-four-zeroes ( '54' | '74' ) ( #x000D #x000A | [ #x0009#x000D#x000A#x000C] )?
| '\t'
S ::= ( #x0020 | #x0009 | #x000D | #x000A )+
SPACE ::= #x0020
S ::= [ #x0009#x000D#x000A#x000C]+
INCLUDES ::= '~='
DASHMATCH
::= '|='
Expand All @@ -108,28 +93,18 @@ SUFFIXMATCH
SUBSTRINGMATCH
::= '*='
IDENT ::= ident
STRING ::= string
FUNCTION ::= ident '('
NUMBER ::= '-'?num
HASH ::= '#' name
HEX ::= '#' one-to-six-hex-digits
PERCENTAGE ::= num '%'
PLUS ::= '+'
GREATER ::= '>'
COMMA ::= ','
TILDE ::= '~'
PLUS ::= w '+'
GREATER ::= w '>'
COMMA ::= w ','
TILDE ::= w '~'
NOT ::= ':' N O T '('
DIMENSION ::= '-'?num ('em' | 'px' | 'fr' | 'cm' | 'mm' | 'in' | 'pt' | 'pc'|'vh')
Char ::= #x0009
| #x000A
| #x000D
| [#x0020-#xD7FF]
| [#xE000-#xFFFD]
| [#x10000-#x10FFFF]
CommentContents
::=( ( Char+ - ( Char* ( '/*' | '*/' ) Char* ) ) - ( Char* '/' ) ) &'*'
| ( Char+ - ( Char* ( '/*' | '*/' ) Char* ) ) &'*/'

DIMENSION ::= '-'?num S? ('em' | 'px' | 'fr' | 'cm' | 'mm' | 'in' | 'pt' | 'pc'|'vh')
COMMENT ::= S* '/*' S? (nmchar|':'|';'|','|S|'='|'('|')'|'#'|"'"|'"'|'/'|'.'|'!'|'?')+ S? '*/' S?
one-to-six-hex-digits
::= [0-9a-fA-F]
| [0-9a-fA-F] [0-9a-fA-F]
Expand Down
133 changes: 103 additions & 30 deletions xpl/css.xpl
Original file line number Diff line number Diff line change
Expand Up @@ -12,50 +12,123 @@
<p:import href="http://xmlcalabash.com/extension/steps/library-1.0.xpl"/>
<p:import href="http://transpect.io/xproc-util/store-debug/xpl/store-debug.xpl"/>
<p:import href="http://transpect.io/xproc-util/file-uri/xpl/file-uri.xpl"/>

<p:import href="http://transpect.io/xproc-util/simple-progress-msg/xpl/simple-progress-msg.xpl"/>

<p:declare-step type="css:parse" name="parse">


<p:documentation>In order to invoke this step directly with Calabash, you need to specify -l css-tools/xpl/css.xpl and
-s {http://www.w3.org/1996/css}parse</p:documentation>

<p:input port="source" primary="true">
<p:documentation>an XHTML document</p:documentation>
</p:input>
<p:input port="stylesheet">
<p:document href="../xsl/REx_css-parser.xsl"/>
<p:documentation>a stylesheet that can be overriden, e.g. if CSS2.1 features are wanted only or if you want to use the
<p:documentation>a stylesheet that can be overridden, e.g. if CSS2.1 features are wanted only or if you want to use the
oldschool regex-based parser</p:documentation>
</p:input>
<p:output port="result" primary="true">
<p:documentation>XML representation of the CSS. See css:expand</p:documentation>
</p:output>

<p:output port="report" sequence="true">
<p:pipe port="report" step="apply-parsing-xsl"/>
</p:output>

<p:option name="debug" required="false" select="'no'"/>
<p:option name="debug-dir-uri" required="false" select="resolve-uri('debug')"/>

<tr:file-uri name="base-uri">
<p:documentation>
Calculate base-uri
</p:documentation>
<p:with-option name="filename" select="(base-uri(/*), static-base-uri())[1]">
<p:pipe port="source" step="parse"/>
</p:with-option>
</tr:file-uri>

<p:xslt name="parsing-xsl">
<p:input port="parameters">
<p:empty/>
</p:input>
<p:option name="status-dir-uri" required="false" select="resolve-uri('status')"/>

<tr:file-uri name="base-uri">
<p:documentation> Calculate base-uri </p:documentation>
<p:with-option name="filename" select="(base-uri(/*), static-base-uri())[1]">
<p:pipe port="source" step="parse"/>
</p:with-option>
</tr:file-uri>

<p:try name="apply-parsing-xsl">
<p:documentation>First try parsing with comments, then try parsing without comments. Parsing with comments
will fail if comments are located in selectors or properties.</p:documentation>
<p:group>
<p:output port="result" primary="true"/>
<p:output port="report" sequence="true">
<p:inline><c:ok/></p:inline>
</p:output>
<p:xslt name="apply-parsing-xsl-with-comments">
<p:input port="parameters"><p:empty/></p:input>
<p:input port="stylesheet">
<p:pipe port="stylesheet" step="parse"/>
</p:input>
<p:input port="source">
<p:pipe port="source" step="parse"/>
</p:input>
<p:with-param name="base-uri" select="/c:result/@local-href">
<p:pipe port="result" step="base-uri"/>
</p:with-param>
<p:with-param name="remove-comments" select="'no'"/>
</p:xslt>
<tr:store-debug pipeline-step="css-expand/css.1.parse-try">
<p:with-option name="active" select="$debug"/>
<p:with-option name="base-uri" select="$debug-dir-uri"/>
</tr:store-debug>
</p:group>
<p:catch name="catch">
<p:output port="result" primary="true"/>
<p:output port="report" sequence="true">
<p:pipe port="result" step="info"/>
</p:output>

<tr:propagate-caught-error name="propagate" msg-file="css-parsing-error.txt" code="tr:CSS01" severity="warning">
<p:with-option name="status-dir-uri" select="$status-dir-uri"/>
<p:input port="source">
<p:pipe port="error" step="catch"/>
</p:input>
</tr:propagate-caught-error>

<p:insert position="last-child" match="/c:errors" name="info">
<p:input port="insertion">
<p:inline>
<c:error code="tr:CSS02" type="info">Reverting to CSS parsing with all comments removed. You can try to
help the parser by moving comments from selectors and properties outside the rules.</c:error>
</p:inline>
</p:input>
</p:insert>

<p:sink/>

<p:xslt name="apply-parsing-xsl-without-comments">
<p:input port="parameters">
<p:empty/>
</p:input>
<p:input port="stylesheet">
<p:pipe port="stylesheet" step="parse"/>
</p:input>
<p:input port="source">
<p:pipe port="source" step="parse"/>
</p:input>
<p:with-param name="base-uri" select="/c:result/@local-href">
<p:pipe port="result" step="base-uri"/>
</p:with-param>
<p:with-param name="remove-comments" select="'yes'"/>
</p:xslt>
</p:catch>
</p:try>

<tr:store-debug pipeline-step="css-expand/css.1.parse">
<p:with-option name="active" select="$debug"/>
<p:with-option name="base-uri" select="$debug-dir-uri"/>
</tr:store-debug>

<p:xslt name="post-process" initial-mode="post-process">
<p:input port="parameters"><p:empty/></p:input>
<p:input port="stylesheet">
<!--<p:document href="../xsl/css-parser.xsl"/>-->
<p:pipe port="stylesheet" step="parse"/>
</p:input>
<p:input port="source">
<p:pipe port="source" step="parse"/>
</p:input>
<p:with-param name="base-uri" select="/c:result/@local-href">
<p:pipe port="result" step="base-uri"/>
</p:with-param>
<p:with-param name="base-uri" select="/c:result/@local-href">
<p:pipe port="result" step="base-uri"/>
</p:with-param>
</p:xslt>

<tr:store-debug pipeline-step="css-expand/css.1.parse">
<tr:store-debug pipeline-step="css-expand/css.2.xml-representation">
<p:with-option name="active" select="$debug"/>
<p:with-option name="base-uri" select="$debug-dir-uri"/>
</tr:store-debug>
Expand All @@ -68,9 +141,9 @@
<p:documentation>an XHTML document</p:documentation>
</p:input>
<p:input port="stylesheet">
<!--<p:document href="../xsl/css-parser.xsl"/>-->
<p:document href="../xsl/REx_css-parser.xsl"/>
<p:documentation>a stylesheet that can be overriden, e.g. if CSS2.1 features are wanted only or if you want to use the
oldschool regex-based parser</p:documentation>
<p:documentation>a stylesheet that can be overriden, e.g. if CSS2.1 features are wanted only</p:documentation>
</p:input>
<p:output port="result" primary="true">
<p:documentation>an XHTML document with CSSa attributes (in addition to its style elements/attributes/linked CSS
Expand Down Expand Up @@ -113,7 +186,7 @@
</p:input>
</p:xslt>

<tr:store-debug pipeline-step="css-expand/css.2.create-xsl" extension="xsl">
<tr:store-debug pipeline-step="css-expand/css.4.create-xsl" extension="xsl">
<p:with-option name="active" select="$debug"/>
<p:with-option name="base-uri" select="$debug-dir-uri"/>
</tr:store-debug>
Expand All @@ -132,7 +205,7 @@
</p:input>
</p:xslt>

<tr:store-debug pipeline-step="css-expand/css.3.expanded">
<tr:store-debug pipeline-step="css-expand/css.5.expanded">
<p:with-option name="active" select="$debug"/>
<p:with-option name="base-uri" select="$debug-dir-uri"/>
</tr:store-debug>
Expand Down
Loading

0 comments on commit 9e62b1d

Please sign in to comment.