Crates.io | supertext |
lib.rs | supertext |
version | |
source | src |
created_at | 2025-04-21 05:46:52.506946+00 |
updated_at | 2025-04-24 09:23:35.849574+00 |
description | html document tools |
homepage | |
repository | http://git.iximeow.net/supertext/ |
max_upload_size | |
id | 1642331 |
Cargo.toml error: | TOML parse error at line 18, column 1 | 18 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
hypertext, a bit less hyper
i want to construct HTML documents in some Rust code. i don't want a full templating solution. i just want to append some tags and not forget to escape user-provided input.
you probably don't want to use this, but if you do it should work. public interfaces are basically expected to break. it is 0.0.1 for a reason.
pub fn example(items: &[(String, String)]) -> Result<String, std::fmt::Error> {
let mut out = String::new();
let mut writer = HtmlWriter::new(&mut out);
let mut html = HtmlSink::root(&mut writer);
{
let mut style = html.open_tag(style());
style.rule(".table { font-family: monospace; border: 1px solid black; }")?;
style.rule(".row-item { padding-left: 4px; padding-right: 4px; border-right: 1px solid black; }")?;
style.rule(".odd-row { background: #eee; }")?;
style.rule(".even-row { background: #ddd; }")?;
}
{
let mut header = html.open_tag(h1());
header.text("an example page that is super cool")?;
}
{
let mut description = html.open_tag(p());
match items.len() {
0 => description.text("no items")?,
1 => description.text("one item")?,
o => description.text(&format!("{} items", o))?,
};
}
let mut table = html.open_tag(table().class("table"));
{
let mut header = table.header();
let th = th().class("row-item");
let mut add_cell = |name: &'static str| header.open_tag(th.clone()).text(name);
add_cell("key")?;
add_cell("value")?;
}
let td = td().class("row-item");
for (i, item) in items.iter().enumerate() {
let mut row = table.row(tr().class(["even-row", "odd-row"][i % 2]));
{
let mut elem = row.open_tag(td.clone());
elem.open_tag(a().href(&format!("/{}", item.0))).text(&item.0)?;
}
{
row.open_tag(td.clone()).text(&item.1)?;
}
}
table.close();
html.close();
Ok(out)
}
this crate is intended to avoid trivially injectable HTML document construction. it is not intended to prevent semantically incoherent HTML documents. yet?
for example, this crate allows creating a table with twelve columns in its header, but varying (and not-twelve) rows afterwards. this crate allows tags to reference styles that are undefined. this crate allows intra-page links that are invalid. this crate allows syntactically invalid CSS.
phrasing content
in the HTML spec draw a clearer line about what elements can be nested.p.text()
lines always just
appends escaped text to the writer, maybe those should be spaced with
newlines? should text()
automatically append a line break?build_html looks good, almost is what i want! unfortunately:
Note that escaping strings is also not automatic. You should use the escape_html function if you are displaying untrusted text.
the API was already wanted more ceremony than i was happy with, but this moves it out of the running.
html is comprehensive, but perhaps too much so.
the docs surface area is roughly the product of all kinds of tags by all kinds of tags, to the point i have a bit of a difficult time with navigation. it includes lots of HTML spec that is probably interesting and meaningful if i was doing interesting things with HTML, but i'm not.
needing to set #![recursion_limit = "512"]
when depending on this crate is
another papercut; between that and its idleness, i'm OK passing here.
maud (book) seems good, but i don't want a template engine, i just want to put a few divs and spans together. more importantly, i want to be able to render elements of a page potentially independently. having to construct an entire HTML document in one go is not great, and having to learn a new syntax for control flow in the document is the opposite direction of what i want.