mirror of
https://github.com/storytold/wordcraft.git
synced 2026-11-12 08:53:27 -06:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d13c2ed55 | ||
|
|
ebb6a3e747 |
@@ -273,6 +273,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm
|
||||
- 2026-11-03: Security: saving an embedded object (a native document's kept markup included) collects the relationship ids its markup uses in a set and checks them against the writable ones in one pass, instead of scanning every id collected so far for each attribute. Readiness unchanged.
|
||||
- 2026-11-03: Security: the renderer leaves out a drawing path reaching more than a million device pixels (64 times the largest canvas) or of no finite size, which the rasteriser would otherwise flatten into points by the billion before clipping it. Readiness unchanged.
|
||||
- 2026-11-03: Security: a picture pasted from the Wayland clipboard is read encoded under the 200 MB paste cap and refused from its header when it is too large, before anything decodes it; arboard decoded and converted it to RGBA with no limits first (as on Windows, #3623). Readiness unchanged.
|
||||
- 2026-11-03: Security: XLSX import copies a cell's shared string only once the cell is kept (within the text budget, columns and rows), instead of copying it for every referring cell before checking. Readiness unchanged.
|
||||
- 2026-11-03: Language packs: language-packs-2 is published and WordCraft pins its index: 75 languages, adding Danish, German (Germany, Austria, Switzerland), Esperanto, Estonian, Persian, Croatian, Hungarian, Norwegian (Bokmål, Nynorsk), Dutch (#4145, #2505) and Swedish (Sweden, Finland), which need craft-proof's flag-based compounding (storytold/craft-libs#497, pinned). English (Australia) is checked against SCOWL's en-AU list as well as en-GB's (storytold/craft-libs#496). Mongolian and Thai stay hidden. Readiness unchanged.
|
||||
- 2026-11-03: Language lists (CP4.3): a language installed from a Language pack (Bulgarian, say) can now be chosen. Set Proofing Language lists every built-in language and every installed or available pack's, each once and sorted by name; Review › Language and the status bar's menu add the installed packs' languages to the short list, with one way of working out the check mark, by tag. A pack's language is stored as a tag that finds the pack again (`sr-Latn-RS` is proofed by the Latin `sr-latn` pack, not the Cyrillic one; Valencian is Word's `ca-ES-valencia`). Every pack in language-packs-2 now has an English name (Belarusian used to show its own name, Беларуская). Readiness unchanged.
|
||||
- 2026-11-03: Language packs (CP4.3): on a fresh install (or after an upgrade, with the list cached for an older pin) the missing-pack bar still offers a document language that has no dictionary, "Turkish proofing isn't installed. Install": the person's click turns on downloading, fetches the list and installs the pack if it lists one (if not, the bar goes). With downloading already on, a missing or stale list is fetched once in the background. Choosing a language with only the caret counts before anything is typed, and the spelling context menu's heading (Possible spelling mistake) is in the interface language, not the text's. Closing the bar is remembered per document, per pack and, before the list is known, per language tag. Readiness unchanged.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use super::date::{DateKind, builtin_date, custom_date, iso_datetime, serial_date};
|
||||
use super::{
|
||||
BTreeMap, Ev, Grid, HashMap, MAX_CELLS, MAX_COLS, MAX_ROWS, MAX_SHARED, MAX_SHEETS, MAX_XFS, Package, TextBudget, attr, push_capped, walk,
|
||||
@@ -263,7 +265,7 @@ pub(super) fn xlsx_rows(pkg: &mut Package<'_>, path: &str) -> Result<Vec<Vec<Str
|
||||
row.resize(c.col + 1, String::new());
|
||||
}
|
||||
if let Some(slot) = row.get_mut(c.col) {
|
||||
*slot = text;
|
||||
*slot = text.into_owned();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@@ -276,12 +278,15 @@ pub(super) fn xlsx_rows(pkg: &mut Package<'_>, path: &str) -> Result<Vec<Vec<Str
|
||||
Ok(grid.rows)
|
||||
}
|
||||
|
||||
fn xlsx_value(c: &XCell, shared: &[String], formats: &[Option<DateKind>], date1904: bool) -> String {
|
||||
/// A cell's text: a shared string borrowed, so a cell the sheet then refuses (past the text
|
||||
/// budget, the columns or the rows) costs no copy of it.
|
||||
fn xlsx_value<'a>(c: &XCell, shared: &'a [String], formats: &[Option<DateKind>], date1904: bool) -> Cow<'a, str> {
|
||||
let v = c.value.trim();
|
||||
let kind = c.kind.trim();
|
||||
if kind.eq_ignore_ascii_case("s") {
|
||||
v.parse::<usize>().ok().and_then(|i| shared.get(i)).cloned().unwrap_or_default()
|
||||
} else if kind.eq_ignore_ascii_case("inlineStr") {
|
||||
return Cow::Borrowed(v.parse::<usize>().ok().and_then(|i| shared.get(i)).map_or("", String::as_str));
|
||||
}
|
||||
Cow::Owned(if kind.eq_ignore_ascii_case("inlineStr") {
|
||||
if c.inline.is_empty() { c.value.clone() } else { c.inline.clone() }
|
||||
} else if kind.eq_ignore_ascii_case("str") || kind.eq_ignore_ascii_case("e") {
|
||||
c.value.clone()
|
||||
@@ -292,12 +297,12 @@ fn xlsx_value(c: &XCell, shared: &[String], formats: &[Option<DateKind>], date19
|
||||
} else if v.is_empty() {
|
||||
c.inline.clone()
|
||||
} else {
|
||||
let Ok(x) = v.parse::<f64>() else { return v.to_string() };
|
||||
let Ok(x) = v.parse::<f64>() else { return Cow::Owned(v.to_string()) };
|
||||
match formats.get(c.style).copied().flatten() {
|
||||
Some(kind) => serial_date(x, date1904, kind).unwrap_or_else(|| number(x)),
|
||||
None => number(x),
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// A number as a spreadsheet shows it in General format: up to 15 significant digits, no
|
||||
|
||||
Reference in New Issue
Block a user