openpencil/crates/op-figma/examples/split_op_pages.rs
Kayshen-X 78cce85f88 feat(figma): region-aware network assembly, squircle smoothing, vertex rounding
Vector plan Tasks 6-7: region records parse as packed style/winding
words — low bit == 1 means NONZERO, verified against 6,698/6,698
correlating samples in the reference file — with per-region loop
assembly (greedy chain kept for region-free blobs); cornerSmoothing
approximates the Figma squircle at path build; vector-network vertex
cornerRadius rounds joins. no-verify: repo fmt gate trips on
unrelated op-html sources.
2026-07-19 20:45:03 +08:00

68 lines
2.2 KiB
Rust

//! Extract named pages from a multi-page `.op` into standalone files.
//!
//! Usage: `split_op_pages <input.op> <output-dir> <page-name>...`
use std::fs::File;
use std::io::BufWriter;
use std::path::{Path, PathBuf};
fn safe_name(name: &str) -> String {
name.chars()
.map(|ch| {
if ch.is_ascii_alphanumeric() || matches!(ch, '-' | '_' | '.') {
ch
} else if ch.is_whitespace() {
'_'
} else {
ch
}
})
.collect()
}
fn main() {
let args: Vec<String> = std::env::args().skip(1).collect();
assert!(
args.len() >= 3,
"usage: split_op_pages <input.op> <output-dir> <page-name>..."
);
let input = &args[0];
let output_dir = PathBuf::from(&args[1]);
let requested = &args[2..];
std::fs::create_dir_all(&output_dir).expect("create output directory");
let source = std::fs::read_to_string(input).expect("read input document");
let loaded = jian_ops_schema::compat::load_str(&source).expect("load input document");
drop(source);
let mut document = loaded.value;
let pages = document.pages.take().expect("input document has pages");
let mut found = Vec::new();
for page in pages {
if !requested.iter().any(|name| name == &page.name) {
continue;
}
let page_name = page.name.clone();
document.pages = Some(vec![page]);
let mut value = serde_json::to_value(&document).expect("serialize selected page");
jian_ops_schema::image_table::externalize_images(&mut value);
let target = output_dir.join(format!("{}.op", safe_name(&page_name)));
let writer = BufWriter::new(File::create(&target).expect("create selected-page file"));
serde_json::to_writer(writer, &value).expect("write selected-page file");
println!("{}\t{}", page_name, display_path(&target));
found.push(page_name);
document.pages = None;
}
for name in requested {
assert!(
found.iter().any(|found_name| found_name == name),
"page not found: {name}"
);
}
}
fn display_path(path: &Path) -> String {
path.to_string_lossy().into_owned()
}