diff --git a/apps/figcraft-cli/src/files.rs b/apps/figcraft-cli/src/files.rs index 111518b3..b3778063 100644 --- a/apps/figcraft-cli/src/files.rs +++ b/apps/figcraft-cli/src/files.rs @@ -208,10 +208,10 @@ pub fn info(path: &str, as_json: bool) -> CliResult { } /// The file name a layer exports to: the app's rule ([`figcraft_engine::cmd::file::safe_file_name`], -/// so `/` becomes `_` too), without leading or trailing spaces and dots. +/// so `/` becomes `_` too), without leading or trailing spaces and dots, at most 100 characters. fn sanitize(name: &str) -> String { let s = figcraft_engine::cmd::file::safe_file_name(name); - let s = s.trim().trim_matches('.').trim().to_string(); + let s = s.trim_matches(|c: char| c == '.' || c.is_whitespace()).to_string(); if s.is_empty() { "layer".into() } else { s.chars().take(100).collect() } } @@ -418,6 +418,7 @@ mod tests { assert_eq!(sanitize("Q&A, 50% #1 [v2] {x} ~é"), "Q&A, 50% #1 [v2] {x} ~é"); assert_eq!(sanitize("a\\b:c*d?e\"fh|i\tj"), "a_b_c_d_e_f_g_h_i_j"); assert_eq!(sanitize(" .hidden. "), "hidden"); + assert_eq!(sanitize(" . .name. . "), "name", "spaces and dots at the edges, mixed"); assert_eq!(sanitize(&"x".repeat(300)).chars().count(), 100); } diff --git a/crates/engine/src/cmd/file.rs b/crates/engine/src/cmd/file.rs index 28fa7a1e..efd1fcb7 100644 --- a/crates/engine/src/cmd/file.rs +++ b/crates/engine/src/cmd/file.rs @@ -1170,8 +1170,9 @@ fn export_path(name: &str) -> String { } /// `name` without path separators and characters file systems reject (`/ \ : * ? " < > |` and -/// control characters become `_`); everything else is kept. `figcraft-cli export` names its files -/// by this rule too. +/// control characters become `_`); everything else is kept, up to the first 200 characters. +/// `figcraft-cli export` names its files by this rule too (and keeps at most 100 characters before +/// the number and extension it adds). pub fn safe_file_name(name: &str) -> String { name.chars().take(200).map(|c| if c.is_control() || "/\\:*?\"<>|".contains(c) { '_' } else { c }).collect() } diff --git a/docs/cli.md b/docs/cli.md index f01de3b4..8f427194 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -53,8 +53,8 @@ page 1 "Screens": 380 nodes, 4 top-level after the frame (`Home.png`, `Settings.png`…); with no frames, one file per top-level layer. The name is kept as it is, except for the characters file systems refuse (`/ \ : * ? " < > |` and control characters), which become `_`, and leading or trailing spaces and dots, which are - dropped. The app's export replaces the same characters (there a `/` makes a folder). Two layers - with the same name get `Name 2`, `Name 3`… + dropped. A name is cut at 100 characters. The app's export replaces the same characters (there a + `/` makes a folder). Two layers with the same name get `Name 2`, `Name 3`… - `` has an image extension: one file with the given `--node`, or the whole page composited. - `--node` takes a layer id (`12` or `0:12`) or a layer name. - `--format fig` (or an `` ending in `.fig`) writes the whole file as `.fig`, experimental: