Collapse newlines from consecutive blocks and add indent to blockquote
Some checks failed
CI / Build and test (, nightly) (push) Waiting to run
CI / lint (push) Has been cancelled
CI / Build and test (, 1.73.0) (push) Has been cancelled
CI / Build and test (, beta) (push) Has been cancelled

This commit is contained in:
Val Lorentz 2023-11-25 23:31:24 +01:00
parent 43f71e9caa
commit 94e3db7415

View File

@ -31,20 +31,42 @@ pub fn escape_html<S: ?Sized + AsRef<str>>(s: &S) -> Cow<'_, str> {
}
#[derive(Clone, Debug)]
struct FormatState<'a> {
struct FormatState {
style: Style,
padding: &'a str,
padding: String,
}
fn format_tree(tree: Rc<Node>, state: FormatState, text: &mut Text<'static>) {
fn format_tree(
tree: Rc<Node>,
state: FormatState,
text: &mut Text<'static>,
mut previous_sibling_is_block: bool,
) -> bool {
use markup5ever_rcdom::NodeData::*;
let state = match &tree.data {
Document | Doctype { .. } | Comment { .. } | ProcessingInstruction { .. } => state,
Text { contents } => {
let s: String = contents.clone().into_inner().into();
let s = s.replace('\n', ""); // Lines are insignificant in HTML
if previous_sibling_is_block && !s.is_empty() {
text.lines.push(Line {
spans: vec![Span {
content: Cow::Owned(state.padding.to_owned()),
style: state.style,
}],
alignment: None,
});
previous_sibling_is_block = false;
}
text.lines.last_mut().unwrap().spans.push(Span {
content: Cow::Owned(contents.clone().into_inner().into()),
content: Cow::Owned(s.to_owned()),
style: state.style,
});
/*
if s.contains(|c: char| !c.is_whitespace()) {
previous_sibling_is_block = false;
}
*/
state
},
Element {
@ -61,13 +83,15 @@ fn format_tree(tree: Rc<Node>, state: FormatState, text: &mut Text<'static>) {
state
},
"p" => {
text.lines.push(Line::raw(state.padding.to_owned()));
previous_sibling_is_block = true;
state
},
"blockquote" => {
// TODO: indent
text.lines.push(Line::raw(state.padding.to_owned()));
state
previous_sibling_is_block = true;
FormatState {
padding: state.padding + "> ",
..state
}
},
"em" | "i" => FormatState {
style: state.style.italic(),
@ -87,7 +111,12 @@ fn format_tree(tree: Rc<Node>, state: FormatState, text: &mut Text<'static>) {
};
for subtree in tree.children.borrow().iter() {
format_tree(subtree.clone(), state.clone(), text);
previous_sibling_is_block = format_tree(
subtree.clone(),
state.clone(),
text,
previous_sibling_is_block,
);
}
match &tree.data {
@ -102,11 +131,15 @@ fn format_tree(tree: Rc<Node>, state: FormatState, text: &mut Text<'static>) {
attrs,
..
} => match name.as_ref() {
"p" | "blockquote" => text.lines.push(Line::default()),
"p" | "blockquote" => {
previous_sibling_is_block = true;
},
_ => {},
},
Element { .. } => {},
}
previous_sibling_is_block
}
pub fn format_html(s: &str) -> Text<'static> {
@ -120,9 +153,9 @@ pub fn format_html(s: &str) -> Text<'static> {
.document;
let state = FormatState {
style: Style::default(),
padding: " ",
padding: " ".to_owned(),
};
let mut text = Text::raw("");
format_tree(tree, state, &mut text);
format_tree(tree, state, &mut text, false);
text
}