Code blocks get rendered without line breaks (#122)

This commit is contained in:
Ulyssa 2023-07-07 21:42:14 -07:00
parent 6e8e12b579
commit b1ccec6732
No known key found for this signature in database
GPG key ID: F2873CA2997B83C5
4 changed files with 148 additions and 3 deletions

View file

@ -237,6 +237,7 @@ pub enum StyleTreeNode {
Image(Option<String>),
List(StyleTreeChildren, ListStyle),
Paragraph(Box<StyleTreeNode>),
Pre(Box<StyleTreeNode>),
Reply(Box<StyleTreeNode>),
Ruler,
Style(Box<StyleTreeNode>, Style),
@ -311,6 +312,39 @@ impl StyleTreeNode {
child.print(printer, style);
printer.commit();
},
StyleTreeNode::Pre(child) => {
let mut subp = printer.sub(2).literal(true);
let subw = subp.width();
child.print(&mut subp, style);
printer.commit();
printer.push_line(
vec![
Span::styled(line::TOP_LEFT, style),
Span::styled(line::HORIZONTAL.repeat(subw), style),
Span::styled(line::TOP_RIGHT, style),
]
.into(),
);
for mut line in subp.finish() {
line.0.insert(0, Span::styled(line::VERTICAL, style));
line.0.push(Span::styled(line::VERTICAL, style));
printer.push_line(line);
}
printer.push_line(
vec![
Span::styled(line::BOTTOM_LEFT, style),
Span::styled(line::HORIZONTAL.repeat(subw), style),
Span::styled(line::BOTTOM_RIGHT, style),
]
.into(),
);
printer.commit();
},
StyleTreeNode::Reply(child) => {
if printer.hide_reply() {
return;
@ -585,6 +619,7 @@ fn h2t(hdl: &Handle) -> StyleTreeChildren {
// Other text blocks.
"blockquote" => StyleTreeNode::Blockquote(c2t(&node.children.borrow())),
"div" | "p" => StyleTreeNode::Paragraph(c2t(&node.children.borrow())),
"pre" => StyleTreeNode::Pre(c2t(&node.children.borrow())),
// No children.
"hr" => StyleTreeNode::Ruler,
@ -593,7 +628,7 @@ fn h2t(hdl: &Handle) -> StyleTreeChildren {
"img" => StyleTreeNode::Image(attrs_to_alt(&attrs.borrow())),
// These don't render in any special way.
"a" | "details" | "html" | "pre" | "summary" | "sub" | "sup" => {
"a" | "details" | "html" | "summary" | "sub" | "sup" => {
*c2t(&node.children.borrow())
},
@ -630,6 +665,7 @@ pub fn parse_matrix_html(s: &str) -> StyleTree {
pub mod tests {
use super::*;
use crate::util::space_span;
use pretty_assertions::assert_eq;
#[test]
fn test_header() {
@ -1173,4 +1209,76 @@ pub mod tests {
])
);
}
#[test]
fn test_pre_tag() {
let s = concat!(
"<pre><code class=\"language-rust\">",
"fn hello() -&gt; usize {\n",
" return 5;\n",
"}\n",
"</code></pre>\n"
);
let tree = parse_matrix_html(s);
let text = tree.to_text(25, Style::default(), true);
assert_eq!(text.lines.len(), 5);
assert_eq!(
text.lines[0],
Spans(vec![
Span::raw(line::TOP_LEFT),
Span::raw(line::HORIZONTAL.repeat(23)),
Span::raw(line::TOP_RIGHT)
])
);
assert_eq!(
text.lines[1],
Spans(vec![
Span::raw(line::VERTICAL),
Span::raw("fn"),
Span::raw(" "),
Span::raw("hello"),
Span::raw("("),
Span::raw(")"),
Span::raw(" "),
Span::raw("-"),
Span::raw(">"),
Span::raw(" "),
Span::raw("usize"),
Span::raw(" "),
Span::raw("{"),
Span::raw(" "),
Span::raw(line::VERTICAL)
])
);
assert_eq!(
text.lines[2],
Spans(vec![
Span::raw(line::VERTICAL),
Span::raw(" "),
Span::raw("return"),
Span::raw(" "),
Span::raw("5"),
Span::raw(";"),
Span::raw(" "),
Span::raw(line::VERTICAL)
])
);
assert_eq!(
text.lines[3],
Spans(vec![
Span::raw(line::VERTICAL),
Span::raw("}"),
Span::raw(" ".repeat(22)),
Span::raw(line::VERTICAL)
])
);
assert_eq!(
text.lines[4],
Spans(vec![
Span::raw(line::BOTTOM_LEFT),
Span::raw(line::HORIZONTAL.repeat(23)),
Span::raw(line::BOTTOM_RIGHT)
])
);
}
}

View file

@ -17,6 +17,7 @@ pub struct TextPrinter<'a> {
alignment: Alignment,
curr_spans: Vec<Span<'a>>,
curr_width: usize,
literal: bool,
}
impl<'a> TextPrinter<'a> {
@ -30,6 +31,7 @@ impl<'a> TextPrinter<'a> {
alignment: Alignment::Left,
curr_spans: vec![],
curr_width: 0,
literal: false,
}
}
@ -38,6 +40,11 @@ impl<'a> TextPrinter<'a> {
self
}
pub fn literal(mut self, literal: bool) -> Self {
self.literal = literal;
self
}
pub fn hide_reply(&self) -> bool {
self.hide_reply
}
@ -56,6 +63,7 @@ impl<'a> TextPrinter<'a> {
alignment: self.alignment,
curr_spans: vec![],
curr_width: 0,
literal: self.literal,
}
}
@ -162,11 +170,16 @@ impl<'a> TextPrinter<'a> {
for mut word in UnicodeSegmentation::split_word_bounds(s) {
if let "\n" | "\r\n" = word {
if self.literal {
self.commit();
continue;
}
// Render embedded newlines as spaces.
word = " ";
}
if self.curr_width == 0 && word.chars().all(char::is_whitespace) {
if !self.literal && self.curr_width == 0 && word.chars().all(char::is_whitespace) {
// Drop leading whitespace.
continue;
}
@ -182,7 +195,7 @@ impl<'a> TextPrinter<'a> {
// Word doesn't fit on this line, so start a new one.
self.commit();
if word.chars().all(char::is_whitespace) {
if !self.literal && word.chars().all(char::is_whitespace) {
// Drop leading whitespace.
continue;
}