text_parsing/entities/
parser.rs

1use super::{
2    entities::{Entity,Instance},
3    state::EntityState,
4};
5use crate::{
6    ParserResult,
7    Source, SourceEvent, ParserEvent, SourceResult, Local,
8    Parser, Runtime, PipeParser, IntoPipeParser,
9};
10
11/*
12
13  Entities: https://www.w3.org/TR/html5/entities.json
14
15
16    Semicolon may be optional (html legacy)
17
18    <   <  <
19
20    "&" + Name + ";"  
21
22    // without parametr entities [ %name; ]  ????
23
24	NameStartChar	   ::=   	":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
25   	NameChar	   ::=   	NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
26   	Name	   ::=   	NameStartChar (NameChar)*
27
28*/
29
30
31
32#[derive(Debug,Clone)]
33pub struct Builder {
34
35}
36impl Builder {
37    pub fn new() -> Builder {
38        Builder { }
39    }
40    pub fn create(self) -> EntityParser {
41        EntityParser(Runtime::new(()))
42    }
43}
44
45pub struct EntityParser(Runtime<EntityState,Entity,()>);
46impl Parser for EntityParser {
47    type Data = Entity;
48    
49    fn next_event<S: Source>(&mut self, src: &mut S) -> ParserResult<Entity> {
50        self.0.next_event(src)
51    }
52}
53
54impl IntoPipeParser for EntityParser {
55    type Piped = PipedEntityParser;
56    
57    fn into_piped(self) -> Self::Piped {
58        PipedEntityParser {
59            parser: self.0,
60            tmp: None,
61        }
62    }
63}
64
65pub struct PipedEntityParser {
66    parser: Runtime<EntityState,Entity,()>,
67    tmp: Option<Local<SourceEvent>>,
68}
69
70impl PipeParser for PipedEntityParser {
71    fn next_char<S: Source>(&mut self, src: &mut S) -> SourceResult {
72        Ok(match self.tmp.take() {
73            Some(local_se) => Some(local_se), 
74            None => match self.parser.next_event(src)? {
75                Some(local_ent) => {
76                    let (local,ent) = local_ent.into_inner();
77                    match ent {
78                        ParserEvent::Char(c) => Some(local.local(SourceEvent::Char(c))),
79                        ParserEvent::Breaker(b) => Some(local.local(SourceEvent::Breaker(b))),
80                        ParserEvent::Parsed(ent) => match ent.entity {
81                            Instance::Char(c) => Some(local.local(SourceEvent::Char(c))),
82                            Instance::Char2(c1,c2) => {
83                                self.tmp = Some(local.local(SourceEvent::Char(c2)));
84                                Some(local.local(SourceEvent::Char(c1)))
85                            },
86                        },
87                    }
88                },
89                None => None,
90            },
91        })
92    }
93}
94
95
96#[cfg(test)]
97mod tests {
98    //use crate::*;
99    //use super::*;
100    
101    /*#[test]
102    fn basic() {
103        let mut src = " &blabla; &#111111111; &quot &AMP; &&GreaterGreater; &#128175; &#x2764;".into_source();
104        let mut parser = Builder::new().create();
105
106        while let Some(local_event) = parser.next_event(&mut src).unwrap() {
107            println!("{:?}",local_event);
108        }
109        panic!();
110    }
111
112    #[test]
113    fn basic_piped() {
114        let mut src = " &blabla; &#111111111; &quot &AMP; &&GreaterGreater; &#128175; &#x2764;".into_source();
115        let mut parser = Builder::new().create().into_piped();
116
117        while let Some(local_se) = parser.next_char(&mut src).unwrap() {
118            println!("{:?}",local_se);
119        }
120        panic!();
121    }
122
123    #[test]
124    fn basic_piped_2() {        
125        let mut src = " &blabla; &#111111111; &quot &AMP; &&GreaterGreater; &#128175; &#x2764;"
126            .into_source()
127            .pipe(Builder::new().create().into_piped());
128
129        while let Some(local_se) = src.next_char().unwrap() {
130            println!("{:?}",local_se);
131        }
132        panic!();
133    }
134    
135    #[test]
136    fn basic_piped_3() {        
137        let mut src = " &blabla; &#111111111; &quot &AMP; &&GreaterGreater; &#128175; &#x2764;"
138            .into_source()
139            .pipe(Builder::new().create().piped(|_| None));
140
141        while let Some(local_se) = src.next_char().unwrap() {
142            println!("{:?}",local_se);
143        }
144        panic!();
145    }
146*/
147}
148