mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-01 13:47:21 -06:00
Batch: keep an existing artboard file of a one-artboard Separate Artboards save
A save in the native, template or .ai formats with separateArtboards writes an artboard file even when the document has one artboard, so an existing file with that name now gives the data set the next free suffix too.
This commit is contained in:
@@ -292,8 +292,9 @@ struct DatasetOutput {
|
||||
joiner: &'static str,
|
||||
}
|
||||
|
||||
/// Lists step output extensions and reserves artboard file names when the document has multiple artboards.
|
||||
/// Per-artboard names count for vectorcraft, template, AI and AIT saves and SVG, SVGZ, EPS, raster, DXF, EMF, WMF and AI exports.
|
||||
/// Lists step output extensions and reserves artboard file names for saves with any artboard or
|
||||
/// exports with multiple artboards. Per-artboard names count for vectorcraft, template, AI and AIT
|
||||
/// saves and SVG, SVGZ, EPS, raster, DXF, EMF, WMF and AI exports.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn dataset_output_extensions(run: &Run<'_>, doc: &vectorcraft_doc::Document) -> Vec<DatasetOutput> {
|
||||
let mut outputs = Vec::new();
|
||||
@@ -314,31 +315,31 @@ fn dataset_output_extensions(run: &Run<'_>, doc: &vectorcraft_doc::Document) ->
|
||||
if safe_extension(&ext) {
|
||||
let format_id = format.and_then(super::format).map(|f| f.id).unwrap_or("vectorcraft");
|
||||
let is_save = matches!(id, "document.save" | "file.save" | "file.saveAs");
|
||||
let artboards = doc.artboards.len() > 1
|
||||
&& if is_save {
|
||||
matches!(format_id, "vectorcraft" | "template" | "ai" | "ait")
|
||||
} else {
|
||||
id == "document.export"
|
||||
&& matches!(
|
||||
format_id,
|
||||
"svg"
|
||||
| "svgz"
|
||||
| "eps"
|
||||
| "png"
|
||||
| "jpg"
|
||||
| "webp"
|
||||
| "gif"
|
||||
| "png8"
|
||||
| "tiff"
|
||||
| "bmp"
|
||||
| "tga"
|
||||
| "psd"
|
||||
| "dxf"
|
||||
| "emf"
|
||||
| "wmf"
|
||||
| "ai"
|
||||
)
|
||||
};
|
||||
let artboards = if is_save {
|
||||
!doc.artboards.is_empty() && matches!(format_id, "vectorcraft" | "template" | "ai" | "ait")
|
||||
} else {
|
||||
doc.artboards.len() > 1
|
||||
&& id == "document.export"
|
||||
&& matches!(
|
||||
format_id,
|
||||
"svg"
|
||||
| "svgz"
|
||||
| "eps"
|
||||
| "png"
|
||||
| "jpg"
|
||||
| "webp"
|
||||
| "gif"
|
||||
| "png8"
|
||||
| "tiff"
|
||||
| "bmp"
|
||||
| "tga"
|
||||
| "psd"
|
||||
| "dxf"
|
||||
| "emf"
|
||||
| "wmf"
|
||||
| "ai"
|
||||
)
|
||||
};
|
||||
outputs.push(DatasetOutput { ext, artboards, joiner: if format_id == "eps" { "_" } else { "-" } });
|
||||
}
|
||||
}
|
||||
@@ -952,6 +953,40 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn batch_single_artboard_save_keeps_existing_artboard_file() {
|
||||
let source = tmp("choice-single-artboard-source");
|
||||
let dest = tmp("choice-single-artboard-dest");
|
||||
let mut s = Session::new();
|
||||
s.execute("file.new", &json!({"width": 20, "height": 20, "artboards": 1})).unwrap();
|
||||
s.execute(
|
||||
"document.save",
|
||||
&json!({
|
||||
"path": source.join("source.vectorcraft").to_string_lossy(),
|
||||
"separateArtboards": true
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(source.join("source-Artboard-1.vectorcraft").exists());
|
||||
|
||||
let existing = dest.join("Alpha-Artboard-1.vectorcraft");
|
||||
std::fs::write(&existing, b"keep").unwrap();
|
||||
s.execute("dataset.new", &json!({"name": "Alpha"})).unwrap();
|
||||
let r = s
|
||||
.execute(
|
||||
"action.batch",
|
||||
&json!({
|
||||
"source": "datasets", "datasetFileNaming": "dataSetName",
|
||||
"destinationFolder": dest.to_string_lossy(),
|
||||
"commands": [{"command": "document.save", "params": {"separateArtboards": true}}]
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(r["failed"], 0, "{r}");
|
||||
assert_eq!(std::fs::read(existing).unwrap(), b"keep");
|
||||
assert_eq!(file_names(&dest), ["Alpha-2-Artboard-1.vectorcraft", "Alpha-2.vectorcraft", "Alpha-Artboard-1.vectorcraft"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn batch_pdf_export_ignores_artboard_named_file() {
|
||||
let dest = tmp("choice-pdf-artboard-name");
|
||||
|
||||
+4
-3
@@ -2971,9 +2971,10 @@ destination and overridden Save/Export paths use the chosen stem with the output
|
||||
set name under Data Set Name falls back to the document stem plus its three-digit ordinal. Batch writes `/`, `\`,
|
||||
`:`, `<`, `>`, `"`, `|`, `?`, `*` and control characters in the data set's name as `-`, and adds the next free `-2`,
|
||||
`-3` suffix to a stem already used in the batch (compared without case). An output already in a destination folder
|
||||
gets the next free suffix only when the batch may read and write that folder before it starts. When a step can write
|
||||
one file per artboard and the document has several artboards, a file with one of those artboard file names for the
|
||||
stem counts too. Under Data Set Name, VectorCraft makes Windows device names safe (`CON` becomes `CON-`). This is
|
||||
gets the next free suffix only when the batch may read and write that folder before it starts. A save in VectorCraft,
|
||||
template, AI or AIT format counts artboard file names when the document has any artboard; a per-artboard export
|
||||
counts them when the document has several artboards.
|
||||
Under Data Set Name, VectorCraft makes Windows device names safe (`CON` becomes `CON-`). This is
|
||||
VectorCraft's naming behavior. Caps: 500
|
||||
files or data sets, 8 folder levels, 256 steps. An action recorded in the Actions panel leaves the artboard out,
|
||||
and its steps of these commands get the artboard that is active when the action plays. A press with the Selection,
|
||||
|
||||
Reference in New Issue
Block a user