- WebP takes lossless and quality; there is no permissive pure-Rust lossy encoder yet, so
lossless: false writes lossless with a warning (the WebP Options dialog says so).
- document.export {format: "txt", encoding: utf8|utf16, lineEndings: lf|crlf,
selectionOnly}: the stories in stacking order (back to front), a thread once, hidden
objects and template layers left out; UTF-16 is little-endian with a byte order mark.
Export As → Text opens Text Export Options.
- File → Save for Office Documents… (document.exportForOffice {ppi, transparent, artboard,
path}): the artboard as a PNG at 72/150/300 ppi on white or transparent, through a small
dialog in the app.
document.formats' writable list and the MCP export tool's enum gain txt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
53 lines
2.3 KiB
Rust
53 lines
2.3 KiB
Rust
//! Export As → Text: the Text Export Options (encoding, line endings, selection only) for a
|
|
//! picked `.txt` path. Fields are `document.export` params (`format`, `path`…).
|
|
|
|
use serde_json::{Value, json};
|
|
|
|
use super::png_options::choice;
|
|
use super::{DialogSpec, form};
|
|
use crate::state::Dialog;
|
|
use crate::theme::Tokens;
|
|
use crate::{VectorcraftApp, io};
|
|
|
|
pub(crate) const KIND: &str = "txtOptions";
|
|
|
|
pub(super) const SPEC: DialogSpec =
|
|
DialogSpec { heading: |_| "Text Export Options".into(), body, confirm, ok: Some("Export"), min_width: 340.0, ..DialogSpec::FORM };
|
|
|
|
const ENCODINGS: [&str; 2] = ["utf8", "utf16"];
|
|
const ENCODING_LABELS: [&str; 2] = ["UTF-8", "UTF-16 (Unicode)"];
|
|
const LINE_ENDINGS: [&str; 2] = ["lf", "crlf"];
|
|
const LINE_ENDING_LABELS: [&str; 2] = ["LF (macOS, Linux)", "CRLF (Windows)"];
|
|
|
|
/// Open the options for exporting the document's text to `path`.
|
|
pub fn open(app: &mut VectorcraftApp, path: &str) {
|
|
// The platform's own line endings by default.
|
|
let eol = if cfg!(windows) { LINE_ENDINGS[1] } else { LINE_ENDINGS[0] };
|
|
let fields = json!({"format": "txt", "path": path, "encoding": ENCODINGS[0], "lineEndings": eol, "selectionOnly": false});
|
|
app.ui.dialog = Some(Dialog::new(KIND, fields));
|
|
}
|
|
|
|
fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
|
|
let t = Tokens::get(ui.ctx());
|
|
let label = |ui: &mut egui::Ui, text: &str| ui.label(egui::RichText::new(text).color(t.text_dim));
|
|
egui::Grid::new("text-export").num_columns(2).spacing([10.0, 8.0]).show(ui, |ui| {
|
|
label(ui, "Encoding:");
|
|
choice(ui, d, "encoding", &ENCODINGS, &ENCODING_LABELS);
|
|
ui.end_row();
|
|
label(ui, "Line Endings:");
|
|
choice(ui, d, "lineEndings", &LINE_ENDINGS, &LINE_ENDING_LABELS);
|
|
ui.end_row();
|
|
});
|
|
ui.add_space(8.0);
|
|
let selected = app.session.active().is_some_and(|st| !st.selection.objects.is_empty());
|
|
ui.add_enabled_ui(selected, |ui| form::check(ui, d, "selectionOnly", "Selection Only"));
|
|
false
|
|
}
|
|
|
|
/// Write the text file (the command runs first, so a bad option keeps the dialog open).
|
|
fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
|
|
let path = io::save_command_output(app, "document.export", "txt", form::params(d))?;
|
|
app.ui.dialog = None;
|
|
Ok(json!({ "path": path }))
|
|
}
|