From d1ce3f112859f5d5cc7d26ff7c6453463fdce4ce Mon Sep 17 00:00:00 2001 From: David Sherret Date: Fri, 16 Aug 2024 15:42:56 -0400 Subject: [PATCH] fix: support block quote callouts (#115) --- src/generation/gen_types.rs | 4 ++++ src/generation/generate.rs | 36 +++++++++++++++++++++------- tests/specs/BlockQuotes/Callouts.txt | 24 +++++++++++++++++++ 3 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 tests/specs/BlockQuotes/Callouts.txt diff --git a/src/generation/gen_types.rs b/src/generation/gen_types.rs index 4a29896..7204d4f 100644 --- a/src/generation/gen_types.rs +++ b/src/generation/gen_types.rs @@ -108,6 +108,10 @@ impl<'a> Context<'a> { self.is_in_list_count > 0 } + pub fn is_in_block_quote(&self) -> bool { + self.is_in_block_quote_count > 0 + } + pub fn with_no_text_wrap(&mut self, func: impl FnOnce(&mut Context) -> T) -> T { self.text_wrap_disabled_count += 1; let items = func(self); diff --git a/src/generation/generate.rs b/src/generation/generate.rs index 508aca5..2df01f2 100644 --- a/src/generation/generate.rs +++ b/src/generation/generate.rs @@ -1,7 +1,3 @@ -use super::common::*; -use super::gen_types::*; -use super::utils; -use crate::configuration::*; use dprint_core::formatting::condition_resolvers; use dprint_core::formatting::conditions::*; use dprint_core::formatting::ir_helpers::*; @@ -11,6 +7,11 @@ use std::borrow::Cow; use std::rc::Rc; use unicode_width::UnicodeWidthStr; +use super::common::*; +use super::gen_types::*; +use super::utils; +use crate::configuration::*; + pub fn generate(node: &Node, context: &mut Context) -> PrintItems { // eprintln!("Kind: {:?}", node.kind()); // eprintln!("Text: {:?}", node.text(context)); @@ -38,7 +39,6 @@ pub fn generate(node: &Node, context: &mut Context) -> PrintItems { Node::List(node) => gen_list(node, false, context), Node::Item(node) => gen_item(node, context), Node::TaskListMarker(_) => unreachable!("this should be handled by gen_paragraph"), - Node::TaskListMarker(_) => unreachable!("this should be handled by gen_paragraph"), Node::HorizontalRule(node) => gen_horizontal_rule(node, context), Node::SoftBreak(_) => PrintItems::new(), Node::HardBreak(_) => gen_hard_break(context), @@ -75,9 +75,7 @@ fn gen_nodes(nodes: &[Node], context: &mut Context) -> PrintItems { let mut last_node: Option<&Node> = None; let mut node_iterator = nodes.iter().filter(|n| !matches!(n, Node::SoftBreak(_))); - while let Some(node) = node_iterator.next() { - let mut node = node; - + while let Some(mut node) = node_iterator.next() { // handle alternate lists if let Some(Node::List(last_list)) = &last_node { if let Node::List(list) = &node { @@ -136,7 +134,21 @@ fn gen_nodes(nodes: &[Node], context: &mut Context) -> PrintItems { let new_line_count = context.get_new_lines_in_range(between_range.0, between_range.1); if new_line_count == 1 { - if matches!(node, Node::Html(_)) { + // Callout example: + // > [!NOTE] + // > Some note. + let is_callout = if context.is_in_block_quote() && matches!(node, Node::Text(_)) { + if let Node::Text(text) = last_node { + is_callout_text(&text.text) + } else { + false + } + } else { + false + }; + if is_callout && !context.is_text_wrap_disabled() { + items.push_signal(Signal::NewLine); // force a newline + } else if matches!(node, Node::Html(_)) { items.push_signal(Signal::NewLine); } else { items.extend(get_newline_wrapping_based_on_config(context)); @@ -163,6 +175,7 @@ fn gen_nodes(nodes: &[Node], context: &mut Context) -> PrintItems { if node.starts_with_list_word() { items.push_space(); } else { + if matches!(last_node, Node::Text(_)) && matches!(node, Node::Text(_)) {} items.extend(get_space_or_newline_based_on_config(context)); } } @@ -423,6 +436,11 @@ fn gen_text(text: &Text, context: &mut Context) -> PrintItems { gen_str(&text.text, context) } +fn is_callout_text(text: &str) -> bool { + // ex. [!NOTE] + text.starts_with("[!") && text.ends_with("]") && text[2..text.len() - 1].chars().all(|c| c.is_ascii_uppercase()) +} + fn gen_str(text: &str, context: &mut Context) -> PrintItems { let mut text_builder = TextBuilder::new(context); diff --git a/tests/specs/BlockQuotes/Callouts.txt b/tests/specs/BlockQuotes/Callouts.txt new file mode 100644 index 0000000..0bef7c4 --- /dev/null +++ b/tests/specs/BlockQuotes/Callouts.txt @@ -0,0 +1,24 @@ +~~ textWrap: always ~~ +!! should format !! +> [!NOTE] +> Some sort of note + +[expect] +> [!NOTE] +> Some sort of note + +!! should format when just a callout !! +> [!NOTE] + +[expect] +> [!NOTE] + +!! should format when has blank line !! +> [!NOTE] +> +> Some sort of note + +[expect] +> [!NOTE] +> +> Some sort of note