Markdown_to_HTML_rs/
lib.rs1extern crate regex;
2#[macro_use] extern crate lazy_static;
3
4use regex::{RegexBuilder, Regex, Captures};
5
6fn reg(s: &str) -> Regex {
7 RegexBuilder::new(s)
8 .multi_line(true)
9 .build()
10 .unwrap()
11}
12
13lazy_static!{
15 static ref CODE_BLOCK: Regex = reg(r"```(\s*)([\s\S]*?)(\s*)```");
16
17 static ref CODE_INLINE: Regex = reg(r"(`)(.*?)(`)");
18
19 static ref LINK: Regex = reg(r"\[([^\[]+)\]\(([^\)]+)\)");
20
21 static ref HEADING: Regex = reg(r"\n(#+\s*)(.*)");
22
23 static ref EMPHASIS: Regex = reg(r"(\*{1,2})(.*?)(\*{1,2})");
24
25 static ref STRIKETHROUGH: Regex = reg(r"(\~\~)(.*?)(\~\~)");
26
27 static ref HORIZONTAL: Regex = reg(r"\n((\-{3,})|(={3,}))");
28
29 static ref UNORDERED: Regex = reg(r"(\n\s*(\-|\+)\s.*)+");
30
31 static ref ORDERED: Regex = reg(r"(\n\s*([0-9]+\.)\s.*)+");
32
33 static ref LT: Regex = reg(r"<");
35
36 static ref GT: Regex = reg(r">");
37
38 static ref AMP: Regex = reg(r"&");
39
40 static ref AST: Regex = reg(r"\*");
41
42 static ref UND: Regex = reg(r"_");
43
44 static ref TIC: Regex = reg(r"`");
45
46 static ref EQL: Regex = reg(r"=");
47
48 static ref HYP: Regex = reg(r"-");
49
50 static ref HASH: Regex = reg(r"#");
51}
52
53fn symbols(s: &str) -> String {
55 HYP.replace_all(&EQL.replace_all(&TIC.replace_all(&UND.replace_all(&AST.replace_all(<.replace_all(>.replace_all(&HASH.replace_all(&.replace_all(s, "&"), "#"), ">"), "<"), "*"), "_"), "`"), "="), "-").to_string()
56}
57
58fn code_block_replacer(cap: &Captures) -> String {
61 format!("<pre>{}</pre>", symbols(&cap[2]))
62}
63
64fn code_inline_replacer(cap: &Captures) -> String {
65 format!("<code>{}</code>", &cap[2])
66}
67
68fn link_replacer(cap: &Captures) -> String {
69 format!("<a href='{}'>{}</a>", &cap[2], &cap[1])
70}
71
72fn heading_replacer(cap: &Captures) -> String {
73 format!("\n<h{}>{}</h{}>", cap[1].len().to_string(), &cap[2], cap[1].len().to_string())
74}
75
76fn emphasis_replacer(cap: &Captures) -> String {
77 format!("<{}>{}</{}>", if{cap[1].len()==1}{"em"}else{"strong"}, &cap[2], if{cap[1].len()==1}{"em"}else{"strong"})
78}
79
80fn rule_replacer(cap: &Captures) -> String {
81 format!("\n<hr />")
82}
83
84fn unordered_replacer(cap: &Captures) -> String {
85 let mut items = String::from("");
86 for i in cap[0].trim().split('\n') {
87 items = format!("{}<li>{}</li>", items, &i[2..]);
88 }
89 format!("<ul>{}</ul>", items)
90}
91
92fn ordered_replacer(cap: &Captures) -> String {
93 let mut items = String::from("");
94 for i in cap[0].trim().split('\n') {
95 items = format!("{}<li>{}</li>", items, &i[i.find('.').unwrap()+2..]);
96 }
97 format!("<ol>{}</ol>", items)
98}
99
100pub fn replace_all(s: &String) -> String {
102 replace::unordered(&replace::ordered(&replace::rules(&replace::emphasis(&replace::headings(&replace::links(&replace::code_inline(&replace::code_blocks(s))))))))
103}
104
105pub mod replace {
107 use crate::*;
108
109 pub fn code_blocks(s: &String) -> String {
110 CODE_BLOCK.replace_all(s, &code_block_replacer).to_string()
111 }
112
113 pub fn code_inline(s: &String) -> String {
114 CODE_INLINE.replace_all(s, &code_inline_replacer).to_string()
115 }
116
117 pub fn links(s: &String) -> String {
118 LINK.replace_all(s, &link_replacer).to_string()
119 }
120
121 pub fn headings(s: &String) -> String {
122 HEADING.replace_all(s, &heading_replacer).to_string()
123 }
124
125 pub fn emphasis(s: &String) -> String {
126 EMPHASIS.replace_all(s, &emphasis_replacer).to_string()
127 }
128
129 pub fn rules(s: &String) -> String {
130 HORIZONTAL.replace_all(s, &rule_replacer).to_string()
131 }
132
133 pub fn unordered(s: &String) -> String {
134 UNORDERED.replace_all(s, &unordered_replacer).to_string()
135 }
136
137 pub fn ordered(s: &String) -> String {
138 ORDERED.replace_all(s, &ordered_replacer).to_string()
139 }
140}