Skip to content

Commit ea19bb0

Browse files
committed
split markdown parser into multiple functions
1 parent 6476018 commit ea19bb0

File tree

1 file changed

+74
-60
lines changed

1 file changed

+74
-60
lines changed

src/elements/text.rs

Lines changed: 74 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ fn get_md_value(element: &mut SvgElement) -> (Vec<String>, Vec<u32>) {
2020

2121
let mut state_per_char = vec![0; parsed_string.len()];
2222

23-
for i in 0..sections.len() {
24-
let bit = sections[i].code_bold_italic;
25-
for j in sections[i].start_ind..sections[i].end_ind {
26-
state_per_char[j] |= 1 << bit;
23+
for s in sections {
24+
let bit = s.code_bold_italic;
25+
for i in s.start_ind..s.end_ind {
26+
state_per_char[i] |= 1 << bit;
2727
}
2828
}
2929

@@ -55,14 +55,13 @@ struct SectionData {
5555
struct DelimiterData {
5656
ind: usize, // goes just before this char
5757
char_type: char,
58-
num_delimiters: u32,
58+
num_delimiters: usize,
5959
is_active: bool,
6060
could_open: bool,
6161
could_close: bool,
6262
}
6363

64-
fn md_parse(text_value: &str) -> (Vec<char>, Vec<SectionData>) {
65-
let mut sections = vec![];
64+
fn md_parse_escapes_and_delimiters(text_value: &str) -> (Vec<char>, Vec<DelimiterData>) {
6665
let mut result = vec![];
6766
let mut delimiters = vec![DelimiterData {
6867
ind: 0,
@@ -77,17 +76,16 @@ fn md_parse(text_value: &str) -> (Vec<char>, Vec<SectionData>) {
7776
// first pass process \ and find delimiters
7877
for c in text_value.chars() {
7978
let mut add = true;
80-
if c == '\\' {
81-
if !escaped {
79+
match (c, escaped) {
80+
('\\', false) => {
8281
add = false;
8382
escaped = true;
84-
} else {
85-
escaped = false;
8683
}
87-
}
88-
// the delimiters
89-
else if c == '`' || c == '_' || c == '*' {
90-
if !escaped {
84+
('\\', true) => {
85+
escaped = true;
86+
}
87+
// the delimiters
88+
('`', false) | ('_', false) | ('*', false) => {
9189
let last = delimiters.last_mut().expect("garenteed not to be empty");
9290
if c == last.char_type && last.ind == result.len() {
9391
// is a continuation
@@ -103,25 +101,31 @@ fn md_parse(text_value: &str) -> (Vec<char>, Vec<SectionData>) {
103101
});
104102
}
105103
add = false;
106-
} else {
107-
escaped = true;
108104
}
109-
} else if escaped {
110-
if c == 'n' {
105+
('`', true) | ('_', true) | ('*', true) => {
106+
escaped = false;
107+
}
108+
('n', true) => {
111109
add = false;
112110
result.push('\n');
113-
} else {
111+
escaped = false;
112+
}
113+
(_, true) => {
114114
// was not an escape
115115
result.push('\\');
116+
escaped = false;
116117
}
117-
escaped = false;
118+
(_, false) => {}
118119
}
119-
120120
if add {
121121
result.push(c);
122122
}
123123
}
124124

125+
return (result, delimiters);
126+
}
127+
128+
fn md_parse_set_delimiter_open_close(result: &Vec<char>, delimiters: &mut Vec<DelimiterData>) {
125129
// set could open/close
126130
for i in 0..delimiters.len() {
127131
let prev_char;
@@ -142,18 +146,23 @@ fn md_parse(text_value: &str) -> (Vec<char>, Vec<SectionData>) {
142146
next_char = result[delimiters[i].ind];
143147
}
144148

145-
if next_char.is_whitespace() {
146-
delimiters[i].could_open = false;
147-
}
148-
if prev_char.is_whitespace() {
149-
delimiters[i].could_close = false;
150-
}
151-
if !next_char.is_whitespace()
152-
&& !prev_char.is_whitespace()
153-
&& delimiters[i].char_type == '_'
154-
{
155-
delimiters[i].could_open = false;
156-
delimiters[i].could_close = false;
149+
match (prev_char.is_whitespace(), next_char.is_whitespace()) {
150+
(false, false) => {
151+
if delimiters[i].char_type == '_' {
152+
delimiters[i].could_open = false;
153+
delimiters[i].could_close = false;
154+
}
155+
}
156+
(true, false) => {
157+
delimiters[i].could_close = false;
158+
}
159+
(false, true) => {
160+
delimiters[i].could_open = false;
161+
}
162+
(true, true) => {
163+
delimiters[i].could_open = false;
164+
delimiters[i].could_close = false;
165+
}
157166
}
158167

159168
if next_char.is_ascii_punctuation()
@@ -167,7 +176,10 @@ fn md_parse(text_value: &str) -> (Vec<char>, Vec<SectionData>) {
167176
delimiters[i].could_close = false;
168177
}
169178
}
179+
}
170180

181+
fn md_parse_eval_sections(delimiters: &mut Vec<DelimiterData>) -> Vec<SectionData> {
182+
let mut sections = vec![];
171183
let stack_bottom = 0; // because I have a null element in it
172184
let mut current_position = stack_bottom + 1;
173185
let mut opener_a = [stack_bottom; 3];
@@ -188,11 +200,10 @@ fn md_parse(text_value: &str) -> (Vec<char>, Vec<SectionData>) {
188200
'*' => &mut opener_a,
189201
'_' => &mut opener_d,
190202
'`' => &mut opener_t,
191-
_ => panic!(),
203+
_ => panic!("this cant happen as current_position starts at 0 and all other delimiters are of above types"),
192204
};
193205

194-
let min = opener_min[(delimiters[current_position].num_delimiters % 3) as usize]
195-
.max(stack_bottom);
206+
let min = opener_min[delimiters[current_position].num_delimiters % 3].max(stack_bottom);
196207
let mut opener_ind = current_position - 1;
197208
while opener_ind > min {
198209
// found opener
@@ -214,8 +225,7 @@ fn md_parse(text_value: &str) -> (Vec<char>, Vec<SectionData>) {
214225

215226
if opener_ind == min {
216227
// not found a opener
217-
opener_min[(delimiters[current_position].num_delimiters % 3) as usize] =
218-
current_position - 1;
228+
opener_min[delimiters[current_position].num_delimiters % 3] = current_position - 1;
219229
current_position += 1;
220230
} else {
221231
delimiters[current_position].could_open = false;
@@ -228,17 +238,15 @@ fn md_parse(text_value: &str) -> (Vec<char>, Vec<SectionData>) {
228238
sections.push(SectionData {
229239
start_ind: delimiters[opener_ind].ind,
230240
end_ind: delimiters[current_position].ind,
231-
code_bold_italic: if code {
232-
0
233-
} else if strong {
234-
1
235-
} else {
236-
2
241+
code_bold_italic: match (code, strong) {
242+
(true, _) => 0,
243+
(_, true) => 1,
244+
(_, _) => 2,
237245
},
238246
});
239247

240-
delimiters[opener_ind].num_delimiters -= 1 + (strong as u32);
241-
delimiters[current_position].num_delimiters -= 1 + (strong as u32);
248+
delimiters[opener_ind].num_delimiters -= 1 + (strong as usize);
249+
delimiters[current_position].num_delimiters -= 1 + (strong as usize);
242250

243251
if delimiters[opener_ind].num_delimiters == 0 {
244252
delimiters[opener_ind].is_active = false;
@@ -248,35 +256,41 @@ fn md_parse(text_value: &str) -> (Vec<char>, Vec<SectionData>) {
248256
current_position += 1;
249257
}
250258

251-
for i in (opener_ind + 1)..current_position {
252-
delimiters[i].is_active = false;
259+
for d in &mut delimiters[(opener_ind + 1)..current_position] {
260+
d.is_active = false;
253261
}
254262
}
255263
}
264+
return sections;
265+
}
266+
267+
fn md_parse(text_value: &str) -> (Vec<char>, Vec<SectionData>) {
268+
let (mut result, mut delimiters) = md_parse_escapes_and_delimiters(text_value);
269+
md_parse_set_delimiter_open_close(&result, &mut delimiters);
270+
let mut sections = md_parse_eval_sections(&mut delimiters);
256271

257272
let mut final_result = vec![];
258273

259274
// work from the back to avoid index invalidation
260-
for i in (0..delimiters.len()).rev() {
261-
while delimiters[i].ind < result.len() {
275+
for d in delimiters.into_iter().rev() {
276+
while d.ind < result.len() {
262277
if let Some(thing) = result.pop() {
263278
final_result.push(thing);
264279
}
265280
}
266281

267-
for j in 0..sections.len() {
282+
for s in sections.iter_mut() {
268283
// if start needs to be after or equal
269-
if sections[j].start_ind >= delimiters[i].ind {
270-
sections[j].start_ind += delimiters[i].num_delimiters as usize;
284+
if s.start_ind >= d.ind {
285+
s.start_ind += d.num_delimiters as usize;
271286
}
272-
if sections[j].end_ind > delimiters[i].ind {
287+
if s.end_ind > d.ind {
273288
// if end needs to be after
274-
sections[j].end_ind += delimiters[i].num_delimiters as usize;
289+
s.end_ind += d.num_delimiters as usize;
275290
}
276291
}
277-
for _ in 0..delimiters[i].num_delimiters {
278-
final_result.push(delimiters[i].char_type);
279-
}
292+
let mut temp = vec![d.char_type; d.num_delimiters];
293+
final_result.append(&mut temp);
280294
}
281295

282296
return (final_result.into_iter().rev().collect(), sections);
@@ -571,7 +585,7 @@ pub fn process_text_attr(element: &SvgElement) -> Result<(SvgElement, Vec<SvgEle
571585
}
572586
}
573587

574-
if !multielement{
588+
if !multielement {
575589
if line_types[0][0] & (1 << 0) != 0 {
576590
text_classes.push("d-text-monospace".to_string());
577591
}

0 commit comments

Comments
 (0)