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; � " & &⪢ 💯 ❤".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; � " & &⪢ 💯 ❤".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; � " & &⪢ 💯 ❤"
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; � " & &⪢ 💯 ❤"
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