1use crate::structs::Color;
2use crate::structs::Font;
3use crate::structs::RichText;
4use crate::structs::TextElement;
5use crate::structs::UnderlineValues;
6use crate::structs::VerticalAlignmentRunValues;
7use chrono::format;
8use html_parser::{Dom, Element, Node};
9use std::collections::HashMap;
10use thin_vec::ThinVec;
11
12#[inline]
33pub fn html_to_richtext(html: &str) -> Result<RichText, html_parser::Error> {
34 html_to_richtext_custom(html, &DataAnalysis::default())
35}
36
37#[inline]
44pub fn html_to_richtext_custom(
45 html: &str,
46 method: &dyn AnalysisMethod,
47) -> Result<RichText, html_parser::Error> {
48 let dom = Dom::parse(html)?;
49 let data = read_node(&dom.children, &Vec::new());
50 let result = make_rich_text(&data, method);
51 Ok(result)
52}
53
54fn read_node(node_list: &Vec<Node>, parent_element: &[HfdElement]) -> ThinVec<HtmlFlatData> {
55 let mut result: ThinVec<HtmlFlatData> = ThinVec::new();
56
57 if node_list.is_empty() {
58 return result;
59 }
60
61 let mut data = HtmlFlatData::default();
62 data.element.extend_from_slice(parent_element);
63
64 for node in node_list {
65 match node {
66 Node::Text(text) => {
67 data.text = format!("{}{}", data.text, text);
68 }
69 Node::Element(element) => {
70 if &element.name == "br" {
71 data.text = format!("{}{}", data.text, "\n");
72 continue;
73 }
74 if &data.text != "" {
75 result.push(data);
76 data = HtmlFlatData::default();
77 data.element.extend_from_slice(parent_element);
78 }
79
80 let mut elm: HfdElement = HfdElement::default();
81 elm.name = element.name.to_string();
82
83 elm.attributes = element
84 .attributes
85 .iter()
86 .map(|(name, value)| {
87 (
88 name.clone(),
89 value.as_ref().map(|v| v.to_string()).unwrap_or_default(),
90 )
91 })
92 .collect();
93
94 elm.classes = element.classes.clone().into();
95 data.element.push(elm);
96
97 let mut children = read_node(&element.children, &data.element);
98 result.append(&mut children);
99
100 data = HtmlFlatData::default();
101 data.element.extend_from_slice(parent_element);
102 }
103 _ => {}
104 }
105 }
106 if &data.text != "" {
107 result.push(data);
108 }
109 result
110}
111
112fn make_rich_text(html_flat_data_list: &[HtmlFlatData], method: &dyn AnalysisMethod) -> RichText {
113 let mut result = RichText::default();
114
115 for html_flat_data in html_flat_data_list {
116 let mut font_name: Option<&str> = method.font_name(html_flat_data);
117 let mut size: Option<f64> = method.size(html_flat_data);
118 let mut color: Option<String> = method.color(html_flat_data);
119 let mut is_bold: bool = method.is_bold(html_flat_data);
120 let mut is_italic: bool = method.is_italic(html_flat_data);
121 let mut is_underline: bool = method.is_underline(html_flat_data);
122 let mut is_superscript: bool = method.is_superscript(html_flat_data);
123 let mut is_subscript: bool = method.is_subscript(html_flat_data);
124 let mut is_strikethrough: bool = method.is_strikethrough(html_flat_data);
125
126 let mut text_element = TextElement::default();
127 let mut font = Font::default();
128
129 if let Some(v) = font_name {
130 font.set_name(v);
131 }
132
133 if let Some(v) = size {
134 font.set_size(v);
135 }
136
137 if let Some(v) = color {
138 let argb = v;
139 let mut clr = Color::default();
140 clr.set_argb(argb);
141 font.set_color(clr);
142 }
143
144 if is_bold {
145 font.set_bold(is_bold);
146 }
147 if is_italic {
148 font.set_italic(is_italic);
149 }
150 if is_underline {
151 font.get_font_underline_mut()
152 .set_val(UnderlineValues::Single);
153 }
154 if is_superscript {
155 font.get_vertical_text_alignment_mut()
156 .set_val(VerticalAlignmentRunValues::Superscript);
157 }
158 if is_subscript {
159 font.get_vertical_text_alignment_mut()
160 .set_val(VerticalAlignmentRunValues::Subscript);
161 }
162 if is_strikethrough {
163 font.set_strikethrough(is_strikethrough);
164 }
165
166 text_element.set_text(&html_flat_data.text);
167 text_element.set_run_properties(font);
168 result.add_rich_text_elements(text_element);
169 }
170 result
171}
172
173#[derive(Clone, Default, Debug)]
174pub struct HtmlFlatData {
175 text: String,
176 element: ThinVec<HfdElement>,
177}
178
179#[derive(Clone, Default, Debug)]
180pub struct HfdElement {
181 name: String,
182 attributes: HashMap<String, String>,
183 classes: ThinVec<String>,
184}
185impl HfdElement {
186 #[inline]
187 pub fn has_name(&self, name: &str) -> bool {
188 self.name == name
189 }
190
191 #[inline]
192 pub fn get_by_name_and_attribute(&self, name: &str, attribute: &str) -> Option<&str> {
193 self.attributes
194 .get(attribute)
195 .and_then(|v| (self.name == name).then(|| v))
196 .map(|x| x.as_str())
197 }
198
199 #[inline]
200 pub fn contains_class(&self, class: &str) -> bool {
201 self.classes.contains(&class.to_string())
202 }
203}
204
205pub trait AnalysisMethod {
206 fn is_tag(&self, html_flat_data: &HtmlFlatData, tag: &str) -> bool;
207 fn font_name<'a>(&'a self, html_flat_data: &'a HtmlFlatData) -> Option<&'a str>;
208 fn size(&self, html_flat_data: &HtmlFlatData) -> Option<f64>;
209 fn color(&self, html_flat_data: &HtmlFlatData) -> Option<String>;
210 fn is_bold(&self, html_flat_data: &HtmlFlatData) -> bool;
211 fn is_italic(&self, html_flat_data: &HtmlFlatData) -> bool;
212 fn is_underline(&self, html_flat_data: &HtmlFlatData) -> bool;
213 fn is_superscript(&self, html_flat_data: &HtmlFlatData) -> bool;
214 fn is_subscript(&self, html_flat_data: &HtmlFlatData) -> bool;
215 fn is_strikethrough(&self, html_flat_data: &HtmlFlatData) -> bool;
216}
217
218#[derive(Clone, Default, Debug)]
219struct DataAnalysis {}
220impl AnalysisMethod for DataAnalysis {
221 #[inline]
222 fn font_name<'a>(&'a self, html_flat_data: &'a HtmlFlatData) -> Option<&str> {
223 html_flat_data
224 .element
225 .iter()
226 .find_map(|element| element.get_by_name_and_attribute("font", "face"))
227 }
228
229 #[inline]
230 fn size(&self, html_flat_data: &HtmlFlatData) -> Option<f64> {
231 html_flat_data.element.iter().find_map(|element| {
232 element
233 .get_by_name_and_attribute("font", "size")
234 .and_then(|v| v.parse::<f64>().ok())
235 })
236 }
237
238 fn color(&self, html_flat_data: &HtmlFlatData) -> Option<String> {
239 let mut result: Option<String> = None;
240 html_flat_data
241 .element
242 .iter()
243 .flat_map(|element| element.get_by_name_and_attribute("font", "color"))
244 .find_map(|v| {
245 let color = v.trim_start_matches('#').to_uppercase();
246 COLOR_MAP
247 .iter()
248 .find_map(|(key, value)| {
249 (*key.to_uppercase() == color).then(|| value.to_uppercase())
250 })
251 .or_else(|| Some(color))
252 })
253 }
254
255 #[inline]
256 fn is_tag(&self, html_flat_data: &HtmlFlatData, tag: &str) -> bool {
257 html_flat_data
258 .element
259 .iter()
260 .any(|element| element.has_name(tag))
261 }
262
263 #[inline]
264 fn is_bold(&self, html_flat_data: &HtmlFlatData) -> bool {
265 self.is_tag(html_flat_data, "b") || self.is_tag(html_flat_data, "strong")
266 }
267
268 #[inline]
269 fn is_italic(&self, html_flat_data: &HtmlFlatData) -> bool {
270 self.is_tag(html_flat_data, "i") || self.is_tag(html_flat_data, "em")
271 }
272
273 #[inline]
274 fn is_underline(&self, html_flat_data: &HtmlFlatData) -> bool {
275 self.is_tag(html_flat_data, "u") || self.is_tag(html_flat_data, "ins")
276 }
277
278 #[inline]
279 fn is_superscript(&self, html_flat_data: &HtmlFlatData) -> bool {
280 self.is_tag(html_flat_data, "sup")
281 }
282
283 #[inline]
284 fn is_subscript(&self, html_flat_data: &HtmlFlatData) -> bool {
285 self.is_tag(html_flat_data, "sub")
286 }
287
288 #[inline]
289 fn is_strikethrough(&self, html_flat_data: &HtmlFlatData) -> bool {
290 self.is_tag(html_flat_data, "del")
291 }
292}
293
294const COLOR_MAP: &[(&str, &str)] = &[
295 ("aliceblue", "f0f8ff"),
296 ("antiquewhite", "faebd7"),
297 ("antiquewhite1", "ffefdb"),
298 ("antiquewhite2", "eedfcc"),
299 ("antiquewhite3", "cdc0b0"),
300 ("antiquewhite4", "8b8378"),
301 ("aqua", "00ffff"),
302 ("aquamarine1", "7fffd4"),
303 ("aquamarine2", "76eec6"),
304 ("aquamarine4", "458b74"),
305 ("azure1", "f0ffff"),
306 ("azure2", "e0eeee"),
307 ("azure3", "c1cdcd"),
308 ("azure4", "838b8b"),
309 ("beige", "f5f5dc"),
310 ("bisque1", "ffe4c4"),
311 ("bisque2", "eed5b7"),
312 ("bisque3", "cdb79e"),
313 ("bisque4", "8b7d6b"),
314 ("black", "000000"),
315 ("blanchedalmond", "ffebcd"),
316 ("blue", "0000ff"),
317 ("blue1", "0000ff"),
318 ("blue2", "0000ee"),
319 ("blue4", "00008b"),
320 ("blueviolet", "8a2be2"),
321 ("brown", "a52a2a"),
322 ("brown1", "ff4040"),
323 ("brown2", "ee3b3b"),
324 ("brown3", "cd3333"),
325 ("brown4", "8b2323"),
326 ("burlywood", "deb887"),
327 ("burlywood1", "ffd39b"),
328 ("burlywood2", "eec591"),
329 ("burlywood3", "cdaa7d"),
330 ("burlywood4", "8b7355"),
331 ("cadetblue", "5f9ea0"),
332 ("cadetblue1", "98f5ff"),
333 ("cadetblue2", "8ee5ee"),
334 ("cadetblue3", "7ac5cd"),
335 ("cadetblue4", "53868b"),
336 ("chartreuse1", "7fff00"),
337 ("chartreuse2", "76ee00"),
338 ("chartreuse3", "66cd00"),
339 ("chartreuse4", "458b00"),
340 ("chocolate", "d2691e"),
341 ("chocolate1", "ff7f24"),
342 ("chocolate2", "ee7621"),
343 ("chocolate3", "cd661d"),
344 ("coral", "ff7f50"),
345 ("coral1", "ff7256"),
346 ("coral2", "ee6a50"),
347 ("coral3", "cd5b45"),
348 ("coral4", "8b3e2f"),
349 ("cornflowerblue", "6495ed"),
350 ("cornsilk1", "fff8dc"),
351 ("cornsilk2", "eee8cd"),
352 ("cornsilk3", "cdc8b1"),
353 ("cornsilk4", "8b8878"),
354 ("cyan1", "00ffff"),
355 ("cyan2", "00eeee"),
356 ("cyan3", "00cdcd"),
357 ("cyan4", "008b8b"),
358 ("darkgoldenrod", "b8860b"),
359 ("darkgoldenrod1", "ffb90f"),
360 ("darkgoldenrod2", "eead0e"),
361 ("darkgoldenrod3", "cd950c"),
362 ("darkgoldenrod4", "8b6508"),
363 ("darkgreen", "006400"),
364 ("darkkhaki", "bdb76b"),
365 ("darkolivegreen", "556b2f"),
366 ("darkolivegreen1", "caff70"),
367 ("darkolivegreen2", "bcee68"),
368 ("darkolivegreen3", "a2cd5a"),
369 ("darkolivegreen4", "6e8b3d"),
370 ("darkorange", "ff8c00"),
371 ("darkorange1", "ff7f00"),
372 ("darkorange2", "ee7600"),
373 ("darkorange3", "cd6600"),
374 ("darkorange4", "8b4500"),
375 ("darkorchid", "9932cc"),
376 ("darkorchid1", "bf3eff"),
377 ("darkorchid2", "b23aee"),
378 ("darkorchid3", "9a32cd"),
379 ("darkorchid4", "68228b"),
380 ("darksalmon", "e9967a"),
381 ("darkseagreen", "8fbc8f"),
382 ("darkseagreen1", "c1ffc1"),
383 ("darkseagreen2", "b4eeb4"),
384 ("darkseagreen3", "9bcd9b"),
385 ("darkseagreen4", "698b69"),
386 ("darkslateblue", "483d8b"),
387 ("darkslategray", "2f4f4f"),
388 ("darkslategray1", "97ffff"),
389 ("darkslategray2", "8deeee"),
390 ("darkslategray3", "79cdcd"),
391 ("darkslategray4", "528b8b"),
392 ("darkturquoise", "00ced1"),
393 ("darkviolet", "9400d3"),
394 ("deeppink1", "ff1493"),
395 ("deeppink2", "ee1289"),
396 ("deeppink3", "cd1076"),
397 ("deeppink4", "8b0a50"),
398 ("deepskyblue1", "00bfff"),
399 ("deepskyblue2", "00b2ee"),
400 ("deepskyblue3", "009acd"),
401 ("deepskyblue4", "00688b"),
402 ("dimgray", "696969"),
403 ("dodgerblue1", "1e90ff"),
404 ("dodgerblue2", "1c86ee"),
405 ("dodgerblue3", "1874cd"),
406 ("dodgerblue4", "104e8b"),
407 ("firebrick", "b22222"),
408 ("firebrick1", "ff3030"),
409 ("firebrick2", "ee2c2c"),
410 ("firebrick3", "cd2626"),
411 ("firebrick4", "8b1a1a"),
412 ("floralwhite", "fffaf0"),
413 ("forestgreen", "228b22"),
414 ("fuchsia", "ff00ff"),
415 ("gainsboro", "dcdcdc"),
416 ("ghostwhite", "f8f8ff"),
417 ("gold1", "ffd700"),
418 ("gold2", "eec900"),
419 ("gold3", "cdad00"),
420 ("gold4", "8b7500"),
421 ("goldenrod", "daa520"),
422 ("goldenrod1", "ffc125"),
423 ("goldenrod2", "eeb422"),
424 ("goldenrod3", "cd9b1d"),
425 ("goldenrod4", "8b6914"),
426 ("gray", "bebebe"),
427 ("gray1", "030303"),
428 ("gray10", "1a1a1a"),
429 ("gray11", "1c1c1c"),
430 ("gray12", "1f1f1f"),
431 ("gray13", "212121"),
432 ("gray14", "242424"),
433 ("gray15", "262626"),
434 ("gray16", "292929"),
435 ("gray17", "2b2b2b"),
436 ("gray18", "2e2e2e"),
437 ("gray19", "303030"),
438 ("gray2", "050505"),
439 ("gray20", "333333"),
440 ("gray21", "363636"),
441 ("gray22", "383838"),
442 ("gray23", "3b3b3b"),
443 ("gray24", "3d3d3d"),
444 ("gray25", "404040"),
445 ("gray26", "424242"),
446 ("gray27", "454545"),
447 ("gray28", "474747"),
448 ("gray29", "4a4a4a"),
449 ("gray3", "080808"),
450 ("gray30", "4d4d4d"),
451 ("gray31", "4f4f4f"),
452 ("gray32", "525252"),
453 ("gray33", "545454"),
454 ("gray34", "575757"),
455 ("gray35", "595959"),
456 ("gray36", "5c5c5c"),
457 ("gray37", "5e5e5e"),
458 ("gray38", "616161"),
459 ("gray39", "636363"),
460 ("gray4", "0a0a0a"),
461 ("gray40", "666666"),
462 ("gray41", "696969"),
463 ("gray42", "6b6b6b"),
464 ("gray43", "6e6e6e"),
465 ("gray44", "707070"),
466 ("gray45", "737373"),
467 ("gray46", "757575"),
468 ("gray47", "787878"),
469 ("gray48", "7a7a7a"),
470 ("gray49", "7d7d7d"),
471 ("gray5", "0d0d0d"),
472 ("gray50", "7f7f7f"),
473 ("gray51", "828282"),
474 ("gray52", "858585"),
475 ("gray53", "878787"),
476 ("gray54", "8a8a8a"),
477 ("gray55", "8c8c8c"),
478 ("gray56", "8f8f8f"),
479 ("gray57", "919191"),
480 ("gray58", "949494"),
481 ("gray59", "969696"),
482 ("gray6", "0f0f0f"),
483 ("gray60", "999999"),
484 ("gray61", "9c9c9c"),
485 ("gray62", "9e9e9e"),
486 ("gray63", "a1a1a1"),
487 ("gray64", "a3a3a3"),
488 ("gray65", "a6a6a6"),
489 ("gray66", "a8a8a8"),
490 ("gray67", "ababab"),
491 ("gray68", "adadad"),
492 ("gray69", "b0b0b0"),
493 ("gray7", "121212"),
494 ("gray70", "b3b3b3"),
495 ("gray71", "b5b5b5"),
496 ("gray72", "b8b8b8"),
497 ("gray73", "bababa"),
498 ("gray74", "bdbdbd"),
499 ("gray75", "bfbfbf"),
500 ("gray76", "c2c2c2"),
501 ("gray77", "c4c4c4"),
502 ("gray78", "c7c7c7"),
503 ("gray79", "c9c9c9"),
504 ("gray8", "141414"),
505 ("gray80", "cccccc"),
506 ("gray81", "cfcfcf"),
507 ("gray82", "d1d1d1"),
508 ("gray83", "d4d4d4"),
509 ("gray84", "d6d6d6"),
510 ("gray85", "d9d9d9"),
511 ("gray86", "dbdbdb"),
512 ("gray87", "dedede"),
513 ("gray88", "e0e0e0"),
514 ("gray89", "e3e3e3"),
515 ("gray9", "171717"),
516 ("gray90", "e5e5e5"),
517 ("gray91", "e8e8e8"),
518 ("gray92", "ebebeb"),
519 ("gray93", "ededed"),
520 ("gray94", "f0f0f0"),
521 ("gray95", "f2f2f2"),
522 ("gray97", "f7f7f7"),
523 ("gray98", "fafafa"),
524 ("gray99", "fcfcfc"),
525 ("green", "00ff00"),
526 ("green1", "00ff00"),
527 ("green2", "00ee00"),
528 ("green3", "00cd00"),
529 ("green4", "008b00"),
530 ("greenyellow", "adff2f"),
531 ("honeydew1", "f0fff0"),
532 ("honeydew2", "e0eee0"),
533 ("honeydew3", "c1cdc1"),
534 ("honeydew4", "838b83"),
535 ("hotpink", "ff69b4"),
536 ("hotpink1", "ff6eb4"),
537 ("hotpink2", "ee6aa7"),
538 ("hotpink3", "cd6090"),
539 ("hotpink4", "8b3a62"),
540 ("indianred", "cd5c5c"),
541 ("indianred1", "ff6a6a"),
542 ("indianred2", "ee6363"),
543 ("indianred3", "cd5555"),
544 ("indianred4", "8b3a3a"),
545 ("ivory1", "fffff0"),
546 ("ivory2", "eeeee0"),
547 ("ivory3", "cdcdc1"),
548 ("ivory4", "8b8b83"),
549 ("khaki", "f0e68c"),
550 ("khaki1", "fff68f"),
551 ("khaki2", "eee685"),
552 ("khaki3", "cdc673"),
553 ("khaki4", "8b864e"),
554 ("lavender", "e6e6fa"),
555 ("lavenderblush1", "fff0f5"),
556 ("lavenderblush2", "eee0e5"),
557 ("lavenderblush3", "cdc1c5"),
558 ("lavenderblush4", "8b8386"),
559 ("lawngreen", "7cfc00"),
560 ("lemonchiffon1", "fffacd"),
561 ("lemonchiffon2", "eee9bf"),
562 ("lemonchiffon3", "cdc9a5"),
563 ("lemonchiffon4", "8b8970"),
564 ("light", "eedd82"),
565 ("lightblue", "add8e6"),
566 ("lightblue1", "bfefff"),
567 ("lightblue2", "b2dfee"),
568 ("lightblue3", "9ac0cd"),
569 ("lightblue4", "68838b"),
570 ("lightcoral", "f08080"),
571 ("lightcyan1", "e0ffff"),
572 ("lightcyan2", "d1eeee"),
573 ("lightcyan3", "b4cdcd"),
574 ("lightcyan4", "7a8b8b"),
575 ("lightgoldenrod1", "ffec8b"),
576 ("lightgoldenrod2", "eedc82"),
577 ("lightgoldenrod3", "cdbe70"),
578 ("lightgoldenrod4", "8b814c"),
579 ("lightgoldenrodyellow", "fafad2"),
580 ("lightgray", "d3d3d3"),
581 ("lightpink", "ffb6c1"),
582 ("lightpink1", "ffaeb9"),
583 ("lightpink2", "eea2ad"),
584 ("lightpink3", "cd8c95"),
585 ("lightpink4", "8b5f65"),
586 ("lightsalmon1", "ffa07a"),
587 ("lightsalmon2", "ee9572"),
588 ("lightsalmon3", "cd8162"),
589 ("lightsalmon4", "8b5742"),
590 ("lightseagreen", "20b2aa"),
591 ("lightskyblue", "87cefa"),
592 ("lightskyblue1", "b0e2ff"),
593 ("lightskyblue2", "a4d3ee"),
594 ("lightskyblue3", "8db6cd"),
595 ("lightskyblue4", "607b8b"),
596 ("lightslateblue", "8470ff"),
597 ("lightslategray", "778899"),
598 ("lightsteelblue", "b0c4de"),
599 ("lightsteelblue1", "cae1ff"),
600 ("lightsteelblue2", "bcd2ee"),
601 ("lightsteelblue3", "a2b5cd"),
602 ("lightsteelblue4", "6e7b8b"),
603 ("lightyellow1", "ffffe0"),
604 ("lightyellow2", "eeeed1"),
605 ("lightyellow3", "cdcdb4"),
606 ("lightyellow4", "8b8b7a"),
607 ("lime", "00ff00"),
608 ("limegreen", "32cd32"),
609 ("linen", "faf0e6"),
610 ("magenta", "ff00ff"),
611 ("magenta2", "ee00ee"),
612 ("magenta3", "cd00cd"),
613 ("magenta4", "8b008b"),
614 ("maroon", "b03060"),
615 ("maroon1", "ff34b3"),
616 ("maroon2", "ee30a7"),
617 ("maroon3", "cd2990"),
618 ("maroon4", "8b1c62"),
619 ("medium", "66cdaa"),
620 ("mediumaquamarine", "66cdaa"),
621 ("mediumblue", "0000cd"),
622 ("mediumorchid", "ba55d3"),
623 ("mediumorchid1", "e066ff"),
624 ("mediumorchid2", "d15fee"),
625 ("mediumorchid3", "b452cd"),
626 ("mediumorchid4", "7a378b"),
627 ("mediumpurple", "9370db"),
628 ("mediumpurple1", "ab82ff"),
629 ("mediumpurple2", "9f79ee"),
630 ("mediumpurple3", "8968cd"),
631 ("mediumpurple4", "5d478b"),
632 ("mediumseagreen", "3cb371"),
633 ("mediumslateblue", "7b68ee"),
634 ("mediumspringgreen", "00fa9a"),
635 ("mediumturquoise", "48d1cc"),
636 ("mediumvioletred", "c71585"),
637 ("midnightblue", "191970"),
638 ("mintcream", "f5fffa"),
639 ("mistyrose1", "ffe4e1"),
640 ("mistyrose2", "eed5d2"),
641 ("mistyrose3", "cdb7b5"),
642 ("mistyrose4", "8b7d7b"),
643 ("moccasin", "ffe4b5"),
644 ("navajowhite1", "ffdead"),
645 ("navajowhite2", "eecfa1"),
646 ("navajowhite3", "cdb38b"),
647 ("navajowhite4", "8b795e"),
648 ("navy", "000080"),
649 ("navyblue", "000080"),
650 ("oldlace", "fdf5e6"),
651 ("olive", "808000"),
652 ("olivedrab", "6b8e23"),
653 ("olivedrab1", "c0ff3e"),
654 ("olivedrab2", "b3ee3a"),
655 ("olivedrab4", "698b22"),
656 ("orange", "ffa500"),
657 ("orange1", "ffa500"),
658 ("orange2", "ee9a00"),
659 ("orange3", "cd8500"),
660 ("orange4", "8b5a00"),
661 ("orangered1", "ff4500"),
662 ("orangered2", "ee4000"),
663 ("orangered3", "cd3700"),
664 ("orangered4", "8b2500"),
665 ("orchid", "da70d6"),
666 ("orchid1", "ff83fa"),
667 ("orchid2", "ee7ae9"),
668 ("orchid3", "cd69c9"),
669 ("orchid4", "8b4789"),
670 ("pale", "db7093"),
671 ("palegoldenrod", "eee8aa"),
672 ("palegreen", "98fb98"),
673 ("palegreen1", "9aff9a"),
674 ("palegreen2", "90ee90"),
675 ("palegreen3", "7ccd7c"),
676 ("palegreen4", "548b54"),
677 ("paleturquoise", "afeeee"),
678 ("paleturquoise1", "bbffff"),
679 ("paleturquoise2", "aeeeee"),
680 ("paleturquoise3", "96cdcd"),
681 ("paleturquoise4", "668b8b"),
682 ("palevioletred", "db7093"),
683 ("palevioletred1", "ff82ab"),
684 ("palevioletred2", "ee799f"),
685 ("palevioletred3", "cd6889"),
686 ("palevioletred4", "8b475d"),
687 ("papayawhip", "ffefd5"),
688 ("peachpuff1", "ffdab9"),
689 ("peachpuff2", "eecbad"),
690 ("peachpuff3", "cdaf95"),
691 ("peachpuff4", "8b7765"),
692 ("pink", "ffc0cb"),
693 ("pink1", "ffb5c5"),
694 ("pink2", "eea9b8"),
695 ("pink3", "cd919e"),
696 ("pink4", "8b636c"),
697 ("plum", "dda0dd"),
698 ("plum1", "ffbbff"),
699 ("plum2", "eeaeee"),
700 ("plum3", "cd96cd"),
701 ("plum4", "8b668b"),
702 ("powderblue", "b0e0e6"),
703 ("purple", "a020f0"),
704 ("rebeccapurple", "663399"),
705 ("purple1", "9b30ff"),
706 ("purple2", "912cee"),
707 ("purple3", "7d26cd"),
708 ("purple4", "551a8b"),
709 ("red", "ff0000"),
710 ("red1", "ff0000"),
711 ("red2", "ee0000"),
712 ("red3", "cd0000"),
713 ("red4", "8b0000"),
714 ("rosybrown", "bc8f8f"),
715 ("rosybrown1", "ffc1c1"),
716 ("rosybrown2", "eeb4b4"),
717 ("rosybrown3", "cd9b9b"),
718 ("rosybrown4", "8b6969"),
719 ("royalblue", "4169e1"),
720 ("royalblue1", "4876ff"),
721 ("royalblue2", "436eee"),
722 ("royalblue3", "3a5fcd"),
723 ("royalblue4", "27408b"),
724 ("saddlebrown", "8b4513"),
725 ("salmon", "fa8072"),
726 ("salmon1", "ff8c69"),
727 ("salmon2", "ee8262"),
728 ("salmon3", "cd7054"),
729 ("salmon4", "8b4c39"),
730 ("sandybrown", "f4a460"),
731 ("seagreen1", "54ff9f"),
732 ("seagreen2", "4eee94"),
733 ("seagreen3", "43cd80"),
734 ("seagreen4", "2e8b57"),
735 ("seashell1", "fff5ee"),
736 ("seashell2", "eee5de"),
737 ("seashell3", "cdc5bf"),
738 ("seashell4", "8b8682"),
739 ("sienna", "a0522d"),
740 ("sienna1", "ff8247"),
741 ("sienna2", "ee7942"),
742 ("sienna3", "cd6839"),
743 ("sienna4", "8b4726"),
744 ("silver", "c0c0c0"),
745 ("skyblue", "87ceeb"),
746 ("skyblue1", "87ceff"),
747 ("skyblue2", "7ec0ee"),
748 ("skyblue3", "6ca6cd"),
749 ("skyblue4", "4a708b"),
750 ("slateblue", "6a5acd"),
751 ("slateblue1", "836fff"),
752 ("slateblue2", "7a67ee"),
753 ("slateblue3", "6959cd"),
754 ("slateblue4", "473c8b"),
755 ("slategray", "708090"),
756 ("slategray1", "c6e2ff"),
757 ("slategray2", "b9d3ee"),
758 ("slategray3", "9fb6cd"),
759 ("slategray4", "6c7b8b"),
760 ("snow1", "fffafa"),
761 ("snow2", "eee9e9"),
762 ("snow3", "cdc9c9"),
763 ("snow4", "8b8989"),
764 ("springgreen1", "00ff7f"),
765 ("springgreen2", "00ee76"),
766 ("springgreen3", "00cd66"),
767 ("springgreen4", "008b45"),
768 ("steelblue", "4682b4"),
769 ("steelblue1", "63b8ff"),
770 ("steelblue2", "5cacee"),
771 ("steelblue3", "4f94cd"),
772 ("steelblue4", "36648b"),
773 ("tan", "d2b48c"),
774 ("tan1", "ffa54f"),
775 ("tan2", "ee9a49"),
776 ("tan3", "cd853f"),
777 ("tan4", "8b5a2b"),
778 ("teal", "008080"),
779 ("thistle", "d8bfd8"),
780 ("thistle1", "ffe1ff"),
781 ("thistle2", "eed2ee"),
782 ("thistle3", "cdb5cd"),
783 ("thistle4", "8b7b8b"),
784 ("tomato1", "ff6347"),
785 ("tomato2", "ee5c42"),
786 ("tomato3", "cd4f39"),
787 ("tomato4", "8b3626"),
788 ("turquoise", "40e0d0"),
789 ("turquoise1", "00f5ff"),
790 ("turquoise2", "00e5ee"),
791 ("turquoise3", "00c5cd"),
792 ("turquoise4", "00868b"),
793 ("violet", "ee82ee"),
794 ("violetred", "d02090"),
795 ("violetred1", "ff3e96"),
796 ("violetred2", "ee3a8c"),
797 ("violetred3", "cd3278"),
798 ("violetred4", "8b2252"),
799 ("wheat", "f5deb3"),
800 ("wheat1", "ffe7ba"),
801 ("wheat2", "eed8ae"),
802 ("wheat3", "cdba96"),
803 ("wheat4", "8b7e66"),
804 ("white", "ffffff"),
805 ("whitesmoke", "f5f5f5"),
806 ("yellow", "ffff00"),
807 ("yellow1", "ffff00"),
808 ("yellow2", "eeee00"),
809 ("yellow3", "cdcd00"),
810 ("yellow4", "8b8b00"),
811 ("yellowgreen", "9acd32"),
812];
813
814#[test]
815fn convert_test() {
816 let html = r#"<font color="red">test</font><br><font class="test" color="green">TE<b>S</b>T<br/>TEST</font>"#;
817 let result = html_to_richtext(html).unwrap();
818}