rustla/parser/state_machine/
aplus_questionnaire.rs1use super::*;
8
9pub fn parse_aplus_questionnaire_text(
11 src_lines: &Vec<String>,
12 base_indent: usize,
13 section_level: &mut usize,
14 line_cursor: &mut LineCursor,
15 mut doctree: DocTree,
16 captures: ®ex::Captures,
17 pattern_name: &Pattern,
18) -> TransitionResult {
19
20 let detected_indent = captures.get(1).unwrap().as_str().chars().count();
21
22 match Parser::parent_indent_matches(doctree.shared_data(), detected_indent) {
23 IndentationMatch::JustRight => {
24 let start_line = line_cursor.relative_offset();
25 let indent_allowed = true;
26 let remove_indent = true;
27 let alignment = Some(detected_indent);
28 let (block_lines, offset) = if let TextBlockResult::Ok {lines, offset } = Parser::read_text_block(
29 src_lines,
30 start_line,
31 indent_allowed,
32 remove_indent,
33 alignment,
34 true
35 ) {
36 (lines, offset)
37 } else {
38 panic!("Error when reading intermediate text in A+ questionnaire on line {}. Computer says no...", line_cursor.sum_total())
39 };
40
41 let inline_nodes = match Parser::inline_parse(block_lines.join("\n"), None, line_cursor) {
42 InlineParsingResult::Nodes(nodes) => nodes,
43 _ => panic!(
44 "Could not parse intermediate questionnaire text on line {} for inline nodes. Computer says no...",
45 line_cursor.sum_total()
46 )
47 };
48
49 let paragraph = TreeNodeType::Paragraph {
50 indent: detected_indent,
51 };
52 doctree = match doctree.push_data_and_focus(paragraph) {
53 Ok(tree) => tree,
54 Err(tree) => {
55 return TransitionResult::Failure {
56 message: format!(
57 "Node insertion error on line {}. Computer says no...",
58 line_cursor.sum_total()
59 ),
60 doctree: tree,
61 }
62 }
63 };
64 for node in inline_nodes {
65 doctree = match doctree.push_data(node) {
66 Ok(tree) => tree,
67 Err(tree) => {
68 return TransitionResult::Failure {
69 message: format!(
70 "Node insertion error on line {}. Computer says no...",
71 line_cursor.sum_total()
72 ),
73 doctree: tree,
74 }
75 }
76 };
77 }
78 doctree = doctree.focus_on_parent();
79 return TransitionResult::Success {
80 doctree: doctree,
81 push_or_pop: PushOrPop::Neither,
82 line_advance: LineAdvance::Some(1),
83 };
84 }
85 _ => {
86 doctree = doctree.focus_on_parent();
87 return TransitionResult::Success {
88 doctree: doctree,
89 push_or_pop: PushOrPop::Pop,
90 line_advance: LineAdvance::None,
91 };
92 }
93 }
94}
95
96pub fn parse_aplus_questionnaire_directive(
99 src_lines: &Vec<String>,
100 base_indent: usize,
101 section_level: &mut usize,
102 line_cursor: &mut LineCursor,
103 mut doctree: DocTree,
104 captures: ®ex::Captures,
105 pattern_name: &Pattern,
106) -> TransitionResult {
107
108 let detected_marker_indent = captures.get(1).unwrap().as_str().chars().count() + base_indent;
109 let detected_directive_label = captures
110 .get(2)
111 .unwrap()
112 .as_str()
113 .split_whitespace()
114 .collect::<String>()
115 .to_lowercase();
116 let detected_first_indent = captures.get(0).unwrap().as_str().chars().count() + base_indent;
117
118 let empty_after_marker: bool = {
119 let line = src_lines.get(line_cursor.relative_offset()).unwrap(); match line.char_indices().nth(detected_first_indent) {
122 Some((index, _)) => line[index..].trim().is_empty(),
123 None => true,
124 }
125 };
126
127 let (body_indent, body_offset) =
128 match Parser::indent_on_subsequent_lines(src_lines, line_cursor.relative_offset() + 1) {
129 Some((indent, offset)) => (indent + base_indent, offset),
130 None => (detected_first_indent, 0), };
132
133 match Parser::parent_indent_matches(doctree.shared_data(), detected_marker_indent) {
134 IndentationMatch::JustRight => match detected_directive_label.as_str() {
135 "pick-one" => directive_parsers::parse_aplus_pick_one(
136 src_lines,
137 doctree,
138 line_cursor,
139 detected_first_indent,
140 body_indent,
141 empty_after_marker,
142 ),
143 "pick-any" => directive_parsers::parse_aplus_pick_any(
144 src_lines,
145 doctree,
146 line_cursor,
147 detected_first_indent,
148 body_indent,
149 empty_after_marker,
150 ),
151 "freetext" => directive_parsers::parse_aplus_freetext(
152 src_lines,
153 doctree,
154 line_cursor,
155 detected_first_indent,
156 body_indent,
157 empty_after_marker,
158 ),
159 _ => {
160 doctree = doctree.focus_on_parent();
161 return TransitionResult::Success {
162 doctree: doctree,
163 push_or_pop: PushOrPop::Pop,
164 line_advance: LineAdvance::None,
165 };
166 }
167 },
168 _ => {
169 doctree = doctree.focus_on_parent();
170 return TransitionResult::Success {
171 doctree: doctree,
172 push_or_pop: PushOrPop::Pop,
173 line_advance: LineAdvance::None,
174 };
175 }
176 }
177}