1
1
use nom:: branch:: alt;
2
2
use nom:: bytes:: streaming:: * ;
3
3
use nom:: character:: streaming:: * ;
4
- use nom:: combinator:: { complete, map, recognize, success} ;
5
- use nom:: error:: Error ;
6
- use nom:: multi:: fold_many0;
7
- use nom:: sequence:: { delimited, pair, preceded, separated_pair} ;
8
- use nom:: IResult ;
4
+ use nom:: combinator:: { complete, map, not , peek , recognize, success, verify } ;
5
+ use nom:: error:: { Error , ParseError } ;
6
+ use nom:: multi:: { fold_many0, length_data , many0 , many_till } ;
7
+ use nom:: sequence:: { delimited, pair, preceded, separated_pair, tuple } ;
8
+ use nom:: { IResult , Parser } ;
9
9
10
10
#[ derive( Debug ) ]
11
11
enum Chunk < ' a > {
@@ -26,7 +26,7 @@ fn parse(input: &str) -> IResult<&str, Vec<Chunk>, Error<&str>> {
26
26
}
27
27
28
28
fn chunk ( input : & str ) -> IResult < & str , Vec < Chunk > , Error < & str > > {
29
- alt ( ( text, alt ( ( esi_tag, html) ) ) ) ( input)
29
+ alt ( ( text, esi_tag, html) ) ( input)
30
30
}
31
31
32
32
fn esi_tag ( input : & str ) -> IResult < & str , Vec < Chunk > , Error < & str > > {
@@ -50,10 +50,11 @@ fn esi_tag_name(input: &str) -> IResult<&str, &str, Error<&str>> {
50
50
}
51
51
52
52
fn attributes ( input : & str ) -> IResult < & str , Vec < ( & str , & str ) > , Error < & str > > {
53
- map (
54
- separated_pair ( preceded ( multispace1, alpha1) , char ( '=' ) , xmlstring) ,
55
- |( name, value) | vec ! [ ( name, value) ] ,
56
- ) ( input)
53
+ many0 ( separated_pair (
54
+ preceded ( multispace1, alpha1) ,
55
+ char ( '=' ) ,
56
+ xmlstring,
57
+ ) ) ( input)
57
58
}
58
59
59
60
fn xmlstring ( input : & str ) -> IResult < & str , & str , Error < & str > > {
@@ -66,12 +67,25 @@ fn html(input: &str) -> IResult<&str, Vec<Chunk>, Error<&str>> {
66
67
67
68
fn script ( input : & str ) -> IResult < & str , Vec < Chunk > , Error < & str > > {
68
69
map (
69
- recognize ( delimited (
70
- delimited ( tag ( "<script" ) , alt ( ( is_not ( ">" ) , success ( "" ) ) ) , char ( '>' ) ) ,
71
- take_until ( "</script" ) ,
72
- delimited ( tag ( "</script" ) , alt ( ( is_not ( ">" ) , success ( "" ) ) ) , char ( '>' ) ) ,
70
+ tuple ( (
71
+ recognize ( verify (
72
+ delimited ( tag_no_case ( "<script" ) , attributes, char ( '>' ) ) ,
73
+ |attrs : & Vec < ( & str , & str ) > | !attrs. iter ( ) . any ( |( k, _) | k == & "src" ) ,
74
+ ) ) ,
75
+ length_data ( map (
76
+ peek ( many_till ( anychar, tag_no_case ( "</script" ) ) ) ,
77
+ |( v, _) | v. len ( ) ,
78
+ ) ) ,
79
+ recognize ( delimited (
80
+ tag_no_case ( "</script" ) ,
81
+ alt ( ( is_not ( ">" ) , success ( "" ) ) ) ,
82
+ char ( '>' ) ,
83
+ ) ) ,
73
84
) ) ,
74
- |s : & str | vec ! [ Chunk :: Text ( s) ] ,
85
+ |( start, script, end) | {
86
+ println ! ( "script parser succeeded" ) ;
87
+ vec ! [ Chunk :: Text ( start) , Chunk :: Text ( script) , Chunk :: Text ( end) ]
88
+ } ,
75
89
) ( input)
76
90
}
77
91
@@ -99,13 +113,18 @@ mod tests {
99
113
#[ test]
100
114
fn test_new_parse ( ) {
101
115
let x = parse (
102
- "<a>foo</a><bar />baz<esi:vars name=\" $hello\" ><baz><script> less < more </script>" ,
116
+ "<a>foo</a><bar />baz<esi:vars name=\" $hello\" ><sCripT src= \" whatever \" >< baz><script> less < more </script>" ,
103
117
) ;
104
118
println ! ( "{:?}" , x) ;
105
119
}
106
120
#[ test]
107
121
fn test_new_parse_script ( ) {
108
- let x = script ( "<script> less < more </script>" ) ;
122
+ let x = script ( "<sCripT> less < more </scRIpt>" ) ;
123
+ println ! ( "{:?}" , x) ;
124
+ }
125
+ #[ test]
126
+ fn test_new_parse_script_with_src ( ) {
127
+ let x = parse ( "<sCripT src=\" whatever\" >" ) ;
109
128
println ! ( "{:?}" , x) ;
110
129
}
111
130
#[ test]
0 commit comments