use std::sync::OnceLock;
const SOURCE: &str = include_str!("../mdbook-lini.css");
pub fn style_tag() -> &'static str {
static TAG: OnceLock<String> = OnceLock::new();
TAG.get_or_init(|| {
format!(
"<style>@layer lini.defaults, mdbook-lini;@layer mdbook-lini {{{}}}</style>\n\n",
minify(SOURCE)
)
})
}
fn minify(css: &str) -> String {
let mut out = String::with_capacity(css.len());
let mut rest = css;
while let Some(start) = rest.find("/*") {
out.push_str(&rest[..start]);
match rest[start + 2..].find("*/") {
Some(end) => rest = &rest[start + 2 + end + 2..],
None => return collapse(&out),
}
}
out.push_str(rest);
collapse(&out)
}
fn collapse(css: &str) -> String {
let mut out = String::with_capacity(css.len());
for part in css.split_whitespace() {
if !out.is_empty() {
out.push(' ');
}
out.push_str(part);
}
for sep in ['{', '}', ';', ':', ','] {
for spaced in [format!(" {sep}"), format!("{sep} ")] {
let bare = sep.to_string();
while out.contains(&spaced) {
out = out.replace(&spaced, &bare);
}
}
}
out.replace(";}", "}")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_tag_carries_the_stylesheet_in_its_own_layer() {
let tag = style_tag();
assert!(tag.starts_with("<style>@layer lini.defaults, mdbook-lini;"), "{tag}");
assert!(tag.contains("@layer mdbook-lini {"), "{tag}");
assert!(tag.ends_with("}</style>\n\n"));
assert!(tag.contains(".lini-figure"));
assert!(tag.contains("color-scheme"));
let order = tag.find("@layer lini.defaults,").unwrap();
assert!(order < tag.find("@layer mdbook-lini {").unwrap());
}
#[test]
fn comments_and_slack_whitespace_are_dropped() {
let out = minify("/* a note */\n.x {\n color: red;\n}\n");
assert_eq!(out, ".x{color:red}");
}
#[test]
fn an_unterminated_comment_does_not_eat_what_came_before() {
assert_eq!(minify(".x{color:red}\n/* oops"), ".x{color:red}");
}
#[test]
fn media_query_spacing_survives() {
assert!(
minify("@media only screen and (max-width: 768px) { .x { color: red } }")
.contains("only screen and (max-width:768px)")
);
}
#[test]
fn the_shipped_stylesheet_minifies_to_balanced_braces() {
let out = minify(SOURCE);
assert_eq!(out.matches('{').count(), out.matches('}').count(), "{out}");
assert!(!out.contains("/*"));
}
}