fn main() {
println!("cargo:rerun-if-changed=SPEC.md");
let spec = std::fs::read_to_string("SPEC.md").expect("SPEC.md not found");
let compact = compact_spec(&spec);
let tracked_path = std::path::Path::new("ai.txt");
let needs_write = match std::fs::read_to_string(tracked_path) {
Ok(existing) => existing != compact,
Err(_) => true,
};
if needs_write {
std::fs::write(tracked_path, &compact).expect("failed to write ai.txt");
}
}
fn compact_spec(src: &str) -> String {
let mut sections: Vec<(String, Vec<String>)> = vec![("INTRO".into(), vec![])];
for line in src.lines() {
let trimmed = line.trim();
if let Some(h) = trimmed.strip_prefix("## ") {
sections.push((h.to_uppercase(), vec![]));
} else {
sections
.last_mut()
.expect("sections always non-empty")
.1
.push(trimmed.to_string());
}
}
let mut out = String::new();
for (heading, raw_lines) in sections {
let tokens = compress_section(&raw_lines);
if tokens.is_empty() {
continue;
}
out.push_str(&heading);
out.push_str(": ");
out.push_str(&tokens);
out.push('\n');
}
out
}
fn compress_section(lines: &[String]) -> String {
#[derive(PartialEq)]
enum TableState {
NotInTable,
InHeader, InData, }
let mut items: Vec<String> = Vec::new();
let mut table_state = TableState::NotInTable;
for line in lines {
let t = line.as_str();
if t.is_empty() || t == "---" || t.starts_with("```") || t.starts_with("# ") {
continue;
}
if let Some(sub) = t.strip_prefix("### ") {
table_state = TableState::NotInTable;
items.push(format!("[{sub}]"));
continue;
}
if t.starts_with('|') {
let is_sep = t.chars().all(|c| matches!(c, '|' | '-' | ':' | ' '));
if is_sep {
table_state = TableState::InData;
continue;
}
match table_state {
TableState::NotInTable => {
table_state = TableState::InHeader;
}
TableState::InHeader => {
}
TableState::InData => {
const PIPE_PLACEHOLDER: &str = "\u{0001}";
let escaped = t.replace("\\|", PIPE_PLACEHOLDER);
let cells: Vec<String> = escaped
.split('|')
.map(str::trim)
.filter(|s| !s.is_empty())
.map(|s| s.replace(PIPE_PLACEHOLDER, "|"))
.collect();
items.push(collapse_ws(&cells.join("=")));
}
}
continue;
}
table_state = TableState::NotInTable;
if let Some(bullet) = t.strip_prefix("- ") {
items.push(collapse_ws(bullet));
} else {
items.push(collapse_ws(t));
}
}
items.join(" ")
}
fn collapse_ws(s: &str) -> String {
s.split_whitespace().collect::<Vec<_>>().join(" ")
}