#table #html #pretty-table #print #format

table_to_html

The library provides a interface to convert a tabled::Table into a HTML table (<table>)

3 releases (breaking)

0.4.0 Dec 20, 2023
0.3.0 Apr 23, 2023
0.2.0 Apr 11, 2023

#1593 in Text processing

26 downloads per month
Used in git-todo-collector

MIT license

775KB
16K SLoC

table_to_html

Provides a interface to build HTML <table>.

Get started

use table_to_html::HtmlTable;

fn main() {
    #[rustfmt::skip]
    let data = vec![
        ["0",  "INDIR", "",       "int sys_syscall(int number, ...)"],
        ["1",  "STD",   "",       "void sys_exit(int rval)"],
        ["2",  "STD",   "",       "int sys_fork(void)"],
        ["3",  "STD",   "NOLOCK", "ssize_t sys_read(int fd, void *buf, size_t nbyte)"],
        ["4",  "STD",   "NOLOCK", "ssize_t sys_write(int fd, const void *buf, size_t nbyte)"],
    ];

    let mut table = HtmlTable::new(data);
    table.set_border(3);

    println!("{table}")
}

<table>


lib.rs:

table_to_html

The library provides a interface to build a HTML table (<table>).

Example building a table from iterator

use table_to_html::HtmlTable;

let data = vec![
    vec!["Debian", "", "0"],
    vec!["Arch", "", "0"],
    vec!["Manjaro", "Arch", "0"],
];

let html_table = HtmlTable::new(data);

assert_eq!(
    html_table.to_string(),
    concat!(
        "<table>\n",
        "    <tbody>\n",
        "        <tr>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        Debian\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        \n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        0\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "        </tr>\n",
        "        <tr>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        Arch\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        \n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        0\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "        </tr>\n",
        "        <tr>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        Manjaro\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        Arch\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        0\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "        </tr>\n",
        "    </tbody>\n",
        "</table>"
    ),
)

Example building a table using Tabled.

use table_to_html::{HtmlTable, Alignment, Entity};
use tabled::{Table, Tabled};

#[derive(Debug, Tabled)]
struct Distribution {
    name: &'static str,
    based_on: &'static str,
    is_active: bool,
}

impl Distribution {
    fn new(name: &'static str, base: &'static str, is_active: bool) -> Self {
        Self {
            based_on: base,
            is_active,
            name,
        }
    }
}

let data = [
    Distribution::new("Debian", "", true),
    Distribution::new("Arch", "", true),
    Distribution::new("Manjaro", "Arch", true),
];

let mut html_table = HtmlTable::with_header(Vec::<Vec<String>>::from(Table::builder(&data)));
html_table.set_alignment(Entity::Row(1), Alignment::center());

assert_eq!(
    html_table.to_string(),
    concat!(
        "<style>\n",
        "    tbody > :nth-child(2) > td, thead > :nth-child(2) > th {\n",
        "      text-align: center;\n",
        "    }\n",
        "</style>\n",
        "<table>\n",
        "    <thead>\n",
        "        <tr>\n",
        "            <th>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        name\n",
        "                    </p>\n",
        "                </div>\n",
        "            </th>\n",
        "            <th>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        based_on\n",
        "                    </p>\n",
        "                </div>\n",
        "            </th>\n",
        "            <th>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        is_active\n",
        "                    </p>\n",
        "                </div>\n",
        "            </th>\n",
        "        </tr>\n",
        "    </thead>\n",
        "    <tbody>\n",
        "        <tr>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        Debian\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        \n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        true\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "        </tr>\n",
        "        <tr>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        Arch\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        \n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        true\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "        </tr>\n",
        "        <tr>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        Manjaro\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        Arch\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td>\n",
        "                <div>\n",
        "                    <p>\n",
        "                        true\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "        </tr>\n",
        "    </tbody>\n",
        "</table>",
    ),
)

The default table might look not very represenative. But it's considered that you might improve it by suplying your own CSS.

In a mean time there's some regular style options.

Also notice that table elements does not have any special id, class attributes. It's supposed that you might add them if nessary your self, by using HtmlTable::visit_mut

Adding custom ids example.

use table_to_html::{HtmlTable, html::{Attribute, HtmlVisitorMut, HtmlElement}};

struct CellIdIndex {
    i: usize
}

impl HtmlVisitorMut for CellIdIndex {
    fn visit_element_mut(&mut self, e: &mut HtmlElement) -> bool {
        if e.tag() == "td" {
            let mut attrs = e.attrs().to_vec();
            attrs.push(Attribute::new("id", self.i.to_string()));
            *e = HtmlElement::new("td", attrs, e.value().cloned());
            self.i += 1;
        } else if e.tag() == "th" {
            let mut attrs = e.attrs().to_vec();
            attrs.push(Attribute::new("id", self.i.to_string()));
            *e = HtmlElement::new("th", attrs, e.value().cloned());
            self.i += 1;
        }

        true
    }
}

let data = vec![
    vec!["Debian", "", "0"],
    vec!["Arch", "", "0"],
    vec!["Manjaro", "Arch", "0"],
];

let mut html_table = HtmlTable::new(data);
html_table.visit_mut(CellIdIndex{ i: 0 });

assert_eq!(
    html_table.to_string(),
    concat!(
        "<table>\n",
        "    <tbody>\n",
        "        <tr>\n",
        "            <td id=\"0\">\n",
        "                <div>\n",
        "                    <p>\n",
        "                        Debian\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td id=\"1\">\n",
        "                <div>\n",
        "                    <p>\n",
        "                        \n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td id=\"2\">\n",
        "                <div>\n",
        "                    <p>\n",
        "                        0\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "        </tr>\n",
        "        <tr>\n",
        "            <td id=\"3\">\n",
        "                <div>\n",
        "                    <p>\n",
        "                        Arch\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td id=\"4\">\n",
        "                <div>\n",
        "                    <p>\n",
        "                        \n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td id=\"5\">\n",
        "                <div>\n",
        "                    <p>\n",
        "                        0\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "        </tr>\n",
        "        <tr>\n",
        "            <td id=\"6\">\n",
        "                <div>\n",
        "                    <p>\n",
        "                        Manjaro\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td id=\"7\">\n",
        "                <div>\n",
        "                    <p>\n",
        "                        Arch\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "            <td id=\"8\">\n",
        "                <div>\n",
        "                    <p>\n",
        "                        0\n",
        "                    </p>\n",
        "                </div>\n",
        "            </td>\n",
        "        </tr>\n",
        "    </tbody>\n",
        "</table>"
    ),
)

Dependencies

~370–800KB
~18K SLoC