mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-26 02:37:01 -06:00
Export for Screens: <filename> takes the saved document's file name
In a file name pattern, <filename> is documented as the document's name without its extension, but it expanded to the File Info title whenever the document had one, so a saved my-logo.vectorcraft titled "Logo: final version" exported as Logo--final-version__Artboard 1.png. The Full Document file and the .zip took the same title. Export for Screens and the dialog's Example line now take <filename> from the document's file, as Save names it (save.rs), and fall back to the title only for a document that has not been saved.
This commit is contained in:
@@ -382,7 +382,7 @@ struct Naming {
|
||||
}
|
||||
|
||||
impl Naming {
|
||||
/// The naming of params `o` for a document titled `title`.
|
||||
/// The naming of params `o` for a document named `title`: its file's path, or its title before it is saved.
|
||||
fn of(o: &ScreenParams, title: &str) -> Result<Self> {
|
||||
let folders = Folders::of(o)?;
|
||||
// A prefix names files, not folders.
|
||||
@@ -669,7 +669,9 @@ pub(crate) fn export(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let o = ScreenParams::of(p)?;
|
||||
let rows = rows_of(s, p, o.preset.as_deref())?;
|
||||
o.one_source()?;
|
||||
let naming = Naming::of(&o, &s.doc()?.doc.title)?;
|
||||
// `<filename>`: the document's file, as Save names it, or its title before it is saved.
|
||||
let st = s.doc()?;
|
||||
let naming = Naming::of(&o, st.path.as_deref().unwrap_or(&st.doc.title))?;
|
||||
let selection = o.selection_mode()?;
|
||||
let selected = if selection.is_some() { selected_artwork(s)? } else { vec![] };
|
||||
let doc = s.doc()?.doc.clone();
|
||||
@@ -846,13 +848,14 @@ pub fn first_file(s: &Session, p: &Value) -> Result<String> {
|
||||
let rows = rows_of(s, &p, o.preset.as_deref())?;
|
||||
o.one_source()?;
|
||||
let selection = o.selection_mode()?;
|
||||
let doc = &s.doc()?.doc;
|
||||
let st = s.doc()?;
|
||||
let doc = &st.doc;
|
||||
let mut selected = if selection.is_some() { selected_artwork(s)? } else { vec![] };
|
||||
// A file per object: objects that draw nothing write no file.
|
||||
if selection == Some(true) {
|
||||
selected = selected.into_iter().find(|id| export_crop(doc, &[*id]).is_some()).into_iter().collect();
|
||||
}
|
||||
let naming = Naming::of(&o, &doc.title)?;
|
||||
let naming = Naming::of(&o, st.path.as_deref().unwrap_or(&doc.title))?;
|
||||
let items = items(doc, &o, selection, &selected, &naming.filename, false, false)?;
|
||||
let (Some(item), Some(r)) = (items.first(), rows.first()) else { return Err(bad(C, "nothing to export")) };
|
||||
let (sub, file) = naming.file(item, 0, 0, r);
|
||||
|
||||
@@ -205,6 +205,39 @@ fn the_first_file_is_the_file_the_export_writes_first() {
|
||||
}
|
||||
}
|
||||
|
||||
/// A saved document's `<filename>`, Full Document file and ZIP are named after its file without the
|
||||
/// extension, as Save names it, whatever its File Info title says.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[test]
|
||||
fn a_saved_document_exports_under_its_file_name() {
|
||||
let mut s = session(1);
|
||||
s.execute("file.info", &json!({"title": "Logo: final version"})).unwrap();
|
||||
let dir = std::env::temp_dir().join(format!("vc-screens-filename-{}", std::process::id()));
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
s.execute("document.save", &json!({"path": dir.join("my-logo.vectorcraft").to_string_lossy()})).unwrap();
|
||||
for (p, name) in [
|
||||
(json!({"name": "<filename>__<name>", "formats": [{"format": "png"}]}), "my-logo__Artboard 1.png"),
|
||||
(json!({"fullDocument": true, "formats": [{"format": "png"}]}), "my-logo.png"),
|
||||
] {
|
||||
assert_eq!(names(&export(&mut s, p.clone())), [name], "{p}");
|
||||
assert_eq!(super::screens::first_file(&s, &p).unwrap(), name, "{p}");
|
||||
}
|
||||
assert_eq!(export(&mut s, json!({"zip": true, "formats": [{"format": "svg"}]}))["name"], "my-logo.zip");
|
||||
let _ = std::fs::remove_dir_all(dir);
|
||||
}
|
||||
|
||||
/// A document that has not been saved has no file: `<filename>` is its title.
|
||||
#[test]
|
||||
fn an_unsaved_document_exports_under_its_title() {
|
||||
let mut s = Session::new();
|
||||
s.execute("file.new", &json!({"width": 40, "height": 30, "name": "Poster"})).unwrap();
|
||||
s.execute("shape.rectangle", &json!({"x": 5, "y": 5, "width": 20, "height": 20})).unwrap();
|
||||
s.execute("file.info", &json!({"title": "Spring poster"})).unwrap();
|
||||
let p = json!({"name": "<filename>", "formats": [{"format": "png"}]});
|
||||
assert_eq!(names(&export(&mut s, p.clone())), ["Spring-poster.png"]);
|
||||
assert_eq!(super::screens::first_file(&s, &p).unwrap(), "Spring-poster.png");
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[test]
|
||||
fn sub_folders_are_made_in_the_export_folder() {
|
||||
|
||||
+3
-2
@@ -3628,8 +3628,9 @@ fallback font…), each note once; the export still writes or returns every file
|
||||
Batch exports (#1935):
|
||||
- **What:** `layers: [id…]` (each layer's art alone) or `selection: "one" | "each"` instead of artboards
|
||||
(`assets`, `fullDocument` as before).
|
||||
- **Names:** `name` is a pattern for every file: `<filename>` (the document), `<name>` (the artboard, asset, layer
|
||||
or object), `<index>`, `####` (a counter zero-padded to the run of `#`, from `counterStart`; `counterPer: "item"`
|
||||
- **Names:** `name` is a pattern for every file: `<filename>` (the document's file name without its extension, or
|
||||
its title before it is saved; the Full Document file and the `.zip` use the same name), `<name>` (the artboard,
|
||||
asset, layer or object), `<index>`, `####` (a counter zero-padded to the run of `#`, from `counterStart`; `counterPer: "item"`
|
||||
or `"file"`), `YYYYMMDD`, `YYYY-MM-DD`, `<date>`, `<time>`, `<format>`, `<scale>` and `<suffix>` (else the row's
|
||||
suffix ends the name; `date` sets the day the pattern uses). Different files it names alike get `-2`, `-3`….
|
||||
- **Folders:** `folders: "none" | "rows" | "format" | "item" | "itemFormat"` (all in one, a folder per row, per
|
||||
|
||||
Reference in New Issue
Block a user