summaryrefslogtreecommitdiffstats
path: root/src/lib.rs
diff options
context:
space:
mode:
authorJonas Bushart <jonas@bushart.org>2019-01-20 18:07:20 +0100
committerJonas Bushart <jonas@bushart.org>2019-08-26 00:36:03 +0200
commit917e480a673d1ab03218702d0e9e726131e48799 (patch)
tree560f4308b71c7addc3bdbc85c024482df2d638e2 /src/lib.rs
parent1e06ea72ccf03cd2129d104360e1e07679190a07 (diff)
Implement HTML output for Table and TableSlice
* Add a HTML escaper to the utils class. * Expand TableSlice, Row, and Cell with HTML printing functions. These are implemented from scratch as they share almost nothing with the line based printing used for text, as HTML directly supports multiline cells. * Add tests to Cell and Table which test the new functionality.
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 66daaf9..1e02055 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -204,6 +204,28 @@ impl<'a> TableSlice<'a> {
pub fn printstd(&self) -> usize {
self.print_tty(false)
}
+
+ /// Print table in HTML format to `out`.
+ pub fn print_html<T: Write + ?Sized>(&self, out: &mut T) -> Result<(), Error> {
+ // Compute column width
+ let column_num = self.get_column_num();
+ out.write_all(b"<table>")?;
+ // Print titles / table header
+ if let Some(ref t) = *self.titles {
+ out.write_all(b"<th>")?;
+ t.print_html(out, column_num)?;
+ out.write_all(b"</th>")?;
+ }
+ // Print rows
+ for r in self.rows {
+ out.write_all(b"<tr>")?;
+ r.print_html(out, column_num)?;
+ out.write_all(b"</tr>")?;
+ }
+ out.write_all(b"</table>")?;
+ out.flush()?;
+ Ok(())
+ }
}
impl<'a> IntoIterator for &'a TableSlice<'a> {
@@ -372,6 +394,10 @@ impl Table {
self.as_ref().printstd()
}
+ /// Print table in HTML format to `out`.
+ pub fn print_html<T: Write + ?Sized>(&self, out: &mut T) -> Result<(), Error> {
+ self.as_ref().print_html(out)
+ }
}
impl Index<usize> for Table {
@@ -980,4 +1006,69 @@ mod tests {
assert_eq!(out, table.to_string().replace("\r\n","\n"));
assert_eq!(7, table.print(&mut StringWriter::new()).unwrap());
}
+
+ #[test]
+ fn table_html() {
+ let mut table = Table::new();
+ table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")]));
+ table.add_row(Row::new(vec![Cell::new("def"), Cell::new("bc"), Cell::new("a")]));
+ table.set_titles(Row::new(vec![Cell::new("t1"), Cell::new("t2"), Cell::new("t3")]));
+ let out = "\
+<table>\
+<th><td style=\"text-align: left;\">t1</td><td style=\"text-align: left;\">t2</td><td style=\"text-align: left;\">t3</td></th>\
+<tr><td style=\"text-align: left;\">a</td><td style=\"text-align: left;\">bc</td><td style=\"text-align: left;\">def</td></tr>\
+<tr><td style=\"text-align: left;\">def</td><td style=\"text-align: left;\">bc</td><td style=\"text-align: left;\">a</td></tr>\
+</table>";
+ let mut writer = StringWriter::new();
+ assert!(table.print_html(&mut writer).is_ok());
+ assert_eq!(writer.as_string().replace("\r\n", "\n"), out);
+ table.unset_titles();
+ let out = "\
+<table>\
+<tr><td style=\"text-align: left;\">a</td><td style=\"text-align: left;\">bc</td><td style=\"text-align: left;\">def</td></tr>\
+<tr><td style=\"text-align: left;\">def</td><td style=\"text-align: left;\">bc</td><td style=\"text-align: left;\">a</td></tr>\
+</table>";
+ let mut writer = StringWriter::new();
+ assert!(table.print_html(&mut writer).is_ok());
+ assert_eq!(writer.as_string().replace("\r\n", "\n"), out);
+ }
+
+ #[test]
+ fn table_html_colors() {
+ let mut table = Table::new();
+ table.add_row(Row::new(vec![
+ Cell::new("bold").style_spec("b"),
+ Cell::new("italic").style_spec("i"),
+ Cell::new("underline").style_spec("u"),
+ ]));
+ table.add_row(Row::new(vec![
+ Cell::new("left").style_spec("l"),
+ Cell::new("center").style_spec("c"),
+ Cell::new("right").style_spec("r"),
+ ]));
+ table.add_row(Row::new(vec![
+ Cell::new("red").style_spec("Fr"),
+ Cell::new("black").style_spec("Fd"),
+ Cell::new("yellow").style_spec("Fy"),
+ ]));
+ table.add_row(Row::new(vec![
+ Cell::new("bright magenta on cyan").style_spec("FMBc"),
+ Cell::new("white on bright green").style_spec("FwBG"),
+ Cell::new("default on blue").style_spec("Bb"),
+ ]));
+ table.set_titles(Row::new(vec![
+ Cell::new("span horizontal").style_spec("H3"),
+ ]));
+ let out = "\
+<table>\
+<th><td colspan=\"3\" style=\"text-align: left;\">span horizontal</td></th>\
+<tr><td style=\"font-weight: bold;text-align: left;\">bold</td><td style=\"font-style: italic;text-align: left;\">italic</td><td style=\"text-decoration: underline;text-align: left;\">underline</td></tr>\
+<tr><td style=\"text-align: left;\">left</td><td style=\"text-align: center;\">center</td><td style=\"text-align: right;\">right</td></tr>\
+<tr><td style=\"color: #aa0000;text-align: left;\">red</td><td style=\"color: #000000;text-align: left;\">black</td><td style=\"color: #aa5500;text-align: left;\">yellow</td></tr>\
+<tr><td style=\"color: #ff55ff;background-color: #00aaaa;text-align: left;\">bright magenta on cyan</td><td style=\"color: #aaaaaa;background-color: #55ff55;text-align: left;\">white on bright green</td><td style=\"background-color: #0000aa;text-align: left;\">default on blue</td></tr>\
+</table>";
+ let mut writer = StringWriter::new();
+ assert!(table.print_html(&mut writer).is_ok());
+ assert_eq!(writer.as_string().replace("\r\n", "\n"), out);
+ }
}