Skip to content

Commit

Permalink
Code blocks get rendered without line breaks (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
ulyssa committed Jul 8, 2023
1 parent 6e8e12b commit b1ccec6
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 3 deletions.
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ features = ["macros", "net", "rt-multi-thread", "sync", "time"]

[dev-dependencies]
lazy_static = "1.4.0"
pretty_assertions = "1.4.0"

[profile.release]
lto = true
Expand Down
110 changes: 109 additions & 1 deletion src/message/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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())
},

Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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)
])
);
}
}
17 changes: 15 additions & 2 deletions src/message/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub struct TextPrinter<'a> {
alignment: Alignment,
curr_spans: Vec<Span<'a>>,
curr_width: usize,
literal: bool,
}

impl<'a> TextPrinter<'a> {
Expand All @@ -30,6 +31,7 @@ impl<'a> TextPrinter<'a> {
alignment: Alignment::Left,
curr_spans: vec![],
curr_width: 0,
literal: false,
}
}

Expand All @@ -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
}
Expand All @@ -56,6 +63,7 @@ impl<'a> TextPrinter<'a> {
alignment: self.alignment,
curr_spans: vec![],
curr_width: 0,
literal: self.literal,
}
}

Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down

0 comments on commit b1ccec6

Please sign in to comment.