Skip to content

Commit 5b9d69f

Browse files
committed
Fix a few cases where empty lines could be added.
1 parent b7c6021 commit 5b9d69f

File tree

3 files changed

+57
-17
lines changed

3 files changed

+57
-17
lines changed

examples/html2text.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ fn main() {
190190

191191
match outfile {
192192
None => {
193-
println!("{}", data);
193+
print!("{}", data);
194194
}
195195
Some(name) => {
196196
let mut file = std::fs::File::create(name).expect("Tried to create file");

src/lib.rs

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -720,9 +720,12 @@ fn table_to_render_tree<'a, 'b, T: Write>(
720720
html_trace!("Found in table: {:?}", bodynode.info);
721721
}
722722
}
723-
Ok(Some(RenderNode::new(RenderNodeInfo::Table(RenderTable::new(
724-
rows,
725-
)))))
723+
if rows.is_empty() {
724+
Ok(None)
725+
} else {
726+
Ok(Some(RenderNode::new(RenderNodeInfo::Table(RenderTable::new(
727+
rows)))))
728+
}
726729
})
727730
}
728731

@@ -731,7 +734,7 @@ fn tbody_to_render_tree<'a, 'b, T: Write>(
731734
handle: Handle,
732735
_err_out: &'b mut T,
733736
) -> TreeMapResult<'a, HtmlContext, Handle, RenderNode> {
734-
pending(handle, |_, rowchildren| {
737+
pending_noempty(handle, |_, rowchildren| {
735738
let mut rows = rowchildren
736739
.into_iter()
737740
.flat_map(|rownode| {
@@ -1038,6 +1041,24 @@ where
10381041
}
10391042
}
10401043

1044+
fn pending_noempty<'a, F>(handle: Handle, f: F) -> TreeMapResult<'a, HtmlContext, Handle, RenderNode>
1045+
where
1046+
for<'r> F: Fn(&'r mut HtmlContext, std::vec::Vec<RenderNode>) -> Result<Option<RenderNode>> + 'static,
1047+
{
1048+
TreeMapResult::PendingChildren {
1049+
children: handle.children.borrow().clone(),
1050+
cons: Box::new(move |ctx, children| {
1051+
if children.is_empty() {
1052+
Ok(None)
1053+
} else {
1054+
f(ctx, children)
1055+
}
1056+
}),
1057+
prefn: None,
1058+
postfn: None,
1059+
}
1060+
}
1061+
10411062
/// Prepend a FragmentStart (or analogous) marker to an existing
10421063
/// RenderNode.
10431064
fn prepend_marker(prefix: RenderNode, mut orig: RenderNode) -> RenderNode {
@@ -1160,7 +1181,7 @@ fn process_dom_node<'a, 'b, 'c, T: Write>(
11601181
}
11611182
expanded_name!(html "span") => {
11621183
/* process children, but don't add anything */
1163-
pending(handle, |_, cs| Ok(Some(RenderNode::new(Container(cs)))))
1184+
pending_noempty(handle, |_, cs| Ok(Some(RenderNode::new(Container(cs)))))
11641185
}
11651186
#[cfg(feature = "css")]
11661187
expanded_name!(html "font") => {
@@ -1178,9 +1199,9 @@ fn process_dom_node<'a, 'b, 'c, T: Write>(
11781199
}
11791200
}
11801201
if let Some(colour) = colour {
1181-
pending(handle, move |_, cs| Ok(Some(RenderNode::new(Coloured(colour, vec![RenderNode::new(Container(cs))])))))
1202+
pending_noempty(handle, move |_, cs| Ok(Some(RenderNode::new(Coloured(colour, vec![RenderNode::new(Container(cs))])))))
11821203
} else {
1183-
pending(handle, |_, cs| Ok(Some(RenderNode::new(Container(cs)))))
1204+
pending_noempty(handle, |_, cs| Ok(Some(RenderNode::new(Container(cs)))))
11841205
}
11851206
}
11861207
expanded_name!(html "a") => {
@@ -1257,13 +1278,13 @@ fn process_dom_node<'a, 'b, 'c, T: Write>(
12571278
})
12581279
}
12591280
expanded_name!(html "p") => {
1260-
pending(handle, |_, cs| Ok(Some(RenderNode::new(Block(cs)))))
1281+
pending_noempty(handle, |_, cs| Ok(Some(RenderNode::new(Block(cs)))))
12611282
}
12621283
expanded_name!(html "li") => {
12631284
pending(handle, |_, cs| Ok(Some(RenderNode::new(ListItem(cs)))))
12641285
}
12651286
expanded_name!(html "div") => {
1266-
pending(handle, |_, cs| Ok(Some(RenderNode::new(Div(cs)))))
1287+
pending_noempty(handle, |_, cs| Ok(Some(RenderNode::new(Div(cs)))))
12671288
}
12681289
expanded_name!(html "pre") => {
12691290
pending(handle, |_, cs| Ok(Some(RenderNode::new(Pre(cs)))))
@@ -1278,10 +1299,10 @@ fn process_dom_node<'a, 'b, 'c, T: Write>(
12781299
td_to_render_tree(handle.clone(), err_out)
12791300
}
12801301
expanded_name!(html "blockquote") => {
1281-
pending(handle, |_, cs| Ok(Some(RenderNode::new(BlockQuote(cs)))))
1302+
pending_noempty(handle, |_, cs| Ok(Some(RenderNode::new(BlockQuote(cs)))))
12821303
}
12831304
expanded_name!(html "ul") => {
1284-
pending(handle, |_, cs| Ok(Some(RenderNode::new(Ul(cs)))))
1305+
pending_noempty(handle, |_, cs| Ok(Some(RenderNode::new(Ul(cs)))))
12851306
}
12861307
expanded_name!(html "ol") => {
12871308
let borrowed = attrs.borrow();
@@ -1293,7 +1314,7 @@ fn process_dom_node<'a, 'b, 'c, T: Write>(
12931314
}
12941315
}
12951316

