mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-26 10:47:11 -06:00
Fix PDF title display provenance
This commit is contained in:
committed by
bflatastic
parent
5e9df83dd4
commit
d548b4ff74
@@ -19,8 +19,15 @@ pub(super) fn serialize(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let f = writable("document.serialize", Some(str_param(p, "format").unwrap_or("vectorcraft")), None)?;
|
||||
let expanded = expand_presets(s, "document.serialize", p)?;
|
||||
let p = with_black_output(s, &expanded);
|
||||
let doc = &*source(s, f, &p, "document.serialize")?;
|
||||
let enc = encode_all(doc, f.id, &p)?;
|
||||
let (doc, display_doc_title) = source(s, f, &p, "document.serialize")?;
|
||||
let doc = &*doc;
|
||||
let mut q = p.clone();
|
||||
if f.id == "pdf"
|
||||
&& let Some(o) = q.as_object_mut()
|
||||
{
|
||||
o.insert("_displayDocTitle".into(), json!(display_doc_title));
|
||||
}
|
||||
let enc = encode_all(doc, f.id, &q)?;
|
||||
let files = enc.named(doc, &default_name(doc, f.extensions[0]));
|
||||
let (main, linked) = files.split_at(enc.files.len());
|
||||
// Text formats come back as text; an SVG in UTF-16 or ISO 8859-1 also as its bytes.
|
||||
@@ -53,8 +60,15 @@ pub(super) fn export(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let f = writable("document.export", str_param(p, "format"), path)?;
|
||||
let expanded = expand_presets(s, "document.export", p)?;
|
||||
let p = with_black_output(s, &expanded);
|
||||
let doc = &*source(s, f, &p, "document.export")?;
|
||||
let enc = encode_all(doc, f.id, &p)?;
|
||||
let (doc, display_doc_title) = source(s, f, &p, "document.export")?;
|
||||
let doc = &*doc;
|
||||
let mut q = p.clone();
|
||||
if f.id == "pdf"
|
||||
&& let Some(o) = q.as_object_mut()
|
||||
{
|
||||
o.insert("_displayDocTitle".into(), json!(display_doc_title));
|
||||
}
|
||||
let enc = encode_all(doc, f.id, &q)?;
|
||||
write_encoded(path, &default_name(doc, f.extensions[0]), doc, &enc, json!({ "format": f.id, "warnings": enc.warnings }))
|
||||
}
|
||||
|
||||
@@ -154,13 +168,16 @@ fn expand_presets<'a>(s: &Session, cmd: &str, p: &'a Value) -> Result<Cow<'a, Va
|
||||
|
||||
/// The document an export of `f` writes: the active one (see [`export_source`]), or for text
|
||||
/// with `selectionOnly` the selected objects alone.
|
||||
fn source<'a>(s: &'a mut Session, f: &Format, p: &Value, cmd: &str) -> Result<Cow<'a, Document>> {
|
||||
fn source<'a>(s: &'a mut Session, f: &Format, p: &Value, cmd: &str) -> Result<(Cow<'a, Document>, bool)> {
|
||||
if f.id == "txt" && bool_or(p, "selectionOnly", false) {
|
||||
return Ok(Cow::Owned(selection(s, cmd)?.0));
|
||||
let doc = selection(s, cmd)?.0;
|
||||
let display_doc_title = super::has_own_title(&doc);
|
||||
return Ok((Cow::Owned(doc), display_doc_title));
|
||||
}
|
||||
let st = s.doc()?;
|
||||
let doc = export_source(st, p)?;
|
||||
Ok(super::titled_for_export(&doc, st.path.as_deref(), f.id).map_or(doc, Cow::Owned))
|
||||
let display_doc_title = super::has_own_title(&doc);
|
||||
Ok((super::titled_for_export(&doc, st.path.as_deref(), f.id).map_or(doc, Cow::Owned), display_doc_title))
|
||||
}
|
||||
|
||||
/// The selected objects (not on template layers) alone on one layer, with one artboard: their
|
||||
|
||||
@@ -871,9 +871,12 @@ pub fn file_stem(name: &str) -> String {
|
||||
/// document that only has the Untitled-N name New gave it is titled after its file, as its tab is
|
||||
/// (the title PDF, PNG and SVG metadata carry). A title of its own stays, and native files keep
|
||||
/// the stored title.
|
||||
pub fn has_own_title(doc: &vectorcraft_doc::Document) -> bool {
|
||||
!doc.title.strip_prefix("Untitled-").is_some_and(|n| !n.is_empty() && n.bytes().all(|b| b.is_ascii_digit()))
|
||||
}
|
||||
|
||||
pub fn titled_for_export(doc: &vectorcraft_doc::Document, path: Option<&str>, format: &str) -> Option<vectorcraft_doc::Document> {
|
||||
let untitled = doc.title.strip_prefix("Untitled-").is_some_and(|n| !n.is_empty() && n.bytes().all(|b| b.is_ascii_digit()));
|
||||
let path = path.filter(|_| untitled && !matches!(format, "vectorcraft" | "template" | "ai"))?;
|
||||
let path = path.filter(|_| !has_own_title(doc) && !matches!(format, "vectorcraft" | "template" | "ai"))?;
|
||||
let mut d = doc.clone();
|
||||
d.title = file_stem(path);
|
||||
Some(d)
|
||||
|
||||
@@ -243,7 +243,14 @@ pub fn options(cmd: &str, doc: &Document, p: &Value) -> Result<PdfOptions> {
|
||||
let pick = if p.is_object() { ArtboardPick::deserialize(p).map_err(|e| bad(cmd, format!("PDF options: {e}")))? } else { ArtboardPick::default() };
|
||||
let artboards = pick.resolve(doc.artboards.len()).map_err(|e| bad(cmd, e))?;
|
||||
let now = vectorcraft_doc::metadata::output_time();
|
||||
Ok(PdfOptions { settings: settings(cmd, p)?, artboards, created: doc.metadata.created.or(now), modified: now, ..Default::default() })
|
||||
Ok(PdfOptions {
|
||||
settings: settings(cmd, p)?,
|
||||
artboards,
|
||||
display_doc_title: bool_or(p, "_displayDocTitle", super::has_own_title(doc)),
|
||||
created: doc.metadata.created.or(now),
|
||||
modified: now,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
/// Why a PDF of some artboards carries no editing data.
|
||||
@@ -387,8 +394,13 @@ fn export_pdf(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let expanded = expand_preset(s, C, p)?;
|
||||
let p = &*expanded;
|
||||
let st = s.doc()?;
|
||||
let display_doc_title = super::has_own_title(&st.doc);
|
||||
let titled = super::titled_for_export(&st.doc, st.path.as_deref(), "pdf");
|
||||
let (bytes, warnings) = encode(C, titled.as_ref().unwrap_or(&st.doc), p)?;
|
||||
let mut q = p.clone();
|
||||
if let Some(o) = q.as_object_mut() {
|
||||
o.insert("_displayDocTitle".into(), json!(display_doc_title));
|
||||
}
|
||||
let (bytes, warnings) = encode(C, titled.as_ref().unwrap_or(&st.doc), &q)?;
|
||||
write_or_return(str_param(p, "path"), &bytes, json!({ "warnings": warnings }))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user