1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use std::fmt::Write;
use tl::*;
pub fn html2maud(html: &str) -> String {
let mut maud_template = String::new();
let dom = tl::parse(html, tl::ParserOptions::default()).unwrap();
let parser = dom.parser();
fn spaces(count: usize) -> String {
return "\t".repeat(count).as_str().to_owned();
}
fn handle_tag(tag: &HTMLTag, parser: &Parser, maud_template: &mut String, indent: usize) {
let tag_name = tag.name().as_utf8_str();
write!(maud_template, "{}{}", spaces(indent), &tag_name).unwrap();
let id = tag.attributes().id().map(|x| x.as_utf8_str());
match &id {
Option::Some(x) => {
let escaped_id = if x.contains("-") {
format!("\"{}\"", &x)
} else {
x.to_string()
};
write!(maud_template, " #{}", &escaped_id).unwrap();
},
Option::None => {},
}
match tag.attributes().class_iter() {
None => {},
Some(classes) => {
for class in classes {
let escaped_class = if class.contains("-") {
format!("\"{}\"", &class)
} else {
class.to_owned()
};
write!(maud_template, ".{}", &escaped_class).unwrap();
}
}
}
for (key, value_opt) in tag.attributes().iter() {
if !(key.eq("id") || key.eq("class")) {
write!(maud_template, " {}", key).unwrap();
match value_opt {
None => {},
Some(value) => write!(maud_template, "\"{}\"", value).unwrap(),
}
}
}
write!(maud_template, " {{\n").unwrap();
let children = tag.children();
let nodes = children.top().as_slice();
for child_node in nodes {
handle_node(child_node.get(parser), parser, maud_template, indent + 1);
write!(maud_template, "\n").unwrap();
}
write!(maud_template, "{}}}", spaces(indent)).unwrap();
}
fn handle_node(node_opt: Option<&Node>, parser: &Parser, maud_template: &mut String, indent: usize) {
match node_opt {
None => {},
Some(node) => {
match node {
Node::Tag(tag) => handle_tag(tag, parser, maud_template, indent),
Node::Comment(_) => {},
Node::Raw(raw) => {
let text = raw.as_utf8_str();
let trimmed_text = text.trim();
if !trimmed_text.is_empty() {
write!(maud_template, "{}\"{}\"", spaces(indent), trimmed_text.replace("\"","\\\"")).unwrap();
}
}
}
}
}
}
for node_handle in dom.children() {
handle_node(node_handle.get(parser), parser, &mut maud_template, 0);
}
maud_template
}