oak_markdown/lexer/
list.rs1use crate::lexer::{MarkdownLexer, State, token_type::MarkdownTokenType};
2use oak_core::Source;
3
4impl<'config> MarkdownLexer<'config> {
5 pub fn lex_list_marker<S: Source + ?Sized>(&self, state: &mut State<S>) -> bool {
7 let start_pos = state.get_position();
8
9 let mut check_pos = start_pos;
10 while check_pos > 0 {
11 check_pos -= 1;
12 if let Some(ch) = state.source().get_char_at(check_pos) {
13 if ch == '\n' || ch == '\r' {
14 break;
15 }
16 else if ch != ' ' && ch != '\t' {
17 return false;
18 }
19 }
20 }
21
22 if let Some(ch) = state.peek() {
23 match ch {
24 '-' | '*' | '+' => {
25 state.advance(1);
26 if let Some(next_ch) = state.peek() {
27 if next_ch == ' ' || next_ch == '\t' {
28 state.add_token(MarkdownTokenType::ListMarker, start_pos, state.get_position());
29 return true;
30 }
31 }
32 state.set_position(start_pos);
33 false
34 }
35 '0'..='9' => {
36 while let Some(digit) = state.peek() {
37 if digit.is_ascii_digit() { state.advance(1) } else { break }
38 }
39
40 if let Some('.') = state.peek() {
41 state.advance(1);
42 if let Some(next_ch) = state.peek() {
43 if next_ch == ' ' || next_ch == '\t' {
44 state.add_token(MarkdownTokenType::ListMarker, start_pos, state.get_position());
45 return true;
46 }
47 }
48 }
49
50 state.set_position(start_pos);
51 false
52 }
53 _ => false,
54 }
55 }
56 else {
57 false
58 }
59 }
60
61 pub fn lex_task_marker<S: Source + ?Sized>(&self, state: &mut State<S>) -> bool {
63 let start_pos = state.get_position();
64
65 if let Some('[') = state.peek() {
66 state.advance(1);
67 if let Some(ch) = state.peek() {
68 if ch == ' ' || ch == 'x' || ch == 'X' {
69 state.advance(1);
70 if let Some(']') = state.peek() {
71 state.advance(1);
72 state.add_token(MarkdownTokenType::TaskMarker, start_pos, state.get_position());
73 return true;
74 }
75 }
76 }
77 state.set_position(start_pos);
78 }
79 false
80 }
81
82 pub fn lex_definition_description<S: Source + ?Sized>(&self, state: &mut State<S>) -> bool {
84 let start_pos = state.get_position();
85
86 let mut check_pos = start_pos;
87 while check_pos > 0 {
88 check_pos -= 1;
89 if let Some(ch) = state.source().get_char_at(check_pos) {
90 if ch == '\n' || ch == '\r' {
91 break;
92 }
93 else if ch != ' ' && ch != '\t' {
94 return false;
95 }
96 }
97 }
98
99 if let Some(':') = state.peek() {
100 state.advance(1);
101 if let Some(next_ch) = state.peek() {
102 if next_ch == ' ' || next_ch == '\t' {
103 state.add_token(MarkdownTokenType::DefinitionDescription, start_pos, state.get_position());
104 return true;
105 }
106 }
107 state.set_position(start_pos);
108 false
109 }
110 else {
111 false
112 }
113 }
114
115 pub fn lex_abbreviation<S: Source + ?Sized>(&self, state: &mut State<S>) -> bool {
117 let start_pos = state.get_position();
118
119 let mut check_pos = start_pos;
120 while check_pos > 0 {
121 check_pos -= 1;
122 if let Some(ch) = state.source().get_char_at(check_pos) {
123 if ch == '\n' || ch == '\r' {
124 break;
125 }
126 else if ch != ' ' && ch != '\t' {
127 return false;
128 }
129 }
130 }
131
132 if let Some('*') = state.peek() {
133 state.advance(1);
134 if let Some('[') = state.peek() {
135 state.advance(1);
136
137 while let Some(ch) = state.peek() {
138 if ch == ']' {
139 state.advance(1);
140 if let Some(':') = state.peek() {
141 state.advance(1);
142 state.add_token(MarkdownTokenType::Abbreviation, start_pos, state.get_position());
143 return true;
144 }
145 break;
146 }
147 state.advance(ch.len_utf8());
148 }
149 }
150 state.set_position(start_pos);
151 }
152 false
153 }
154}