From 07970d27453906b36c08e4c27ab0d49ca889af0e Mon Sep 17 00:00:00 2001 From: ef3d0c3e Date: Sun, 25 Aug 2024 13:19:24 +0200 Subject: [PATCH] Fixed blockquote --- src/compiler/navigation.rs | 2 + src/elements/blockquote.rs | 250 +++++++++++++++++++------------------ 2 files changed, 132 insertions(+), 120 deletions(-) diff --git a/src/compiler/navigation.rs b/src/compiler/navigation.rs index 69f316d..4818f0b 100644 --- a/src/compiler/navigation.rs +++ b/src/compiler/navigation.rs @@ -103,6 +103,8 @@ impl NavEntries { std::cmp::Ordering::Greater } else if rp.as_str() == left_title { std::cmp::Ordering::Less + } else if rp.as_str() == lp.as_str() { + left_title.cmp(right_title) } else { Self::sort_entry(entrymap, lp.as_str(), rp.as_str()) } diff --git a/src/elements/blockquote.rs b/src/elements/blockquote.rs index 3e65f92..48fd5c6 100644 --- a/src/elements/blockquote.rs +++ b/src/elements/blockquote.rs @@ -76,7 +76,12 @@ impl Element for Blockquote { fn element_name(&self) -> &'static str { "Blockquote" } - fn compile(&self, compiler: &Compiler, document: &dyn Document, cursor: usize) -> Result { + fn compile( + &self, + compiler: &Compiler, + document: &dyn Document, + cursor: usize, + ) -> Result { match compiler.target() { HTML => { let mut result = r#"
"#.to_string(); @@ -124,7 +129,9 @@ impl Element for Blockquote { result += "

"; for elem in &self.content { - result += elem.compile(compiler, document, cursor+result.len())?.as_str(); + result += elem + .compile(compiler, document, cursor + result.len())? + .as_str(); } result += "

"; if self.style.author_pos == After { @@ -215,7 +222,8 @@ impl Rule for BlockquoteRule { fn next_match(&self, _state: &ParserState, cursor: &Cursor) -> Option<(usize, Box)> { self.start_re - .find_at(cursor.source.content(), cursor.pos).map(|m| (m.start(), Box::new([false; 0]) as Box)) + .find_at(cursor.source.content(), cursor.pos) + .map(|m| (m.start(), Box::new([false; 0]) as Box)) } fn on_match<'a>( @@ -229,134 +237,130 @@ impl Rule for BlockquoteRule { let content = cursor.source.content(); let mut end_cursor = cursor.clone(); - loop { - if let Some(captures) = self.start_re.captures_at(content, end_cursor.pos) { + if let Some(captures) = self.start_re.captures_at(content, end_cursor.pos) { + if captures.get(0).unwrap().start() != end_cursor.pos { + return (end_cursor, reports); + } + // Advance cursor + end_cursor = end_cursor.at(captures.get(0).unwrap().end()); + + // Properties + let mut author = None; + let mut cite = None; + let mut url = None; + if let Some(properties) = captures.get(1) { + match self.parse_properties(properties) { + Err(err) => { + reports.push( + Report::build( + ReportKind::Warning, + cursor.source.clone(), + properties.start(), + ) + .with_message("Invalid Blockquote Properties") + .with_label( + Label::new((cursor.source.clone(), properties.range())) + .with_message(err) + .with_color(state.parser.colors().warning), + ) + .finish(), + ); + return (end_cursor, reports); + } + Ok(props) => (author, cite, url) = props, + } + } + + // Content + let entry_start = captures.get(0).unwrap().start(); + let mut entry_content = captures.get(2).unwrap().as_str().to_string(); + let mut spacing: Option<(Range, &str)> = None; + while let Some(captures) = self.continue_re.captures_at(content, end_cursor.pos) { if captures.get(0).unwrap().start() != end_cursor.pos { break; } // Advance cursor end_cursor = end_cursor.at(captures.get(0).unwrap().end()); - // Properties - let mut author = None; - let mut cite = None; - let mut url = None; - if let Some(properties) = captures.get(1) { - match self.parse_properties(properties) { - Err(err) => { - reports.push( - Report::build( - ReportKind::Warning, - cursor.source.clone(), - properties.start(), - ) - .with_message("Invalid Blockquote Properties") - .with_label( - Label::new((cursor.source.clone(), properties.range())) - .with_message(err) - .with_color(state.parser.colors().warning), - ) - .finish(), - ); - break; - } - Ok(props) => (author, cite, url) = props, - } - } - - // Content - let entry_start = captures.get(0).unwrap().start(); - let mut entry_content = captures.get(2).unwrap().as_str().to_string(); - let mut spacing: Option<(Range, &str)> = None; - while let Some(captures) = self.continue_re.captures_at(content, end_cursor.pos) { - // Advance cursor - end_cursor = end_cursor.at(captures.get(0).unwrap().end()); - - // Spacing - let current_spacing = captures.get(1).unwrap().as_str(); - if let Some(spacing) = &spacing { - if spacing.1 != current_spacing { - reports.push( - Report::build( - ReportKind::Warning, - cursor.source.clone(), - captures.get(1).unwrap().start(), - ) - .with_message("Invalid Blockquote Spacing") - .with_label( - Label::new(( - cursor.source.clone(), - captures.get(1).unwrap().range(), - )) - .with_message("Spacing for blockquote entries do not match") - .with_color(state.parser.colors().warning), - ) - .with_label( - Label::new((cursor.source.clone(), spacing.0.clone())) - .with_message("Previous spacing") - .with_color(state.parser.colors().warning), - ) - .finish(), - ); - } - } else { - spacing = Some((captures.get(1).unwrap().range(), current_spacing)); - } - - entry_content += " "; - entry_content += captures.get(2).unwrap().as_str(); - } - - // Parse entry content - let token = Token::new(entry_start..end_cursor.pos, end_cursor.source.clone()); - let entry_src = Rc::new(VirtualSource::new( - token.clone(), - "Blockquote Entry".to_string(), - entry_content, - )); - let parsed_content = match parse_paragraph(state, entry_src, document) { - Err(err) => { + // Spacing + let current_spacing = captures.get(1).unwrap().as_str(); + if let Some(spacing) = &spacing { + if spacing.1 != current_spacing { reports.push( - Report::build(ReportKind::Warning, token.source(), token.range.start) - .with_message("Unable to Parse Blockquote Entry") - .with_label( - Label::new((token.source(), token.range.clone())) - .with_message(err) - .with_color(state.parser.colors().warning), - ) - .finish(), + Report::build( + ReportKind::Warning, + cursor.source.clone(), + captures.get(1).unwrap().start(), + ) + .with_message("Invalid Blockquote Spacing") + .with_label( + Label::new(( + cursor.source.clone(), + captures.get(1).unwrap().range(), + )) + .with_message("Spacing for blockquote entries do not match") + .with_color(state.parser.colors().warning), + ) + .with_label( + Label::new((cursor.source.clone(), spacing.0.clone())) + .with_message("Previous spacing") + .with_color(state.parser.colors().warning), + ) + .finish(), ); - break; } - Ok(mut paragraph) => std::mem::take(&mut paragraph.content), - }; + } else { + spacing = Some((captures.get(1).unwrap().range(), current_spacing)); + } - // Get style - let style = state - .shared - .styles - .borrow() - .current(blockquote_style::STYLE_KEY) - .downcast_rc::() - .unwrap(); - - state.push( - document, - Box::new(Blockquote { - location: Token::new( - entry_start..end_cursor.pos, - end_cursor.source.clone(), - ), - content: parsed_content, - author, - cite, - url, - style, - }), - ); - } else { - break; + entry_content += " "; + entry_content += captures.get(2).unwrap().as_str(); } + + // Parse entry content + let token = Token::new(entry_start..end_cursor.pos, end_cursor.source.clone()); + let entry_src = Rc::new(VirtualSource::new( + token.clone(), + "Blockquote Entry".to_string(), + entry_content, + )); + let parsed_content = match parse_paragraph(state, entry_src, document) { + Err(err) => { + reports.push( + Report::build(ReportKind::Warning, token.source(), token.range.start) + .with_message("Unable to Parse Blockquote Entry") + .with_label( + Label::new((token.source(), token.range.clone())) + .with_message(err) + .with_color(state.parser.colors().warning), + ) + .finish(), + ); + return (end_cursor, reports); + } + Ok(mut paragraph) => std::mem::take(&mut paragraph.content), + }; + + // Get style + let style = state + .shared + .styles + .borrow() + .current(blockquote_style::STYLE_KEY) + .downcast_rc::() + .unwrap(); + + state.push( + document, + Box::new(Blockquote { + location: Token::new(entry_start..end_cursor.pos, end_cursor.source.clone()), + content: parsed_content, + author, + cite, + url, + style, + }), + ); } (end_cursor, reports) @@ -426,6 +430,8 @@ BEFORE > contin**ued here > ** AFTER +> Another quote +END "# .to_string(), None, @@ -446,6 +452,10 @@ AFTER Style; }; Paragraph { Text{ content == "AFTER" }; }; + Blockquote { + Text { content == "Another quote" }; + }; + Paragraph { Text{ content == "END" }; }; ); }