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