panache_parser/parser/blocks/
blockquotes.rs1use crate::syntax::SyntaxKind;
6use rowan::GreenNodeBuilder;
7
8use crate::parser::utils::container_stack::{Container, ContainerStack};
9
10pub(crate) use crate::parser::utils::marker_utils::{
11 count_blockquote_markers, try_parse_blockquote_marker,
12};
13
14pub(in crate::parser) fn can_start_blockquote(
22 pos: usize,
23 lines: &[&str],
24 fenced_divs_enabled: bool,
25) -> bool {
26 if pos == 0 {
28 return true;
29 }
30 if crate::parser::utils::helpers::is_blank_line(lines[pos - 1]) {
32 return true;
33 }
34 if fenced_divs_enabled
37 && crate::parser::blocks::fenced_divs::try_parse_div_fence_open(lines[pos - 1]).is_some()
38 {
39 return true;
40 }
41 false
44}
45
46pub(in crate::parser) fn current_blockquote_depth(containers: &ContainerStack) -> usize {
48 containers
49 .stack
50 .iter()
51 .filter(|c| matches!(c, Container::BlockQuote { .. }))
52 .count()
53}
54
55pub(in crate::parser) fn strip_n_blockquote_markers(line: &str, n: usize) -> &str {
57 let mut remaining = line;
58 for _ in 0..n {
59 if let Some((_, content_start)) = try_parse_blockquote_marker(remaining) {
60 remaining = &remaining[content_start..];
61 } else {
62 break;
63 }
64 }
65 remaining
66}
67
68pub(in crate::parser) fn emit_one_blockquote_marker(
70 builder: &mut GreenNodeBuilder<'static>,
71 leading_spaces: usize,
72 has_trailing_space: bool,
73) {
74 if leading_spaces > 0 {
75 builder.token(SyntaxKind::WHITESPACE.into(), &" ".repeat(leading_spaces));
76 }
77 builder.token(SyntaxKind::BLOCK_QUOTE_MARKER.into(), ">");
78 if has_trailing_space {
79 builder.token(SyntaxKind::WHITESPACE.into(), " ");
80 }
81}