use crate::cursor::{LineCursor, indent_len};
use crate::syntax::{Parsed, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken};
use crate::text::TextRange;
fn build_content_range(cursor: &LineCursor, first: Option<usize>, last: usize) -> Option<TextRange> {
first.map(|f| {
let first_line = cursor.line_text(f);
let first_col = indent_len(first_line);
let last_line = cursor.line_text(last);
let last_col = indent_len(last_line) + last_line.trim().len();
cursor.make_range(f, first_col, last, last_col)
})
}
pub fn parse_plain(input: &str) -> Parsed {
let mut line_cursor = LineCursor::new(input);
let mut root_children: Vec<SyntaxElement> = Vec::new();
line_cursor.skip_blanks();
if line_cursor.is_eof() {
let root = SyntaxNode::new(SyntaxKind::PLAIN_DOCSTRING, line_cursor.full_range(), root_children);
return Parsed::new(input.to_string(), root);
}
let mut summary_done = false;
let mut summary_first: Option<usize> = None;
let mut summary_last: usize = 0;
let mut ext_first: Option<usize> = None;
let mut ext_last: usize = 0;
while !line_cursor.is_eof() {
if line_cursor.current_trimmed().is_empty() {
if !summary_done && summary_first.is_some() {
root_children.push(SyntaxElement::Token(SyntaxToken::new(
SyntaxKind::SUMMARY,
build_content_range(&line_cursor, summary_first, summary_last).unwrap(),
)));
summary_done = true;
}
line_cursor.advance();
continue;
}
if !summary_done {
if summary_first.is_none() {
summary_first = Some(line_cursor.line);
}
summary_last = line_cursor.line;
} else {
if ext_first.is_none() {
ext_first = Some(line_cursor.line);
}
ext_last = line_cursor.line;
}
line_cursor.advance();
}
if !summary_done && summary_first.is_some() {
root_children.push(SyntaxElement::Token(SyntaxToken::new(
SyntaxKind::SUMMARY,
build_content_range(&line_cursor, summary_first, summary_last).unwrap(),
)));
}
if ext_first.is_some() {
root_children.push(SyntaxElement::Token(SyntaxToken::new(
SyntaxKind::EXTENDED_SUMMARY,
build_content_range(&line_cursor, ext_first, ext_last).unwrap(),
)));
}
let root = SyntaxNode::new(SyntaxKind::PLAIN_DOCSTRING, line_cursor.full_range(), root_children);
Parsed::new(input.to_string(), root)
}