rustla/parser/state_machine/
block_quote.rs1use super::*;
8use crate::parser::types_and_aliases::IndentedBlockResult;
9
10pub fn attribution(
13 src_lines: &Vec<String>,
14 base_indent: usize,
15 section_level: &mut usize,
16 line_cursor: &mut LineCursor,
17 mut doctree: DocTree,
18 captures: ®ex::Captures,
19 pattern_name: &Pattern,
20) -> TransitionResult {
21
22 let match_len = captures.get(0).unwrap().as_str().chars().count() + base_indent;
23 let attribution_line_indent = captures.get(1).unwrap().as_str().chars().count() + base_indent;
24
25 match Parser::parent_indent_matches(doctree.shared_data(), attribution_line_indent) {
26 IndentationMatch::JustRight => {
27 let current_line = if let Some(line) = src_lines.get(line_cursor.relative_offset()) {
30 line
31 } else {
32 panic!("Found an attribution marker on line {} but the line doesn't exist? Computer says no...", line_cursor.sum_total())
33 };
34
35 let line_after_marker = Parser::line_suffix(current_line, match_len - base_indent);
36
37 let empty_after_marker = line_after_marker.as_str().trim().is_empty();
38
39 let first_indent = if empty_after_marker {
40 None
41 } else {
42 Some(match_len)
43 };
44
45 let next_indent = if let Some((indent, offset)) =
46 Parser::indent_on_subsequent_lines(src_lines, line_cursor.relative_offset())
47 {
48 if offset == 0 && indent >= attribution_line_indent {
49 Some(indent)
50 } else {
51 Some(match_len)
52 }
53 } else {
54 Some(match_len)
55 };
56
57 let (attribution_string, offset) = if let IndentedBlockResult::Ok {lines, minimum_indent, offset, blank_finish } =
58 Parser::read_indented_block(
59 src_lines,
60 line_cursor.relative_offset(),
61 true,
62 true,
63 next_indent,
64 first_indent,
65 true,
66 ) {
67 (lines.join(" ").trim().to_string(), offset)
68 } else {
69 panic!(
70 "Could not read comment block on line {}...",
71 line_cursor.sum_total()
72 )
73 };
74
75 doctree = match doctree.push_data(
76 TreeNodeType::Attribution {
77 raw_text: attribution_string,
78 }
79 ) {
80 Ok(tree) => tree,
81 Err(tree) => {
82 return TransitionResult::Failure {
83 message: format!(
84 "Node insertion error on line {}. Computer says no...",
85 line_cursor.sum_total()
86 ),
87 doctree: tree,
88 }
89 }
90 };
91 doctree = doctree.focus_on_parent();
92
93 TransitionResult::Success {
94 doctree: doctree,
95 push_or_pop: PushOrPop::Pop,
96 line_advance: LineAdvance::Some(offset),
97 }
98 }
99 IndentationMatch::TooMuch => {
100 doctree = match doctree.push_data_and_focus(
102 TreeNodeType::BlockQuote {
103 body_indent: attribution_line_indent,
104 }
105 ) {
106 Ok(tree) => tree,
107 Err(tree) => {
108 return TransitionResult::Failure {
109 message: format!(
110 "Node insertion error on line {}. Computer says no...",
111 line_cursor.sum_total()
112 ),
113 doctree: tree,
114 }
115 }
116 };
117
118 return TransitionResult::Success {
119 doctree: doctree,
120 push_or_pop: PushOrPop::Push(vec![State::BlockQuote]),
121 line_advance: LineAdvance::None,
122 };
123 }
124 _ => {
125 doctree = doctree.focus_on_parent();
126 TransitionResult::Success {
127 doctree: doctree,
128 push_or_pop: PushOrPop::Pop,
129 line_advance: LineAdvance::None,
130 }
131 }
132 }
133}