Files
wordcraft/apps/wordcraft-cli/tests/convert_region.rs
bf2bd69470 HTML import: bold header cells, cell alignment and the region paper (#1381) (#1494)
* #1381: WIP

* #1381: HTML import: bold <th>, cell text-align, region paper for HTML/MD/TXT

Header cells are bold unless their own CSS says otherwise. text-align on a
td/th, or inherited from its tr/row group/table, aligns the cell's
paragraphs; a paragraph's own alignment wins, and a table's align attribute
(which places the table) no longer counts. Files that give no page size
(HTML, Markdown, plain text) open on the region's paper, as a new blank
document does: file.open uses the session's region, wordcraft-cli reads the
system region the way the app does (Region::from_locale_vars, shared with
ui-egui). Tables size to that page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #1381: the CLI uses the system region everywhere; help mentions WORDCRAFT_REGION

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-14 13:58:14 -04:00

54 lines
2.7 KiB
Rust

//! `wordcraft-cli convert page.html out.docx` puts an HTML file, which gives no page size, on the
//! system region's paper, as the app does: A4 in Italy, Letter in the US (#1381).
use std::process::Command;
const HTML: &str = "<html><body><h2>Premessa</h2><table border=1><thead><tr><th>Indicatore</th><th>Valore</th></tr></thead>\
<tbody><tr><td>Audit</td><td style=\"text-align:right;\">4</td></tr></tbody></table></body></html>";
/// Run the CLI in `region` with `args` (`{src}` is the sample HTML, `{out}` a JSON file it
/// writes) and read back the page size of the JSON it saved.
fn page_size_of(region: &str, args: &[&str]) -> (f64, f64) {
let dir = std::env::temp_dir().join(format!("wordcraft-cli-region-{region}-{}-{}", args.len(), std::process::id()));
std::fs::create_dir_all(&dir).unwrap();
let (src, out) = (dir.join("page.html"), dir.join("out.json"));
std::fs::write(&src, HTML).unwrap();
let args: Vec<String> = args.iter().map(|a| a.replace("{src}", &src.to_string_lossy()).replace("{out}", &out.to_string_lossy())).collect();
let run = Command::new(env!("CARGO_BIN_EXE_wordcraft-cli")).args(&args).env("WORDCRAFT_REGION", region).env_remove("LC_ALL").output().unwrap();
assert!(run.status.success(), "{args:?}: {}", String::from_utf8_lossy(&run.stderr));
let doc: serde_json::Value = serde_json::from_slice(&std::fs::read(&out).unwrap()).unwrap();
let _ = std::fs::remove_dir_all(&dir);
let sp = &doc["lastSection"];
(sp["pageW"].as_f64().unwrap(), sp["pageH"].as_f64().unwrap())
}
/// Convert the sample to JSON in `region` and read back the page size.
fn page_size(region: &str) -> (f64, f64) {
page_size_of(region, &["convert", "{src}", "{out}"])
}
fn is_a4((w, h): (f64, f64)) -> bool {
(w - 595.28).abs() < 0.01 && (h - 841.89).abs() < 0.01
}
#[test]
fn html_converts_onto_the_region_paper() {
let (w, h) = page_size("it-IT");
assert!(is_a4((w, h)), "A4 in Italy: {w} x {h}");
assert_eq!(page_size("en-US"), (612.0, 792.0), "Letter in the US");
}
#[test]
fn every_run_session_follows_the_region() {
// `run --file`, `run --template` and a bare `run` all start a session in the system region,
// so `file.new` gives the same paper whichever way the session began.
for args in [
&["run", "--cmd", "file.new", "--save", "{out}"][..],
&["run", "--template", "blank", "--save", "{out}"][..],
&["run", "--file", "{src}", "--cmd", "file.new", "--save", "{out}"][..],
] {
assert!(is_a4(page_size_of("it-IT", args)), "A4 in Italy: {args:?} gave {:?}", page_size_of("it-IT", args));
assert_eq!(page_size_of("en-US", args), (612.0, 792.0), "Letter in the US: {args:?}");
}
}