Variables: Load and Save Variable Library hold visibility, image and graph variables

Load Variable Library defines each variable with the kind of its trait
(textcontent, visibility, fileref, graphdata; any other or none is the
unknown kind) and reads visibility values from true or false, image
values from a file's absolute path or file: URL, and graph values from
a data element of series names and rows. A document variable declared
with the same name and kind keeps its bindings. Save Variable Library
writes every kind in the same forms and is enabled with any variable.
Image values that aren't absolute paths and graph data past what a
graph holds are refused, so every saved file loads back.
This commit is contained in:
dotCooCoo
2026-11-14 13:23:02 -08:00
parent 14f12130e7
commit e90c4e6fb2
9 changed files with 773 additions and 236 deletions
+38 -22
View File
@@ -3281,32 +3281,48 @@ already walks Image Trace. Short agent entry points:
`dataset.import`, adds no undo step when it leaves the variables and data sets as they were. The library
is XML whose `variableSets` element holds `variableSet` elements, each with a `variables` element of `variable`
elements (`varName`, `trait`) and a `sampleDataSets` element of `sampleDataSet` elements (`dataSetName`). Every
data set is deleted, and every variable of the document is deleted with its bindings and values, except a text
variable the library also declares: it keeps its bindings, so selecting one of the library's data sets changes the
objects bound to it. Then the library's other variables whose `trait` is `textcontent` are defined as text
variables, unbound. In each data set, the element named
after a text variable gives its value: the text of its `p` elements, one paragraph each. An element without a `p`
element gives no value. Variables of other kinds are left out with their values: the reply lists them in `skipped`
(`name`, `trait`), and its `warning` names each `trait` with its count. The reply's `deleted` and `deletedDataSets`
data set is deleted, and every variable of the document is deleted with its bindings and values, except a variable
the library also declares with the same kind: it keeps its bindings, so selecting one of the library's data sets
changes the objects bound to it. Then the library's other variables are defined, unbound, with the kind their
`trait` gives: `textcontent` is text, `visibility` is visibility, `fileref` (a linked file) is image and
`graphdata` is graph. A variable without a `trait`, or with one VectorCraft doesn't know, is defined of unknown
kind and takes no values. In each data set, the element named after a variable gives its value:
- text: the text of its `p` elements, one paragraph each; an element without a `p` element gives no value;
- visibility: `true` or `false`, in any case;
- image: a file's absolute path (from `/`, `\\` or a drive's root) or a `file:` URL of one, whose `%XX` escapes
are decoded; the file isn't read, so a library can name files that aren't there;
- graph: a `data` element. Its optional `propertyRow` holds a corner cell and then the series names, and each `row`
of its `values` holds the row's category in a first `value` whose `key` is `name`, then a `value` per series. A
value that is empty, marked `type="string"` or not a number is a blank. The data is read as the CSV
`graph.setData` takes, at most 256 KiB of it. Graph data with more than 10,000 rows or 256 series, which a
graph doesn't hold, is refused, by `variable.saveLibrary` too. `variable.saveLibrary` also refuses graph data
with neither rows nor series, which loads back as no value.
Visibility, image and graph values are read without the white space round them, and an element holding only white
space gives no value. The reply's `variables` lists the library's variables, and `deleted` and `deletedDataSets`
list the variables and data sets the load deleted. While the variables are locked, a library that would delete or
define a variable fails with "variables are locked". The reply is `{variables, deleted, deletedDataSets, names,
skipped, warning?}`. A library larger than 8 MiB, one whose elements nest more than 256 deep, and one with more
define a variable fails with "variables are locked". The reply is `{variables, deleted, deletedDataSets, names}`. A
library larger than 8 MiB, one whose elements nest more than 256 deep, and one with more
than 256 variables or 1,000 data sets are refused. Its document type declaration may hold an external identifier,
comments, processing instructions and up to 64 entity declarations whose values are plain text (no `<`, `&` or
`%`). A declaration that holds anything else, and entity references that expand the library past 8 MiB, are
refused. So are a variable or data set declared twice and a value for a variable the library doesn't declare.
`variable.saveLibrary {path?}` (the panel menu's Save Variable Library…) writes the document's text variables and
every data set as a variable library in the layout `variable.loadLibrary` reads: a `variable` element with
`varName` and `trait="textcontent"` for each text variable, and a `sampleDataSet` element with `dataSetName` for
each data set, holding an element named after each text variable it has a value for, with one `p` element per line
of the value. Loading the file gives back the same text variables, data set names and text values. Variables of
other kinds are left out with their values: the reply lists them in `skipped` (`name`, `kind`), and its `warning`
names each kind with its count. Saving is refused for a document without a text variable, for a text variable whose
name isn't an XML name (it starts with a letter or `_` and holds only letters, digits, `-`, `_` and `.`), for a
data set whose name or text value holds a control character, for a data set name with white space at either end,
for a name longer than 255 characters or used twice, and past `variable.loadLibrary`'s caps (256 variables, 1,000
data sets, 8 MiB). Without `path` the reply is `{xml, variables, datasets, skipped, warning?}`;
with it, the file is written and the reply is `{path, variables, datasets, skipped, warning?}`.
refused. So are a variable or data set declared twice, a value for a variable the library doesn't declare, and a
value that doesn't fit its variable's kind.
`variable.saveLibrary {path?}` (the panel menu's Save Variable Library…) writes the document's variables and every
data set as a variable library in the layout `variable.loadLibrary` reads: a `variable` element with `varName` for
each variable, with the `trait` and `category` of its kind (`textcontent` and `&ns_flows;`, `visibility` and
`&ns_vars;`, `fileref` and `&ns_vars;`, `graphdata` and `&ns_graphs;`; neither for a variable of unknown kind), and
a `sampleDataSet` element with `dataSetName` for each data set, holding an element named after each variable it has
a value for. A text value is written with one `p` element per line, a visibility value as `true` or `false`, an
image value as its path (a path from the root of a Unix file system as a `file:///` URL), and a graph value as a
`data` element, with a blank category marked `type="string"`. Loading the file gives back the same variables with their kinds, data set names and values; graph
data comes back in the CSV form Graph Data writes. Saving is refused for a document without a variable, for a
variable whose name isn't an XML name (it starts with a letter or `_` and holds only letters, digits, `-`, `_` and
`.`; a variable of unknown kind has no values, so its name isn't checked), for a name or value that holds a control
character, for a name with white space at either end, for a name longer than 255 characters or used twice, for an
image value that isn't a file's absolute path, and past `variable.loadLibrary`'s caps (256 variables, 1,000 data
sets, 8 MiB). Without `path` the reply is `{xml, variables, datasets}`; with it, the file is written and the reply
is `{path, variables, datasets}`.
- Batch: `action.batch {commands, source?: folder|datasets, folder?, destination?: none|saveAndClose|folder,
destinationFolder?, overrideOpen?, overrideSave?, overrideExport?, includeSubdirs?, stopOnError?}` plays an
action on every file in a folder or every data set (the Actions panel menu's Batch…). Override Save and Override
+2 -2
View File
@@ -808,8 +808,8 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
- Variables: Import Data Sets… (`dataset.import`) reads a UTF-16 file without a byte-order mark, instead of refusing it, when at least half of its two-byte units hold a NUL byte; it uses the byte order that reads its line breaks.
- Graphs: the Graph Data window's Import Data reads a UTF-16 text file without a byte-order mark by the same rule as Import Data Sets…, instead of filling the cells with NUL characters. It reads a file cut short by one byte, or with an unpaired surrogate, as it reads one after a byte-order mark.
- Variables: Import Data Sets… (`dataset.import`) defines the variables a file's header names that the document lacks, unbound. `#Shown` defines a visibility variable, `@Photo` defines an image variable, and a header without a prefix defines a text variable. A header that is a variable's exact name keeps naming it, and any other `%` header (graph data files) is refused.
- Variables: Load Variable Library… in the Variables panel menu (`variable.loadLibrary`) replaces the document's variables and data sets with a variable library's, read from its XML file, in one undo step: every data set is deleted, and every variable is deleted with its bindings and values, except a text variable the library also declares, which stays bound so the library's data sets change its objects (#4136); then the library's other text variables are defined, unbound, and its data sets take the text of each value's `p` elements, one paragraph each. Variables of other kinds are left out with a warning that names their kinds.
- Variables: Save Variable Library… in the Variables panel menu (`variable.saveLibrary`) writes the document's text variables and data sets as a variable library's XML file, which Load Variable Library reads back with the same text variables, data set names and text values. Variables of other kinds are left out with a warning that names their kinds.
- Variables: Load Variable Library… in the Variables panel menu (`variable.loadLibrary`) replaces the document's variables and data sets with a variable library's, read from its XML file, in one undo step: every data set is deleted, and every variable is deleted with its bindings and values, except a variable the library also declares with the same kind, which stays bound so the library's data sets change its objects (#4136); then the library's other variables are defined, unbound: text, visibility, image (linked file) and graph variables, and variables without a known `trait` as unknown. Its data sets take text values from each value's `p` elements, one paragraph each, visibility values from `true` or `false`, image values from a file's absolute path or `file:` URL, and graph values from a `data` element of series names and rows.
- Variables: Save Variable Library… in the Variables panel menu (`variable.saveLibrary`) writes the document's variables of every kind and its data sets as a variable library's XML file, which Load Variable Library reads back with the same variables, kinds, data set names and values.
- JSON-lines control channel with real egui pointer and keyboard injection.
- Variables: a type object holds one text variable. `variable.bind` and Make Text Dynamic refuse a second one and name the text variable the object has; a visibility variable can still share the object, and a document saved with two text variables on one object opens with both.
- Synthetic input validates complete gestures before queue mutation: at most 256 drag steps, 16 clicks and 1,024 pending events; up to 64 control requests per frame, with later requests retained for the next frame (#1709).