From 02b3940efd1c8224d43f0612392774b8c8d5615b Mon Sep 17 00:00:00 2001 From: Mex <44814932+MMexicann@users.noreply.github.com> Date: Tue, 20 Oct 2026 23:08:54 +0200 Subject: [PATCH 1/3] M8: honor explicit empty chart number-format sections Keep blank whole-format General fallback while hiding values selected by explicit empty sections. Pin section selection, signed zeros, semicolon boundaries and General controls with regressions. Contribution on behalf of @MMexicann. --- crates/model/src/numfmt.rs | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/crates/model/src/numfmt.rs b/crates/model/src/numfmt.rs index c3cf1713..4f865895 100644 --- a/crates/model/src/numfmt.rs +++ b/crates/model/src/numfmt.rs @@ -150,7 +150,7 @@ pub fn format(code: &str, v: f64, lang: Option<&str>) -> String { ([pos, ..], v) => (*pos, v.abs(), v < 0.0), ([], v) => ("General", v.abs(), v < 0.0), }; - if sec.trim().eq_ignore_ascii_case("general") || sec.trim().is_empty() { + if sec.trim().eq_ignore_ascii_case("general") || (secs.len() == 1 && sec.trim().is_empty()) { let s = general(v, dec); return if minus { format!("-{s}") } else { s }; } @@ -314,6 +314,36 @@ mod tests { assert_eq!(format("\"x\"0", 5.0, None), "x5"); } + #[test] + fn explicit_empty_sections_hide_their_values() { + for v in [3.0, -3.0, 0.0, -0.0] { + assert_eq!(format(";;;", v, None), "", "all sections empty: {v}"); + } + for (code, positive, negative, zero) in [ + (";0;0", "", "3", "0"), + ("0;;0", "3", "", "0"), + ("0;-0;", "3", "-3", ""), + (";0", "", "3", ""), + (r#"";"0;;"#, ";3", "", ""), + (r"\;0;;", ";3", "", ""), + ] { + assert_eq!(format(code, 3.0, None), positive, "positive: {code}"); + assert_eq!(format(code, -3.0, None), negative, "negative: {code}"); + assert_eq!(format(code, 0.0, None), zero, "zero: {code}"); + } + assert_eq!(format("0;-0;", -0.0, None), ""); + } + + #[test] + fn blank_whole_codes_and_general_keep_their_fallback() { + for code in ["", " \t", "General", " general "] { + assert_eq!(format(code, 2.5, None), "2.5", "{code:?}"); + assert_eq!(format(code, -2.5, None), "-2.5", "{code:?}"); + assert_eq!(format(code, 0.0, None), "0", "{code:?}"); + assert_eq!(format(code, 2.5, Some("de-DE")), "2,5", "{code:?}"); + } + } + #[test] fn scientific_formats() { assert_eq!(format("0.00E+00", 1234.0, None), "1.23E+03"); From 5e0a60b15ee02e62d78d2e715828b78bced1f7f1 Mon Sep 17 00:00:00 2001 From: Mex <44814932+MMexicann@users.noreply.github.com> Date: Tue, 20 Oct 2026 23:09:29 +0200 Subject: [PATCH 2/3] M8: record empty chart number-format section fix Record narrow formatter behavior and synthetic regression evidence without changing chart scores or readiness estimates. --- ROADMAP.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ROADMAP.md b/ROADMAP.md index 93bc931e..a8090f31 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,7 +2,7 @@ **Stage: alpha** · next: beta, ~20 points and ~120–210 h away -> **Last reviewed:** 2026-10-14 · **Last updated:** 2026-10-18 · **Change:** minor (native chart payloads stored in bounded ZIP members; previous: major, community PR wave 2026-10-14: ~60 landed items in the progress log, among them the Font, Paragraph, Photo Album, theme colour and font and Date and Time dialogs, presenter and show controls, the SmartArt Text Pane and PPTX corpus slices; breadth 84% after `cargo xtask parity`, ready stays ~55%, stage stays alpha; duplicated rows and headers folded; previous: minor, hours to ~95% per audience added) · **Target:** Microsoft PowerPoint for Mac 16.113 (Microsoft 365) +> **Last reviewed:** 2026-10-14 · **Last updated:** 2026-10-20 · **Change:** trivial (empty chart number-format sections hide values; previous: minor, native chart payloads stored in bounded ZIP members; previous: major, community PR wave 2026-10-14: ~60 landed items in the progress log, among them the Font, Paragraph, Photo Album, theme colour and font and Date and Time dialogs, presenter and show controls, the SmartArt Text Pane and PPTX corpus slices; breadth 84% after `cargo xtask parity`, ready stays ~55%, stage stays alpha; duplicated rows and headers folded; previous: minor, hours to ~95% per audience added) · **Target:** Microsoft PowerPoint for Mac 16.113 (Microsoft 365) DeckCraft aims at full PowerPoint parity, and to be better: faster, open (a documented zip+JSON format plus PPTX), scriptable by agents (CLI, JSON control channel, MCP), and available everywhere @@ -131,6 +131,7 @@ app's JSON control channel (`deckcraft --control PORT`). | Date | What landed | |---|---| +| 2026-10-20 | Chart number formats with explicit empty positive, negative or zero sections hide the corresponding labels, including all values with three semicolons; a blank whole format still uses General. Synthetic formatter regressions | | 2026-10-18 | Native chart sidecar bytes move from JSON arrays into referenced ZIP entries, with shared media byte/item limits and bounded reads; older inline sidecars still load. Synthetic format regressions cover large workbooks and malformed members | | 2026-10-17 | Opening a file caps absurd effect sizes (glow, soft edges, shadows, reflections, on shapes, text and table text) at what Format Shape allows: a glow of 10^18 pt in a .pptx made rendering ask for 34 GB and abort | | 2026-10-17 | Opening a .deckcraft file whose shapes repeat an id gives the repeats fresh ids (groups, layouts and masters too), so the deck validates and edits by id find one shape | @@ -239,6 +240,7 @@ app's JSON control channel (`deckcraft --control PORT`). | Date | Change | Summary | |---|---|---| +| 2026-10-20 | trivial | Explicit empty chart number-format sections hide their values; blank whole-code General fallback is retained. Synthetic formatter regressions; chart-element scores and readiness estimates unchanged | | 2026-10-18 | minor | Native chart payloads use referenced ZIP members and share media byte/item limits; old inline sidecars remain readable. Synthetic tests cover multi-megabyte layout, all shape owners, shared budgets, missing/corrupt members and invalid references. Scores and milestone scope unchanged | | 2026-10-15 | trivial | Progress log: chart package parts survive a native save. Scores and milestone names unchanged | | 2026-10-15 | trivial | Progress log: PPTX trigger click-step round trip. Feature scores and milestone names unchanged | From 6b91132ce70141f4a7a5ec6e229f101022b7acea Mon Sep 17 00:00:00 2001 From: Mex <44814932+MMexicann@users.noreply.github.com> Date: Tue, 20 Oct 2026 23:10:09 +0200 Subject: [PATCH 3/3] M8: document verified empty-format reliability scope Record the synthetic formatter regression and preserved General fallback; broader chart gaps and readiness scores remain unchanged. --- docs/gaps.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/gaps.md b/docs/gaps.md index 57271c4e..8e7c20de 100644 --- a/docs/gaps.md +++ b/docs/gaps.md @@ -1,6 +1,6 @@ # Where DeckCraft falls short of PowerPoint -> **Last reviewed:** 2026-10-14 · **Last updated:** 2026-10-18 · **Change:** minor (native chart payloads stored in bounded ZIP members; previous: major, community PR wave 2026-10-14: soak tests, PPTX corpus, comment threads (#70), embedded fonts, SmartArt Text Pane, Animation Pane timeline, Hunspell spelling, thesaurus, AutoCorrect, 14 new dialogs, pen pressure and trackpad gestures; duplicated entries and headers folded; previous: minor, 3-D bevel, camera and face lighting rendered) · **Target:** Microsoft PowerPoint for Mac 16.113 (Microsoft 365) +> **Last reviewed:** 2026-10-14 · **Last updated:** 2026-10-20 · **Change:** trivial (empty chart number-format sections hide values; previous: minor, native chart payloads stored in bounded ZIP members; previous: major, community PR wave 2026-10-14: soak tests, PPTX corpus, comment threads (#70), embedded fonts, SmartArt Text Pane, Animation Pane timeline, Hunspell spelling, thesaurus, AutoCorrect, 14 new dialogs, pen pressure and trackpad gestures; duplicated entries and headers folded; previous: minor, 3-D bevel, camera and face lighting rendered) · **Target:** Microsoft PowerPoint for Mac 16.113 (Microsoft 365) Every known shortfall, one entry each, ranked by how much it stops someone who presents with PowerPoint from switching. This is the work list: pick from the top. Numbers are summarized in @@ -13,6 +13,8 @@ tests (calibration in [target-app-parity.md](target-app-parity.md#calibration-ho When a gap closes, delete its entry, update the parity doc it points to, and add a line to the revision history. +Chart number-format reliability: explicit empty sections now hide the corresponding numeric labels, including all values with three semicolons. Blank whole-code General fallback remains. Synthetic formatter regressions cover section selection and quoted/escaped semicolons; broader chart-element gaps and readiness estimates below are unchanged. + ## Ranked: the top 15 | # | Gap | Category | Beta | Hours | Doc | @@ -356,6 +358,7 @@ Detail in [localization-parity.md](localization-parity.md). | Date | Change | Summary | |---|---|---| +| 2026-10-20 | trivial | Explicit empty chart number-format sections hide their values; blank whole-code General fallback is retained. Synthetic formatter regressions; chart-element scores and readiness estimates unchanged | | 2026-10-18 | minor | Native chart payloads use referenced ZIP members and share media byte/item limits; old inline sidecars remain readable. Synthetic tests cover multi-megabyte layout, all shape owners, shared budgets, missing/corrupt members and invalid references. Scores and milestone scope unchanged | | 2026-10-15 | trivial | Native saves retain chart package parts and relationships, including charts in groups; edited chart data still does not export a stale source workbook. Chart editing gaps and scores remain unchanged | | 2026-10-15 | trivial | PPTX trigger sequences keep later On Click steps instead of converting them to After Previous; mixed starts, independent buttons and paragraph builds have synthetic round-trip regressions |