| 30 | } |
| 31 | |
| 32 | pub fn parse_text_lines(lines: Vec<String>) -> Result<Vec<Vec<StyledSegment>>, String> { |
| 33 | let mut result_lines: Vec<Vec<StyledSegment>> = Vec::new(); |
| 34 | let mut style_stack: Vec<String> = Vec::new(); |
| 35 | |
| 36 | let mut in_style_def = false; |
| 37 | let mut escaped = false; |
| 38 | |
| 39 | let mut text_buffer = String::new(); |
| 40 | let mut style_buffer = String::new(); |
| 41 | |
| 42 | for line in lines { |
| 43 | let mut line_segments: Vec<StyledSegment> = Vec::new(); |
| 44 | |
| 45 | for c in line.chars() { |
| 46 | if escaped { |
| 47 | if in_style_def { |
| 48 | style_buffer.push(c); |
| 49 | } else { |
| 50 | text_buffer.push(c); |
| 51 | } |
| 52 | escaped = false; |
| 53 | continue; |
| 54 | } |
| 55 | |
| 56 | match c { |
| 57 | '\\' => { |
| 58 | escaped = true; |
| 59 | } |
| 60 | '{' => { |
| 61 | if in_style_def { |
| 62 | style_buffer.push(c); |
| 63 | } else { |
| 64 | if !text_buffer.is_empty() { |
| 65 | line_segments.push(StyledSegment { |
| 66 | text: text_buffer.clone(), |
| 67 | styles: style_stack.clone(), |
| 68 | }); |
| 69 | text_buffer.clear(); |
| 70 | } |
| 71 | in_style_def = true; |
| 72 | } |
| 73 | } |
| 74 | '|' => { |
| 75 | if in_style_def { |
| 76 | style_stack.push(style_buffer.clone()); |
| 77 | style_buffer.clear(); |
| 78 | in_style_def = false; |
| 79 | } else { |
| 80 | text_buffer.push(c); |
| 81 | } |
| 82 | } |
| 83 | '}' => { |
| 84 | if in_style_def { |
| 85 | style_buffer.push(c); |
| 86 | } else { |
| 87 | if !text_buffer.is_empty() { |
| 88 | line_segments.push(StyledSegment { |
| 89 | text: text_buffer.clone(), |