1296-
pending(handle, move |_, cs| {
1317+
pending_noempty(handle, move |_, cs| {
12971318
dbg!(&cs);
12981319
let cs = cs.into_iter()
12991320
.filter(|n| match &n.info {
@@ -1310,7 +1331,7 @@ fn process_dom_node<'a, 'b, 'c, T: Write>(
13101331
))),
13111332
_ => {
13121333
html_trace!("Unhandled element: {:?}\n", name.local);
1313-
pending(handle, |_, cs| Ok(Some(RenderNode::new(Container(cs)))))
1334+
pending_noempty(handle, |_, cs| Ok(Some(RenderNode::new(Container(cs)))))
13141335
//None
13151336
}
13161337
};
@@ -1742,6 +1763,10 @@ fn render_table_tree<T: Write, D: TextDecorator>(
17421763
.saturating_sub(1)
17431764
};
17441765

1766+
if table_width == 0 {
1767+
return Ok(TreeMapResult::Nothing);
1768+
}
1769+
17451770
renderer.add_horizontal_border_width(table_width)?;
17461771

17471772
Ok(TreeMapResult::PendingChildren {

src/render/text_renderer.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,15 @@ impl<T: PartialEq + Eq + Clone + Debug + Default> RenderLine<T> {
840840
RenderLine::Line(border) => border.to_string(),
841841
}
842842
}
843+
844+
/// Return whether this line has any text content
845+
/// Borders do not count as text.
846+
fn has_content(&self) -> bool {
847+
match self {
848+
RenderLine::Text(line) => !line.is_empty(),
849+
RenderLine::Line(_) => false,
850+
}
851+
}
843852
}
844853

845854
/// A renderer which just outputs plain text with
@@ -973,7 +982,7 @@ impl<D: TextDecorator> SubRenderer<D> {
973982

974983
#[cfg(feature = "html_trace")]
975984
/// Returns a string of the current builder contents (for testing).
976-
fn to_string(&self) -> String {
985+
pub fn to_string(&self) -> String {
977986
let mut result = String::new();
978987
for line in &self.lines {
979988
result += &line.to_string();
@@ -1079,7 +1088,13 @@ impl<D: TextDecorator> Renderer for SubRenderer<D> {
10791088
fn start_block(&mut self) -> crate::Result<()> {
10801089
html_trace!("start_block({})", self.width);
10811090
self.flush_all()?;
1082-
if !self.lines.is_empty() {
1091+
if self.lines.iter().any(|l| l.has_content()) {
1092+
/*
1093+
eprintln!("Starting block, lines not empty");
1094+
for line in &self.lines {
1095+
dbg!(line);
1096+
}
1097+
*/
10831098
self.add_empty_line()?;
10841099
}
10851100
html_trace_quiet!("start_block; at_block_end <- false");
@@ -1231,7 +1246,7 @@ impl<D: TextDecorator> Renderer for SubRenderer<D> {
12311246
{
12321247
use self::TaggedLineElement::Str;
12331248
html_trace!("append_columns_with_borders(collapse={})", collapse);
1234-
html_trace!("self=\n{}", self.to_string());
1249+
html_trace!("self=<<<\n{}>>>", self.to_string());
12351250

12361251
self.flush_wrapping()?;
12371252

0 commit comments

Comments
 (0)