diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2c4b8cb1a4..f92b4ccfed 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,11 +7,30 @@ updates: interval: "daily" time: "06:00" timezone: "America/New_York" - # Consolidate updates into a single PR rather than one PR per crate + # Minor and patch updates share one PR. A breaking bump gets its own PR so one API change + # doesn't hold the safe updates back (#2973). For cargo, Dependabot counts a 0.y bump of a + # 0.x crate as major, as Cargo does. A dependency goes to the first group it matches, so the + # crate families that must move together come before the catch-all. groups: + egui: + patterns: + - "egui" + - "egui_*" + - "eframe" + - "winit" + fonts: + patterns: + - "skrifa" + - "harfrust" + hayro: + patterns: + - "hayro-*" cargo-dependencies: patterns: - "*" + update-types: + - "minor" + - "patch" commit-message: prefix: "chore(deps)" diff --git a/Cargo.lock b/Cargo.lock index 666b2a033f..e46eb7356f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1157,6 +1157,15 @@ dependencies = [ "zip 9.1.0", ] +[[package]] +name = "craft-web-host" +version = "0.1.0" +source = "git+https://github.com/storytold/craft-libs?rev=2e2312ddaf21bc3d85cd3395d0955c7d239306f6#2e2312ddaf21bc3d85cd3395d0955c7d239306f6" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + [[package]] name = "craft-window" version = "0.1.0" @@ -6815,6 +6824,7 @@ dependencies = [ "wordcraft-engine", "wordcraft-fonts", "wordcraft-ui-egui", + "x11rb", "zbus", ] @@ -6880,6 +6890,7 @@ dependencies = [ "log", "proptest", "quick-xml 0.41.0", + "serde_json", "sha1 0.11.0", "sha2 0.11.1", "thiserror 2.0.21", @@ -7084,6 +7095,7 @@ dependencies = [ name = "wordcraft-web" version = "0.15.1" dependencies = [ + "craft-web-host", "eframe", "egui", "js-sys", diff --git a/README.md b/README.md index 1b1bcc2ede..ba5081af35 100644 --- a/README.md +++ b/README.md @@ -299,10 +299,21 @@ adapter. The log file records the choice (lines starting with RISC-V (riscv64): `wordcraft--linux-riscv64.tar.gz`, a tarball cross-compiled for glibc 2.39+ (Ubuntu 24.04, Debian 13 and newer). +**Read Aloud** (Review › Read Aloud) speaks through a speech program installed on the system: it +tries `espeak-ng`, then `espeak`, and when neither is installed it talks to Speech Dispatcher. +The `.rpm` package recommends `espeak-ng`; the `.deb` recommends `espeak-ng` or +`speech-dispatcher`, so the package manager installs one of the two by default. With the +AppImage or the tarball, install one yourself if neither is there (`sudo apt install espeak-ng`, +`sudo dnf install espeak-ng`, `sudo pacman -S espeak-ng`). The Flatpak doesn't speak yet: it has +no audio access and doesn't include `espeak-ng`, `espeak` or Speech Dispatcher. + **Wayland:** on a Wayland desktop the app runs through XWayland when it is available, because winit (the windowing library) supports dragging files into the window only on X11. To use the native Wayland backend instead (for example for sharper text with fractional scaling, at the cost -of file drag-and-drop), start it with `WORDCRAFT_WAYLAND=1`: +of file drag-and-drop), choose **File › Options › Advanced › Linux display server › Wayland**; it +applies the next time WordCraft starts, and **X11 (XWayland)** or **Automatic** switches back. The +`WORDCRAFT_WAYLAND` environment variable overrides the setting: `1` for native Wayland, `0` for +XWayland: ```sh WORDCRAFT_WAYLAND=1 wordcraft diff --git a/ROADMAP.md b/ROADMAP.md index 60eceed19c..56db05d1c6 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -4,8 +4,9 @@ **Stage: alpha** · next: beta, ~15 points (60% → 75% ready for real work) and ~150–230 h away -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-04 · **Change:** trivial (Control/MCP #2596 review: partial-write outcomes, path-bearing image exports, accept-thread startup cleanup and malformed UTF-8 handling); previously trivial (progress log: ODT display settings removed); previously trivial (progress log: dialogs are modal except the five Word keeps modeless, and a press beside one shakes it, #3859); previously trivial (progress log: picture brightness, contrast and transparency, ODT element audit, ODT checked against 220 files from other applications, ODT display styles); previously trivial (progress log: the dialogs of the mirrored Arabic interface read right to left: label-and-field rows, tables (list columns, the Models table), tile galleries and the Add/Remove arrows follow the reading direction, through one `rtl::Table` helper that draws exactly as before in English; no ranked gap closed, readiness estimates unchanged); previously trivial (progress log: fonts that aren't installed are flagged in the font box and status bar); previously trivial (progress log: ODT sections inside text boxes); previously trivial (progress log: ODT definitions sharing a name, sections around tables, stacking order); previously trivial (progress log: ODT forms and indexes written as read); previously trivial (progress log: ODT table styles saved, WordCraft-origin documents checked in LibreOffice); previously trivial (progress log: ODT interpretation profile); previously trivial (progress log: ODT controls, custom shapes, in-line placement); previously trivial (progress log: ODT charts kept, frame outlines, header height); previously trivial (progress log: ODT header rows); previously trivial (progress log: ODT layout setting, padding, columns); previously trivial (progress log: ODT tables, header spacing, picture paragraphs); previously trivial (progress log: ODT round trips keep their page count); previously trivial (progress log: emphasis marks, SET fields, ODT page backgrounds and tables); previously trivial (progress log: ODT checked against LibreOffice's templates); previously trivial (progress log: ODT at ~90%); previously trivial (progress log: ODT read and written nearly whole); previously trivial (progress log: ODT text boxes); previously trivial (progress log: ODT layout settings); previously trivial (progress log: ODT character styles); previously trivial (progress log: ODT custom styles); previously trivial (progress log: ODT equations saved); previously trivial (progress log: ODT floating pictures); previously trivial (progress log: ODT paragraph borders); previously trivial (progress log: ODT heading numbering); previously trivial (progress log: ODT table borders); previously trivial (progress log: ODT heading styles); previously trivial (progress log: ODT tab stops); previously trivial (progress log: ODT character formatting); previously trivial (progress log: ODT lists); previously trivial (progress log: ODT comments); previously trivial (progress log: ODT footnotes and endnotes); previously trivial (progress log: ODT headers, footers and fields); previously trivial (progress log: ODT paragraph spacing); previously trivial (progress log: Options › Language redesign, CP4.3); previously trivial (progress log: the missing-pack bar on a fresh install, the caret's typing language, and the spelling menu heading in the interface language, CP4.3); previously trivial (progress log: Language pack languages in every language list, CP4.3); previously trivial (progress log: craft-proof pin, French elision and Valencian, CP4.3); previously trivial (progress log: a long comment's card and balloon stop at ten lines, #3382); previously trivial (progress log: a pasted text box story is charged for the formatting it copies); previously trivial (progress log: a .doc table row keeps one override per cell); previously trivial (progress log: a .doc file's sections find their paragraphs by index); previously minor (Arabic interface language with mirrored UI, #1195); previously trivial (progress log: Replace and Remove Table of Contents with Word's title above a section break, #4041); previously trivial (progress log: a password-protected file named on the command line asks for its password after the startup document is replaced, #5299); previously trivial (progress log: language-packs-2 published and pinned, 75 Language packs); previously trivial (progress log: language-packs-1 published and pinned, CP4.4); previously trivial (progress log: Language packs, CP4);; previously trivial (DOCX table rows and cells inside selected alternate-content branches survive open and repeated saves (#5219); broader corpus qualification and readiness estimates unchanged); previously trivial (progress log: a list inside a Markdown block quote stays quoted); previously trivial (progress log: arrowheads keep their kind, width and length and are drawn at Word's sizes); previously trivial (progress log: the line between columns for selected text, #5178); previously trivial (progress log: .doc standard font, #5066); previously trivial (progress log: a table row doesn't split off a picture that doesn't fit, #4272); previously trivial (progress log: a middle or bottom cell of a row split across pages lines up on the first page); previously trivial (progress log: tab leader dots spaced and placed as in Word); previously trivial (progress log: a list level above counts its first number at the first deeper item); previously trivial (progress log: paragraph side borders lie outside the text, #5036); previously trivial (progress log: a paragraph naming an undefined style is formatted as Normal, #5077); previously trivial (progress log: TOC page numbers as PAGEREF fields, #5097); previously trivial (progress log: Backstage keytips, #4960); previously trivial (Progress log: only the printer's PDF leaves out links; Save these pages as PDF keeps them, #4734); previously trivial (progress log: Chinese and Japanese text counts a word per character, #4547; previously trivial: aligned-copy review fixes retain the document axis through scrolling and include secondary selections (#4764)); previously trivial (connector rerouting indexes laid-out object positions once per batch (#3631); previously trivial (progress log: corporate authors in bibliographies, #4848); previously trivial (custom-property bookmark-link preservation, #4767); previously trivial (progress log: Table Properties follows the selection, #4857); previously trivial (Relative font-size commands preserve mixed sizes in the selection (#4903); existing button steps and one-point shortcuts are unchanged; readiness estimates unchanged); previously trivial (Arabic Backspace removes one combining mark and keeps its base letter (#4757); previously trivial (note conversion walks reference offsets and formatting runs together, #4750); previously trivial (DOCX comment-ID save lookups); previously trivial (progress log: RTF pictures stored as Windows or Enhanced Metafiles are imported, #4259); previously trivial (#4658 bounds nested Markdown reference-label work); previously trivial (HTML import keeps preformatted lines with CR or CRLF input newlines, #4810); previously trivial (progress log: Insert › Shapes icon grid, #4349); previously trivial (progress log: AutoCorrect Options with no document open, #4585); previously trivial (progress log: window fallback geometry and equation symbol tooltips); previously trivial (progress log: window titles omit NUL characters, #3634); previously trivial (Recipient labels continue across product-sized sheets instead of stopping after the first sheet (#4880)); previously trivial (progress log: Custom document properties dialog, #2982; previously trivial: progress log: View › New Window; previously trivial: progress log: interface translations come from storytold/craft-i18n through the `craft-i18n` crate; previously trivial: progress log: disabled-control reasons translated in every interface language, #2678; previously trivial: progress log: mail merge record navigation and record ranges for printing, #3028; previously trivial: selection bar for right-to-left paragraphs and table rows; previously trivial: group connector rerouting preserves rotated and flipped free or unresolved endpoints under nonuniform group scaling; readiness estimates unchanged; previously trivial: progress log: a word with no break opportunity in it no longer makes the layout quadratic, #3412; previously trivial: progress log: a relationship the markup names without the prefix is read as it wrote, and an ordinary `id` names no part; previously trivial: progress log: a document with many relationships opens in the time its part takes, and an id the text only mentions is not a reference, #3411; previously trivial: progress log: read only and comments-only protection grey out edits; previously trivial: progress log: an empty paragraph with a hidden mark shows nothing, not even its list number, #3982; previously trivial: progress log: "NaN" in the Font dialog's Size box no longer closes the app, #3663; previously trivial: progress log: a table cell span from a `.json` file no longer overflows, #3637; previously trivial: progress log: a click in the footer while editing the header moves there; previously trivial: explicit documents keep the editor when recovery discovery finishes; readable recovery controls; previously trivial: Slovenian interface catalog, 2,614 entries; previously trivial: Insert Table of Figures dialog for any caption label, #3013; previously trivial: progress log: Home › Underline drop-down, #2738; previously trivial: personal templates in File › New and Save as Word Template, #2852; previously trivial: progress log: the scrollbar page tip stays on one line, #3341; previously trivial: progress log: forms protection greys out the control buttons; previously trivial: progress log: a document with many content controls saves in the time the controls take, #13; previously trivial: progress log: Word signature lines kept on save; previously trivial: a Thai run with Latin finds one installed font covering it all on Linux too, #1549; previously trivial: progress log: closing the header returns to the body selection, #3331; previously trivial: progress log: saving to a NAS share mounted by GVFS, #3003; previously trivial: progress log: a picture dragged near the bottom of a page lands there, #3169; previously trivial: centred list labels after leading page breaks, #2964; previously trivial: progress log: inline pictures drag to an insertion cursor and stay inline, #2233, #2234; previously trivial: progress log: a text file saved over itself closes without asking, #2376; previously trivial: progress log: a text frame in the paragraph defaults frames nothing, #2360; previously trivial: fixed font inputs in four layout controls; previously trivial: typing no longer starts render threads on every repaint, #3027; previously trivial: a right, centre or decimal tab whose text doesn't fit, or a left tab past the right indent, goes to the next line with its text, #1840; previously trivial: progress log: banded rows shade as in Word, #3415; previously trivial: progress log: the table handles show while the caret is in the table, #2428; previously trivial: progress log: a click below a floating table reaches the text after it, #2038; previously trivial: progress log: Delete on selected table cells leaves one empty paragraph in each, #2802; previously trivial: progress log: lam-alef in exported PDFs extracts whole with fonts that draw it as two glyphs, #2310; previously trivial: Bullets and Numbering toggle off style-inherited lists at their effective level, including basedOn chains and numbered ListParagraph styles; other paragraphs and list definitions stay unchanged (related to #3459); previously trivial: Russian sorting keeps ё with е and recognises decomposed ё/й; previously trivial: progress log: a text box that keeps the keyboard no longer resets the input method every frame, #2986; previously trivial: progress log: recovery copies and .json files store pictures as base64, #586 follow-up; previously trivial: progress log: legacy menu keys, #1697; previously trivial: progress log: shape gradients and transparency, #1500; previously trivial: progress log: Focus fills the screen, and Full Screen View shows the pages alone, #1678; previously trivial: progress log: text above a float's anchor wraps around it, #2048; previously trivial: progress log: File › Recover follows the app theme, #3243; previously trivial: progress log: formatting toolbar with the text context menu, #2959; previously trivial: progress log: caret inside ligatures, #1974; previously trivial: text typed into a content control takes the control's formatting; localized placeholder styles recognised; previously trivial: forms protection keeps its content controls: no inserting, Properties or Remove Content Control; previously trivial: long navigation headings wrap onto further lines within the pane, #3015; previously trivial: clearing a no-match font query keeps the recent heading visible, #2068; previously trivial: a word after a slash wraps whole, like Word, #2963; previously trivial: progress log: a header-cell picture watermark sits behind the text, #1775; previously trivial: symbols keep their font when the text font changes, #2036; previously trivial: opening a DOCX no longer copies its pictures; previously trivial: Add Font imports every selected font file, #1789); previously trivial (RTF export writes sections (gap 19); previously trivial: ODT export writes sections (gap 19); previously trivial: Read Aloud speaks each sentence in its own language, #1843; previously trivial: hint-reliant CJK outlines; previously trivial: Ctrl+wheel zoom no longer scrolls the document, #1743; previously trivial: progress log: Turkish case mapping in AutoCorrect, #1923; previously trivial: a mouse drag on a table leaves the view where it is, #1738; previously trivial: progress log: Hebrew field results and smart quotes, #1670; previously trivial: Backspace removes a selected table, rows or columns, #1844; previously trivial: progress log: mixed Hebrew/Latin text keeps its order in Word, #1543; previously trivial: progress log: web typing in non-Latin text no longer repeats, #1480; previously trivial: progress log: font family caches bounded and math font lookups follow font changes, #1354; previously trivial: `-->` AutoCorrect replacement, #2223; previously trivial: numbered headings, #1793; previously trivial: Navigation Find exposes Results, #2096; previously trivial: progress log: Columns on selected text, #2024; previously trivial: progress log: legacy outline, shadow, emboss and imprint text effects drawn, #2534; previously trivial: progress log: Indonesian proofing, #498; previously trivial: progress log: DOCX glossary documents (building blocks); previously trivial: progress log: Read Mode keeps the keyboard and shows whole, unobscured columns, #1772); previously trivial: progress log: font list entries of tall-ascent fonts no longer cut off, #2570); previously trivial: progress log: Split Cells and Convert Text to Table dialogs follow the Word check, #2592; previously trivial: a new source's Tag is made like Word's, three letters of the author and two digits of the year with a number added when taken, and an edit keeps the Tag, #2094; previously trivial: Web Layout fills the window width, #1876; previously trivial: progress log: Different First Page headers reachable from page 1, #2826; previously trivial: Language dialog keeps inherited proofing language and no-proof choices (#2717); previously trivial: progress log: web preferences kept between visits, #2132; previously trivial: progress log: undrawable private-use list bullets show the level's default bullet, #1683; previously trivial: progress log: `w:eastAsianLayout` kept on save; previously trivial: table style editor formats every part, #714); previously trivial: VML freeforms read and kept on save; previously trivial: progress log: consistent preferred cell widths; previously trivial: multi-paragraph field instructions no longer add blank lines; previously trivial: page-break-only list paragraphs hide their labels; previously trivial: progress log: grouped `flowChartOr` shapes draw their circle and crossing spokes; previously trivial: progress log: copies keep their formatting in other programs, #1523; previously trivial: progress log: privacy options on save, #1062; previously trivial: progress log: equation pictures in theme colours on Windows, #1002; previously trivial: symbol fonts, #776; previously trivial: the save prompt answers from the keyboard, #861; previously trivial: table column and row markers on the rulers, #700; previously trivial: table borders and the resize handle drag on the page, #217; previously trivial: formatting revisions landed, #41; previously trivial: Draw tab ink, #307, and Draw Table and Eraser, #303, landed: catalog 402/434; previously minor: readiness table with hours per audience; full number back to the additive weighted sum, 60%; mainstream and essentials numbers added; alpha gate checked; previously major: full re-measure against Word for Mac 16.113.4; progress docs restructured) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4 +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-05 · **Change:** trivial (Control/MCP #2596 review: partial-write outcomes, path-bearing image exports, accept-thread startup cleanup and malformed UTF-8 handling); previously trivial (progress log: the status bar's count can be words, characters or characters without spaces, #2797); previously trivial (Linux display server setting in File › Options › Advanced, #2184); previously trivial (progress log: Linux Read Aloud through Speech Dispatcher, #4576); previously trivial (progress log: a click just outside a floating table by turned cell text, #4181; previously minor: progress log: Spanish proofing, #3360, #3553; previously trivial: progress log: Insert › Table's grid previews the hovered table on the page, #3931; previously trivial: progress log: interface translations come from storytold/craft-i18n through the `craft-i18n` crate; previously trivial: progress log: disabled-control reasons translated in every interface language, #2678; previously trivial: progress log: mail merge record navigation and record ranges for printing, #3028; previously trivial: selection bar for right-to-left paragraphs and table rows; previously trivial: group connector rerouting preserves rotated and flipped free or unresolved endpoints under nonuniform group scaling; readiness estimates unchanged; previously trivial: progress log: a word with no break opportunity in it no longer makes the layout quadratic, #3412; previously trivial: progress log: a relationship the markup names without the prefix is read as it wrote, and an ordinary `id` names no part; previously trivial: progress log: a document with many relationships opens in the time its part takes, and an id the text only mentions is not a reference, #3411; previously trivial: progress log: read only and comments-only protection grey out edits; previously trivial: progress log: an empty paragraph with a hidden mark shows nothing, not even its list number, #3982; previously trivial: progress log: "NaN" in the Font dialog's Size box no longer closes the app, #3663; previously trivial: progress log: a table cell span from a `.json` file no longer overflows, #3637; previously trivial: progress log: a click in the footer while editing the header moves there; previously trivial: explicit documents keep the editor when recovery discovery finishes; readable recovery controls; previously trivial: Slovenian interface catalog, 2,614 entries; previously trivial: Insert Table of Figures dialog for any caption label, #3013; previously trivial: progress log: Home › Underline drop-down, #2738; previously trivial: personal templates in File › New and Save as Word Template, #2852; previously trivial: progress log: the scrollbar page tip stays on one line, #3341; previously trivial: progress log: forms protection greys out the control buttons; previously trivial: progress log: a document with many content controls saves in the time the controls take, #13; previously trivial: progress log: Word signature lines kept on save; previously trivial: a Thai run with Latin finds one installed font covering it all on Linux too, #1549; previously trivial: progress log: closing the header returns to the body selection, #3331; previously trivial: progress log: saving to a NAS share mounted by GVFS, #3003; previously trivial: progress log: a picture dragged near the bottom of a page lands there, #3169; previously trivial: centred list labels after leading page breaks, #2964; previously trivial: progress log: inline pictures drag to an insertion cursor and stay inline, #2233, #2234; previously trivial: progress log: a text file saved over itself closes without asking, #2376; previously trivial: progress log: a text frame in the paragraph defaults frames nothing, #2360; previously trivial: fixed font inputs in four layout controls; previously trivial: typing no longer starts render threads on every repaint, #3027; previously trivial: a right, centre or decimal tab whose text doesn't fit, or a left tab past the right indent, goes to the next line with its text, #1840; previously trivial: progress log: banded rows shade as in Word, #3415; previously trivial: progress log: the table handles show while the caret is in the table, #2428; previously trivial: progress log: a click below a floating table reaches the text after it, #2038; previously trivial: progress log: Delete on selected table cells leaves one empty paragraph in each, #2802; previously trivial: progress log: lam-alef in exported PDFs extracts whole with fonts that draw it as two glyphs, #2310; previously trivial: Bullets and Numbering toggle off style-inherited lists at their effective level, including basedOn chains and numbered ListParagraph styles; other paragraphs and list definitions stay unchanged (related to #3459); previously trivial (progress log: MHT quoted MIME parameters); previously trivial (progress log: CLI convert format options); previously trivial (MATH construction reuse, #3630); previously trivial (DOCX `w:adjustRightInd` is preserved through style resolution and ordered DOCX saves); previously trivial (per-page ink object lookups, #3614); previously trivial (progress log: ODT display settings removed); previously trivial (progress log: dialogs are modal except the five Word keeps modeless, and a press beside one shakes it, #3859); previously trivial (progress log: picture brightness, contrast and transparency, ODT element audit, ODT checked against 220 files from other applications, ODT display styles); previously trivial (progress log: the dialogs of the mirrored Arabic interface read right to left: label-and-field rows, tables (list columns, the Models table), tile galleries and the Add/Remove arrows follow the reading direction, through one `rtl::Table` helper that draws exactly as before in English; no ranked gap closed, readiness estimates unchanged); previously trivial (progress log: fonts that aren't installed are flagged in the font box and status bar); previously trivial (progress log: ODT sections inside text boxes); previously trivial (progress log: ODT definitions sharing a name, sections around tables, stacking order); previously trivial (progress log: ODT forms and indexes written as read); previously trivial (progress log: ODT table styles saved, WordCraft-origin documents checked in LibreOffice); previously trivial (progress log: ODT interpretation profile); previously trivial (progress log: ODT controls, custom shapes, in-line placement); previously trivial (progress log: ODT charts kept, frame outlines, header height); previously trivial (progress log: ODT header rows); previously trivial (progress log: ODT layout setting, padding, columns); previously trivial (progress log: ODT tables, header spacing, picture paragraphs); previously trivial (progress log: ODT round trips keep their page count); previously trivial (progress log: emphasis marks, SET fields, ODT page backgrounds and tables); previously trivial (progress log: ODT checked against LibreOffice's templates); previously trivial (progress log: ODT at ~90%); previously trivial (progress log: ODT read and written nearly whole); previously trivial (progress log: ODT text boxes); previously trivial (progress log: ODT layout settings); previously trivial (progress log: ODT character styles); previously trivial (progress log: ODT custom styles); previously trivial (progress log: ODT equations saved); previously trivial (progress log: ODT floating pictures); previously trivial (progress log: ODT paragraph borders); previously trivial (progress log: ODT heading numbering); previously trivial (progress log: ODT table borders); previously trivial (progress log: ODT heading styles); previously trivial (progress log: ODT tab stops); previously trivial (progress log: ODT character formatting); previously trivial (progress log: ODT lists); previously trivial (progress log: ODT comments); previously trivial (progress log: ODT footnotes and endnotes); previously trivial (progress log: ODT headers, footers and fields); previously trivial (progress log: ODT paragraph spacing); previously trivial (progress log: Options › Language redesign, CP4.3); previously trivial (progress log: the missing-pack bar on a fresh install, the caret's typing language, and the spelling menu heading in the interface language, CP4.3); previously trivial (progress log: Language pack languages in every language list, CP4.3); previously trivial (progress log: craft-proof pin, French elision and Valencian, CP4.3); previously trivial (progress log: a long comment's card and balloon stop at ten lines, #3382); previously trivial (progress log: a pasted text box story is charged for the formatting it copies); previously trivial (progress log: a .doc table row keeps one override per cell); previously trivial (progress log: a .doc file's sections find their paragraphs by index); previously minor (Arabic interface language with mirrored UI, #1195); previously trivial (progress log: Replace and Remove Table of Contents with Word's title above a section break, #4041); previously trivial (progress log: a password-protected file named on the command line asks for its password after the startup document is replaced, #5299); previously trivial (progress log: language-packs-2 published and pinned, 75 Language packs); previously trivial (progress log: language-packs-1 published and pinned, CP4.4); previously trivial (progress log: Language packs, CP4);; previously trivial (DOCX table rows and cells inside selected alternate-content branches survive open and repeated saves (#5219); broader corpus qualification and readiness estimates unchanged); previously trivial (progress log: a list inside a Markdown block quote stays quoted); previously trivial (progress log: arrowheads keep their kind, width and length and are drawn at Word's sizes); previously trivial (progress log: the line between columns for selected text, #5178); previously trivial (progress log: .doc standard font, #5066); previously trivial (progress log: a table row doesn't split off a picture that doesn't fit, #4272); previously trivial (progress log: a middle or bottom cell of a row split across pages lines up on the first page); previously trivial (progress log: tab leader dots spaced and placed as in Word); previously trivial (progress log: a list level above counts its first number at the first deeper item); previously trivial (progress log: paragraph side borders lie outside the text, #5036); previously trivial (progress log: a paragraph naming an undefined style is formatted as Normal, #5077); previously trivial (progress log: TOC page numbers as PAGEREF fields, #5097); previously trivial (progress log: Backstage keytips, #4960); previously trivial (Progress log: only the printer's PDF leaves out links; Save these pages as PDF keeps them, #4734); previously trivial (progress log: Chinese and Japanese text counts a word per character, #4547; previously trivial: aligned-copy review fixes retain the document axis through scrolling and include secondary selections (#4764)); previously trivial (connector rerouting indexes laid-out object positions once per batch (#3631); previously trivial (progress log: corporate authors in bibliographies, #4848); previously trivial (custom-property bookmark-link preservation, #4767); previously trivial (progress log: Table Properties follows the selection, #4857); previously trivial (Relative font-size commands preserve mixed sizes in the selection (#4903); existing button steps and one-point shortcuts are unchanged; readiness estimates unchanged); previously trivial (Arabic Backspace removes one combining mark and keeps its base letter (#4757); previously trivial (note conversion walks reference offsets and formatting runs together, #4750); previously trivial (DOCX comment-ID save lookups); previously trivial (progress log: RTF pictures stored as Windows or Enhanced Metafiles are imported, #4259); previously trivial (#4658 bounds nested Markdown reference-label work); previously trivial (HTML import keeps preformatted lines with CR or CRLF input newlines, #4810); previously trivial (progress log: Insert › Shapes icon grid, #4349); previously trivial (progress log: AutoCorrect Options with no document open, #4585); previously trivial (progress log: window fallback geometry and equation symbol tooltips); previously trivial (progress log: window titles omit NUL characters, #3634); previously trivial (Recipient labels continue across product-sized sheets instead of stopping after the first sheet (#4880)); previously trivial (progress log: Custom document properties dialog, #2982; previously trivial: progress log: View › New Window; previously trivial: progress log: interface translations come from storytold/craft-i18n through the `craft-i18n` crate; previously trivial: progress log: disabled-control reasons translated in every interface language, #2678; previously trivial: progress log: mail merge record navigation and record ranges for printing, #3028; previously trivial: selection bar for right-to-left paragraphs and table rows; previously trivial: group connector rerouting preserves rotated and flipped free or unresolved endpoints under nonuniform group scaling; readiness estimates unchanged; previously trivial: progress log: a word with no break opportunity in it no longer makes the layout quadratic, #3412; previously trivial: progress log: a relationship the markup names without the prefix is read as it wrote, and an ordinary `id` names no part; previously trivial: progress log: a document with many relationships opens in the time its part takes, and an id the text only mentions is not a reference, #3411; previously trivial: progress log: read only and comments-only protection grey out edits; previously trivial: progress log: an empty paragraph with a hidden mark shows nothing, not even its list number, #3982; previously trivial: progress log: "NaN" in the Font dialog's Size box no longer closes the app, #3663; previously trivial: progress log: a table cell span from a `.json` file no longer overflows, #3637; previously trivial: progress log: a click in the footer while editing the header moves there; previously trivial: explicit documents keep the editor when recovery discovery finishes; readable recovery controls; previously trivial: Slovenian interface catalog, 2,614 entries; previously trivial: Insert Table of Figures dialog for any caption label, #3013; previously trivial: progress log: Home › Underline drop-down, #2738; previously trivial: personal templates in File › New and Save as Word Template, #2852; previously trivial: progress log: the scrollbar page tip stays on one line, #3341; previously trivial: progress log: forms protection greys out the control buttons; previously trivial: progress log: a document with many content controls saves in the time the controls take, #13; previously trivial: progress log: Word signature lines kept on save; previously trivial: a Thai run with Latin finds one installed font covering it all on Linux too, #1549; previously trivial: progress log: closing the header returns to the body selection, #3331; previously trivial: progress log: saving to a NAS share mounted by GVFS, #3003; previously trivial: progress log: a picture dragged near the bottom of a page lands there, #3169; previously trivial: centred list labels after leading page breaks, #2964; previously trivial: progress log: inline pictures drag to an insertion cursor and stay inline, #2233, #2234; previously trivial: progress log: a text file saved over itself closes without asking, #2376; previously trivial: progress log: a text frame in the paragraph defaults frames nothing, #2360; previously trivial: fixed font inputs in four layout controls; previously trivial: typing no longer starts render threads on every repaint, #3027; previously trivial: a right, centre or decimal tab whose text doesn't fit, or a left tab past the right indent, goes to the next line with its text, #1840; previously trivial: progress log: banded rows shade as in Word, #3415; previously trivial: progress log: the table handles show while the caret is in the table, #2428; previously trivial: progress log: a click below a floating table reaches the text after it, #2038; previously trivial: progress log: Delete on selected table cells leaves one empty paragraph in each, #2802; previously trivial: progress log: lam-alef in exported PDFs extracts whole with fonts that draw it as two glyphs, #2310; previously trivial: Bullets and Numbering toggle off style-inherited lists at their effective level, including basedOn chains and numbered ListParagraph styles; other paragraphs and list definitions stay unchanged (related to #3459); previously trivial: Russian sorting keeps ё with е and recognises decomposed ё/й; previously trivial: progress log: a text box that keeps the keyboard no longer resets the input method every frame, #2986; previously trivial: progress log: recovery copies and .json files store pictures as base64, #586 follow-up; previously trivial: progress log: legacy menu keys, #1697; previously trivial: progress log: shape gradients and transparency, #1500; previously trivial: progress log: Focus fills the screen, and Full Screen View shows the pages alone, #1678; previously trivial: progress log: text above a float's anchor wraps around it, #2048; previously trivial: progress log: File › Recover follows the app theme, #3243; previously trivial: progress log: formatting toolbar with the text context menu, #2959; previously trivial: progress log: caret inside ligatures, #1974; previously trivial: text typed into a content control takes the control's formatting; localized placeholder styles recognised; previously trivial: forms protection keeps its content controls: no inserting, Properties or Remove Content Control; previously trivial: long navigation headings wrap onto further lines within the pane, #3015; previously trivial: clearing a no-match font query keeps the recent heading visible, #2068; previously trivial: a word after a slash wraps whole, like Word, #2963; previously trivial: progress log: a header-cell picture watermark sits behind the text, #1775; previously trivial: symbols keep their font when the text font changes, #2036; previously trivial: opening a DOCX no longer copies its pictures; previously trivial: Add Font imports every selected font file, #1789); previously trivial (RTF export writes sections (gap 19); previously trivial: ODT export writes sections (gap 19); previously trivial: Read Aloud speaks each sentence in its own language, #1843; previously trivial: hint-reliant CJK outlines; previously trivial: Ctrl+wheel zoom no longer scrolls the document, #1743; previously trivial: progress log: Turkish case mapping in AutoCorrect, #1923; previously trivial: a mouse drag on a table leaves the view where it is, #1738; previously trivial: progress log: Hebrew field results and smart quotes, #1670; previously trivial: Backspace removes a selected table, rows or columns, #1844; previously trivial: progress log: mixed Hebrew/Latin text keeps its order in Word, #1543; previously trivial: progress log: web typing in non-Latin text no longer repeats, #1480; previously trivial: progress log: font family caches bounded and math font lookups follow font changes, #1354; previously trivial: `-->` AutoCorrect replacement, #2223; previously trivial: numbered headings, #1793; previously trivial: Navigation Find exposes Results, #2096; previously trivial: progress log: Columns on selected text, #2024; previously trivial: progress log: legacy outline, shadow, emboss and imprint text effects drawn, #2534; previously trivial: progress log: Indonesian proofing, #498; previously trivial: progress log: DOCX glossary documents (building blocks); previously trivial: progress log: Read Mode keeps the keyboard and shows whole, unobscured columns, #1772); previously trivial: progress log: font list entries of tall-ascent fonts no longer cut off, #2570); previously trivial: progress log: Split Cells and Convert Text to Table dialogs follow the Word check, #2592; previously trivial: a new source's Tag is made like Word's, three letters of the author and two digits of the year with a number added when taken, and an edit keeps the Tag, #2094; previously trivial: Web Layout fills the window width, #1876; previously trivial: progress log: Different First Page headers reachable from page 1, #2826; previously trivial: Language dialog keeps inherited proofing language and no-proof choices (#2717); previously trivial: progress log: web preferences kept between visits, #2132; previously trivial: progress log: undrawable private-use list bullets show the level's default bullet, #1683; previously trivial: progress log: `w:eastAsianLayout` kept on save; previously trivial: table style editor formats every part, #714); previously trivial: VML freeforms read and kept on save; previously trivial: progress log: consistent preferred cell widths; previously trivial: multi-paragraph field instructions no longer add blank lines; previously trivial: page-break-only list paragraphs hide their labels; previously trivial: progress log: grouped `flowChartOr` shapes draw their circle and crossing spokes; previously trivial: progress log: copies keep their formatting in other programs, #1523; previously trivial: progress log: privacy options on save, #1062; previously trivial: progress log: equation pictures in theme colours on Windows, #1002; previously trivial: symbol fonts, #776; previously trivial: the save prompt answers from the keyboard, #861; previously trivial: table column and row markers on the rulers, #700; previously trivial: table borders and the resize handle drag on the page, #217; previously trivial: formatting revisions landed, #41; previously trivial: Draw tab ink, #307, and Draw Table and Eraser, #303, landed: catalog 402/434; previously minor: readiness table with hours per audience; full number back to the additive weighted sum, 60%; mainstream and essentials numbers added; alpha gate checked; previously major: full re-measure against Word for Mac 16.113.4; progress docs restructured) · **Target:** Microsoft Word (Microsoft 365) for Mac 16.113.4 > **Printing update:** 2026-10-12 · direct desktop printing through craft-print; details below. +> **Legacy form update:** 2026-10-22 · trivial: numeric XML references decode in field names and labels; readiness estimates unchanged. WordCraft aims for complete parity with Microsoft Word, then goes further on speed, openness and agent control. This page is the summary; the assessment is @@ -139,6 +140,10 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm ## Progress log +- 2026-11-04: CLI `convert` rejects a missing or repeated `--format` value before opening the input or writing output, matching the existing page/scale option checks. Readiness estimates unchanged. +- 2026-11-04: MHT import keeps semicolons and escaped quotes inside quoted MIME parameters, so an unrelated parameter cannot supply a false multipart boundary and hide the document text. Readiness estimates unchanged. +- 2026-10-28: Ink replay, eraser picking, lasso selection and arrow-candidate discovery reuse the paragraph prefixes they have already scanned (#3614). Page item order, stroke geometry and saved data retain their behavior. This narrows the stability work; ink import fidelity, native pen input and broader corpus qualification remain open. + - 2026-11-04: OpenDocument files have no display settings any more (gap 19): File › Options › Advanced › OpenDocument files, `file.options` `odf`, `WORDCRAFT_ODF`, the LibreOffice style and custom values are gone. WordCraft makes one choice for each case the standard leaves open, the one the default made, and still follows what a file states ([docs/odf-interpretation.md](docs/odf-interpretation.md)). - 2026-10-31: Dialogs are modal, as in Word (#3859): while one is open, the ribbon, File, the page and the panes of its document window take no clicks, and typing and shortcuts (Ctrl+O…) do nothing until it closes; WordCraft's own Open/Save As window is modal too. A press beside a modal dialog shakes it a little, so it is clear why nothing behind it reacts (Word beeps); with animation effects off, its border flashes instead. Find and Replace, Symbol, Mark Index Entry, Cross-reference and Insert Merge Field stay modeless, as in Word for Mac 16.114.1 (checked on a newer build than the 16.113.4 the parity target names). - 2026-11-04: OpenDocument files are shown in one of two styles (gap 19): Microsoft Word style, the default, or LibreOffice style (File › Options › Advanced › OpenDocument files; `file.options` `{"odf": {"preset": "word"}}` or `"libreoffice"`; `WORDCRAFT_ODF=word` or `WORDCRAFT_ODF=libreoffice`). Custom stays for one's own value per case; `wordcraft`, the earlier id of Word's style, is still taken. @@ -235,6 +240,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm - 2026-10-22: Recovery covers every open document. Each dirty document keeps its own copy, written on the same ten-second cadence whether it is shown or not; closing a document without saving deletes its copy, as saving does, and a clean exit deletes the copies of every document saved or closed since its last copy. File › Recover lists only copies no open document keeps, and Restore opens a copy as another document (or in place of an untouched blank one), so it never replaces work. After a crash with several unsaved documents, the next start lists all of them. - 2026-10-22: The desktop window works with several open documents (one window per document comes next). View › Window › Switch Windows lists them and shows the one chosen, back where it was left; New, Open and the mailings open beside unsaved work instead of asking about it; File › Close shows the next document; quitting asks about every document with unsaved changes, one at a time, and Cancel keeps the app open. - 2026-10-22: Several open documents in one session (engine part of one window per document). File › New opens a new document beside the open ones; File › Open opens beside them too, replaces a blank document nobody has used, and shows a file that is already open instead of opening it twice. Each document keeps its own text, selection, undo history, find state, view and recovery copy. View › Window › Switch Windows (`view.switchWindows`) lists the open documents and switches between them; `file.closeDocument` closes one where no window asks about unsaved changes (agents, headless sessions). Envelopes, Labels, Finish & Merge and New from Template open their result as a new document and leave the main document open as it was. Document ids are unique in the process. The desktop app still shows one document per window; the windows come next. +- 2026-10-22: Legacy form names and selected drop-down labels decode numeric XML references, including saved whitespace, without decoding escaped reference text twice. - 2026-10-25: Interface catalogs are still the shared storytold/craft-i18n ones embedded from `craft-i18n.rev` (`9205108c…`): 27 WordCraft languages with English fallback for missing strings, and the equation “Delete Around Caret in Equation” translation preserved. Native-speaker review remains human. - 2026-10-25: Input methods (egui 0.37): character- and byte-counted surrounding deletions, a fresh composition after body/equation replacement, rejection of queued stale replacements before mutation, transactional equation deletes and one undo group, with tracked and placeholder length mapping. Synthetic regressions document these paths; managed CI passed, and native IME acceptance (#155–#164) plus browser IME behavior remain open. - 2026-10-25: Text Highlight Color shows the last colour as the button's bar in the ribbon and mini toolbar; after No Color it shows the pen without a misleading yellow bar, and the button removes highlighting (#4087). @@ -244,6 +250,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm - 2026-10-24: Parity catalog: Read Mode's View menu has its own rows. Column Width (`view.readColumnWidth`) and Page Color (`view.readPageColor`) count as live; Layout (`view.readLayout`) is listed as missing. Catalog 504/520 (96.9%). - 2026-10-24: Find and Replace: with Regular expressions on, Replace with expands capture groups instead of inserting them as typed. `(\w+), (\w+)` replaced with `$2 $1` or `\2 \1` swaps the words, and `(?\d{4})-` with `${y}/` names a group; `$0` is the whole match, `$$` a dollar sign, `\t` a tab and `\n` a paragraph mark that splits the paragraph, as `^p` does. Missing or out-of-range groups expand to nothing, and the `^` codes still work (#4177). +- 2026-10-24: A click just outside a floating table, within 2pt of a cell whose text is turned (Text Direction, or a section whose text runs down or up the page), goes to the text beside or after the table, as it already did by upright cell text, instead of putting the caret in that cell (#4181). - 2026-10-23: DOCX: a document whose default font size is unset keeps its size when saved and reopened. The size was left out of the file, and the reader read the missing size as 10 pt while the document resolved it as 11 pt; the file now says 11 pt (`DEFAULT_FONT_SIZE`). Files from other programs without a size are read as before. - 2026-10-23: Insert › Table: hovering the grid shows the table on the page where it would go, as Word's Live Preview does, and the preview follows the pointer from square to square. It is laid out on a copy of the document, so nothing changes, and Undo has nothing new, until a square is clicked (#3931). - 2026-10-24: Exact line spacing fixes the floating-table contact boundary independently of paragraph-mark metrics (#3977). Both row selection and word skipping use it; original regressions cover oversized and undersized marks, contact and one-twip offsets in modes 11/12/14/15. Shape behavior is unchanged. @@ -293,10 +300,13 @@ Imported Word 97–2003 `.doc`/`.dot` files now ask for a supported DOCX target | Date | What landed | | 2026-11-04 | Pictures keep the brightness, contrast and transparency their file gives them (#1711, #1766): a "Washout" picture watermark (VML `gain`/`blacklevel`) and a washed-out letterhead picture behind the text (`a:lum`) are drawn faded on screen and in PDF instead of at full colour, with the pixel curve measured on Word's own PDF export; `a:alphaModFix` transparency too. Saved back as DrawingML (and as VML `gain`/`blacklevel` in Word 2003 XML, without the transparency). Picture Format › Corrections, Transparency and Color › Washout replace the file's values (other Color modes leave them alone), and Reset Picture discards them all, as in Word; the PDF embeds the corrected pixels once per picture | +|---|---| +| 2026-10-17 | Copies keep their formatting in programs that read RTF rather than HTML: Copy and Cut put RTF beside the text and HTML on the system clipboard on Windows, macOS and Wayland (an X11 copy stays text and HTML, since arboard owns the selection there; a copy of only pictures or shapes carries no HTML or RTF, so pasting it back keeps every detail), and Paste reads another program's RTF on macOS and X11 too, not only on Windows and Wayland | | 2026-11-03 | **Arabic interface (#1195):** `ar` selectable (and every `ar-*` system locale); craft-i18n catalog; mirrored ribbon, panes, File page, dialogs and menus; Arabic UI font fallback; document direction stays independent. No kashida or Arabic proofing yet; Hebrew UI still open. | | 2026-11-01 | **English spelling reads SCOWL 2026 (CP2, #40, #520, #1281, #1045):** en-US, en-GB (also en-AU, en-NZ, en-IE, en-IN…) and en-CA each check against their own SCOWL `rel-2026.02.25` Hunspell dictionary from craft-i18n, embedded and read by craft-proof's affix engine (which now understands `COMPOUNDRULE`, so ordinals like `21st` are words). Suggestions come from the dialect's own dictionary; our American/British policy (`en-variants.txt`) still decides the other dialect's spellings, because Word accepts more than SCOWL's one spelling per dialect (`organize` and `organise` in en-GB). Rare words the 1990s Moby list accepted (`aposiopesis`) are now flagged. The Moby list stays for hyphenation and as a fallback. The build carries 1.5 MB more Language data. | | 2026-11-01 | Proofing moved to the shared libraries, with nothing users see changing: the code is `craft-proof` in storytold/craft-libs (with its history) and the spelling and hyphenation data (the Moby list, our English patterns and word lists, the German, Polish, Portuguese and Italian patterns, `ru-extra`) is craft-i18n's `language-data/`, embedded from `CRAFT_I18N_DIR` at the commit in `craft-i18n.rev`. Before/after `wordcraft-cli` runs on a proofing document give the same issues, suggestions and hyphenated PDF (CP1). | | 2026-10-28 | Fonts a document uses that aren't installed are no longer silent: the font box shows a warning mark (hover names the font drawn instead) and the status bar says how many are missing, listing them (the first 20, then how many more) with the faces drawn instead and Add Font…. The list is what layout actually drew, so hidden text, unused styles and orphaned stories don't count; substitutes that measure the same (Carlito for Calibri, Liberation for Arial) and Symbol/Wingdings bullets aren't flagged | +| 2026-10-21 | Read Aloud on Linux speaks through Speech Dispatcher when neither `espeak-ng` nor `espeak` is installed (#4576). It talks to the server over its own socket (SSIP), so the text is never taken for a command and stopping cancels only WordCraft's own speech, not a screen reader's; each sentence goes in its language, region included, and a sentence a screen reader's announcement cuts off is said again after a short pause; if another program keeps stopping it, reading pauses on it with a message. With no speech program at all, Read Aloud names the package to install, and the `.deb` and `.rpm` packages recommend one. | | 2026-10-28 | **Arabic diacritic editing (#4757):** Backspace removes the last stored Arabic combining mark, so its base letter can stay while the mark is replaced. Caret movement and forward Delete keep their cluster rules. Synthetic command, history, protection and native/DOCX fresh-reopen checks; no native Word comparison or readiness change. | | 2026-10-29 | Insert › Shapes shows the basic shapes as a grid of code-drawn icon tiles, each with an accessible name and tooltip, instead of a text list (#4349) | | 2026-11-03 | A password-protected file named on the command line (double-clicked in the file manager) asks for its password when the first blank document was replaced because File › Options chose a region; the window now follows that replacement at once, so the first frame no longer takes it for a document switch and drops the Password box (#5299) | @@ -305,6 +315,8 @@ Imported Word 97–2003 `.doc`/`.dot` files now ask for a supported DOCX target | 2026-10-29 | A NUL in a document title no longer reaches the native window title, which panicked on X11 (#3634): displayed titles and suggested file names drop NUL characters and fall back to the untitled name when empty; the stored title is unchanged | | 2026-10-28 | The Traditional Chinese interface draws hanzi to the Taiwan standard: on the desktop an installed Traditional Chinese font (PingFang TC on macOS, Microsoft JhengHei on Windows, Noto Sans CJK TC on Linux) comes before the embedded Noto Sans CJK SC, which drew 說, 這, 為, 戶 in mainland shapes; without one, and on the web, nothing changes. | | 2026-10-17 | macOS launch arguments (`-psn_*`, `-NS*`, `-Apple*`) are no longer opened as files, and a file that fails to open names the file and the real cause on the status bar and in the log (#1103). The reported "corrupt" error could not be reproduced. | +| 2026-10-19 | Linux: File › Options › Advanced › Linux display server picks Automatic (the default: XWayland where there's an X server, for file drag-and-drop), Wayland or X11 (XWayland), so people who don't start WordCraft from a terminal can switch without an environment variable (#2184). It's kept in `ui.json` and applies at the next launch; `WORDCRAFT_WAYLAND` still overrides it, and `WORDCRAFT_WAYLAND=0` now asks for X11. A choice that isn't available falls back to the other instead of failing to start, and the log's `display:` line says which ran and why. Hidden on Windows, macOS and the web; `ui.displayServer` for agents. | +| 2026-10-19 | The status bar's count is selectable (#2797): words (default), characters (with spaces) or characters (no spaces), from a right-click menu on the count itself or File › Options › Display › Status bar (`ui.statusCount`), kept in `ui.json` between runs; a selection shows "selected of total" in the chosen unit, counted exactly as the Word Count dialog counts them, whose numbers and meaning are unchanged. | | 2026-10-14 | Insert › Date & Time and DATE, TIME and other date fields show the computer's local date, time and weekday, daylight saving included, as Word does (#1707); they showed UTC, so a user in New Zealand at noon on 31 October got 30 October 23:00. Timestamps saved in files (revisions, comments, document properties) stay UTC. Backstage's greeting follows the local hour too | | 2026-10-23 | File > Print: N-up physical sheets and left/right-bound booklets, shared preview/PDF geometry and padded copies (#641); printer jobs keep upstream’s link-annotation fix. | | 2026-10-17 | Password-protected Word files from Word 2007 (Standard encryption: AES-128/192/256, SHA-1) open with their password, also when named `.doc` or `.dot`; a wrong or missing password is reported as for newer files. Word 97-2003 files with an AES header, which the public spec doesn't define, are refused with a clear message (gap 9) | @@ -758,6 +770,9 @@ Imported Word 97–2003 `.doc`/`.dot` files now ask for a supported DOCX target Footer page-table height and body wrapping are corrected. Other pagination gaps remain open. +Section page-numbering settings preserve `w:chapStyle` values across the full unsigned-byte range. +MATH glyphs that reference the same construction now share its immutable variants and assembly data (#3630). Glyph mappings, values and the existing partial-record fallback stay unchanged. Repeated glyph IDs keep their last valid reference without retaining superseded constructions. Distinct overlapping constructions and assembly-only sharing remain separate. + ## Revision history > 2026-11-03 · Arabic dialogs read right to left (rtl::Table); recorded in the progress log, readiness unchanged. @@ -773,12 +788,19 @@ Footer page-table height and body wrapping are corrected. Other pagination gaps | Date | Change | Summary | |---|---|---| | 2026-10-31 | trivial | Control/MCP #2596 review fixes; readiness estimates unchanged | +| 2026-11-05 | trivial | PR #4545: eligible cell floats retain in-bounds offsets and touch the outer cell edge only on overflow, ignoring wrap distances for object placement. Front-of-text, turned-cell and outside-cell opt-outs remain. Synthetic geometry controls; native front/behind-text parity remains unqualified. | +| 2026-11-04 | trivial | Progress log: CLI convert format options; readiness estimates unchanged | +| 2026-11-04 | trivial | Progress log: MHT quoted MIME parameters; readiness estimates unchanged | +| 2026-11-05 | trivial | DOCX paragraph `w:adjustRightInd` is preserved with true, false and absent values; OOXML properties follow schema order. Grid layout remains open. | +| 2026-10-28 | trivial | Per-page ink object lookups, #3614. Drawing order, geometry and saved data retain their behavior; no readiness estimate change | +| 2026-10-28 | trivial | Shared MATH construction records reuse variants and assembly data without changing glyph mappings or existing limits (#3630); readiness estimates unchanged | | 2026-11-04 | trivial | Progress log: OpenDocument display settings removed (gap 19) | | 2026-10-31 | trivial | Progress log: dialogs are modal except the five Word keeps modeless; a press beside one shakes it (#3859) | | 2026-11-04 | trivial | Progress log: picture brightness, contrast and transparency (#1711, #1766) | | 2026-11-04 | trivial | Progress log: ODT element audit (gap 19) | | 2026-11-04 | trivial | Progress log: ODT checked against 220 files from other applications (gap 19) | | 2026-11-04 | trivial | Progress log: OpenDocument files shown in Microsoft Word style or LibreOffice style (gap 19) | +| 2026-11-04 | trivial | PR #4609: relative REF keeps context already displayed by the own or a needed ancestor label; six synthetic legal-template cases and separate-list context follow the Word for Windows measurements reported by @pakiat in PR discussion. Existing unknown-switch/cache boundaries and readiness estimates unchanged; no new native Word run. | | 2026-11-01 | trivial | Progress log: SEQ, STYLEREF and REF fields show fresh results in output | | 2026-10-29 | trivial | Progress log: Print Markup balloon anchors use one object walk per paragraph (#3614); readiness estimates unchanged | | 2026-10-28 | trivial | Print Markup text-copy comment discovery walks paragraph objects once (#3614); quotes, order, limits and readiness estimates unchanged | @@ -786,6 +808,7 @@ Footer page-table height and body wrapping are corrected. Other pagination gaps | 2026-11-03 | trivial | Progress log: the missing-pack bar on a fresh install, the caret's typing language, and the spelling menu heading in the interface language (CP4.3) | | 2026-11-03 | trivial | Progress log: Options › Language and Proofing redesign (CP4.3) | | 2026-10-30 | trivial | Progress log: layout resource caps — repeated table headers are bounded by item counts, the wrap cache by decoded pixels and linked text box layout by its lines and items; PDF export, hit testing, tracked changes, clipped tables and long endnote selections cost linear time (#3867, #3866) | +| 2026-10-17 | trivial | Progress log: RTF on the system clipboard | | 2026-11-03 | trivial | Progress log: craft-proof pin, French elision suggestions and Valencian (CP4.3) | | 2026-11-03 | trivial | Progress log: a long comment's card and balloon stop at ten lines (#3382) | | 2026-11-03 | trivial | Progress log: Replace and Remove Table of Contents with Word's title above a section break (#4041) | @@ -803,6 +826,7 @@ Footer page-table height and body wrapping are corrected. Other pagination gaps | 2026-10-31 | trivial | Progress log: a list level above counts its first number at the first deeper item | | 2026-11-01 | trivial | Progress log: paragraph side borders lie outside the text (#5036) | | 2026-11-01 | trivial | Progress log: proofing moved to craft-proof (craft-libs) and its data to craft-i18n `language-data/` (CP1) | +| 2026-11-01 | trivial | #3915: preserve guarded whole-line ordinary-tab alignment with current main. Existing controls retained; source checks only, primary qualification pending. | | 2026-10-31 | trivial | Progress log: a paragraph naming an undefined DOCX style is formatted as Normal (#5077) | | 2026-10-31 | trivial | Progress log: TOC page numbers are PAGEREF fields (#5097) | | 2026-10-31 | trivial | Progress log: Backstage keytips, Alt, F, P prints (#4960) | @@ -810,6 +834,7 @@ Footer page-table height and body wrapping are corrected. Other pagination gaps | 2026-10-29 | trivial | Progress log: documents with links print (#4734) | | 2026-10-31 | trivial | Synchronize the existing Proofing pane with main `eecbb8f`; preserve explicit-position lookup, implicit selection, navigation, undo and per-window state; fresh exact-SHA hosted validation pending, readiness unchanged | | 2026-10-30 | trivial | Synchronize the existing Proofing pane and navigation/selection/undo regressions with main `3b7f7ed`; new-SHA validation pending, readiness unchanged | +| 2026-10-31 | trivial | Progress log: Linux Read Aloud through Speech Dispatcher (#4576) | | 2026-10-28 | trivial | Aligned copies retain their locked document coordinate during middle-button scrolling and can start on secondary selected objects; existing Ctrl and Shift selection behavior stays (#4764) | | 2026-10-28 | trivial | Ctrl/Command+Shift drags a selected floating object into an axis-aligned copy (#4764); synthetic Linux interaction and persistence controls, native desktop and Word untested; gap/readiness estimates unchanged | | 2026-10-28 | trivial | Connector object lookups retain the typed column-selection inputs on current main (#3631); readiness estimates unchanged | @@ -825,13 +850,17 @@ Footer page-table height and body wrapping are corrected. Other pagination gaps | 2026-10-29 | trivial | Progress log: window fallback geometry and equation symbol tooltips | | 2026-10-29 | trivial | Progress log: window titles omit NUL characters (#3634) | | 2026-10-29 | trivial | Recipient labels continue across product-sized sheets instead of stopping after the first sheet (#4880). Filtered/sorted order, product geometry and single-label mode retained; readiness estimates unchanged. | +| 2026-10-19 | trivial | Progress log: Linux display server setting (#2184) | +| 2026-10-19 | trivial | Progress log: the status bar's count can be words, characters or characters without spaces (#2797) | | 2026-10-27 | trivial | Progress log: Return on File › Print prints, as Word's default Print button does | +| 2026-10-27 | trivial | PR #4609: Numeric cross-references (#4533): preserve the numbered clause through field updates; adapted from @Alyosha-dot-shop's issue patch, with extra relative-context and cache guards. Synthetic checks only; readiness estimates unchanged. | | 2026-10-26 | minor | Word-observed Proofing task pane uses shared review commands; clicking a suggestion corrects and advances; context, suggestion cards and ignore/dictionary links follow the Windows reference; inspected previews prompted a full-width context and scrollable three-card list; exact selected spelling takes priority over overlapping grammar, with command/pane regressions and integration workflow paths; readiness estimates unchanged | | 2026-10-14 | trivial | Progress log: Insert Date and Time and DATE/TIME fields use local time (#1707) | | 2026-10-22 | trivial | Progress log: one native window per open document | | 2026-10-22 | trivial | Progress log: every open document keeps its own recovery copy | | 2026-10-22 | trivial | Progress log: several open documents in the desktop window | | 2026-10-22 | trivial | Progress log: several open documents in one session | +| 2026-10-22 | trivial | Decode numeric XML references once in legacy form names and drop-down labels | | 2026-10-25 | trivial | Progress log: egui 0.37 migration records the `craft-i18n.rev` catalog pin (9205108…; 27 languages) and the input-method handling; managed CI passed; native acceptance and native-speaker review remain open | | 2026-10-17 | trivial | Progress log: Standard-encrypted (AES) Word files open (gap 9) | | 2026-10-25 | trivial | Progress log: Text Highlight Color buttons show the remembered colour, or no colour bar after No Color (#4087) | @@ -847,6 +876,7 @@ Footer page-table height and body wrapping are corrected. Other pagination gaps | 2026-10-24 | trivial | Progress log: AutoFormat As You Type turns `*bold*` and `_italic_` marks into formatting | | 2026-10-24 | trivial | Progress log: the parity catalog counts Read Mode's View menu (Column Width, Page Color, Layout) | | 2026-10-24 | trivial | Progress log: regex Replace expands capture groups (#4177) | +| 2026-10-24 | trivial | Progress log: a click just outside a floating table by turned cell text goes to the text after it (#4181) | | 2026-10-23 | trivial | Progress log: interface translations from storytold/craft-i18n through the `craft-i18n` crate | | 2026-10-23 | trivial | Progress log: comment times in local time (#2322, #2337) | | 2026-10-22 | trivial | Progress log: mail merge record navigation and record ranges for Finish & Merge and Print Documents (#3028) | @@ -1209,3 +1239,6 @@ Footer page-table height and body wrapping are corrected. Other pagination gaps | 2026-10-27 | trivial | Progress log: AutoCorrect Options with no document open (#4585) | | 2026-10-28 | trivial | Progress log: RTF metafile pictures are imported (#4259) | | 2026-10-28 | trivial | Progress log: Chinese and Japanese text counts a word per character (#4547) | +| 2026-10-27 | trivial | 2026-10-27 · #4533 review: numeric REF updates lazily index body bookmarks once per update, retaining the first body bookmark for duplicate names. Unsupported switches and ordinary REF/PAGEREF behavior are unchanged; a synthetic 64-reference regression covers repeated updates and duplicate names. Estimates unchanged. | +| 2026-10-27 | trivial | 2026-10-27 · #4533: numeric REF fields use paragraph list numbers for no/full/relative context, reusing bounded numbering. Shared context already embedded in a level label is removed; merged-away cells do not count. Unsupported separator/text/position switches and ambiguous contexts or delimiter-free joins retain cached results. Synthetic OOXML regressions; no native Word or real-document validation, estimates unchanged. | +> 2026-10-29 · Port #3915 to split layout modules: ordinary LTR tab groups follow paragraph alignment. Positional tabs, lists, RTL and display math retain their alignment paths. Source port only; no test execution or new native measurements. diff --git a/apps/wordcraft-cli/src/main.rs b/apps/wordcraft-cli/src/main.rs index 661bb1861d..669da7c377 100644 --- a/apps/wordcraft-cli/src/main.rs +++ b/apps/wordcraft-cli/src/main.rs @@ -430,7 +430,12 @@ fn run>(args: &[S]) -> Result<(), Failure> { "convert" => { validate_options("convert", &rest, CONVERT_OPTIONS)?; // `--format wordml2003` (or `flatopc`) picks the kind of `.xml` file; its value isn't a path. - let format = arg_value(&rest, "--format"); + let format = match find_option_arg(&rest, "--format") { + OptionArg::Absent => None, + OptionArg::Duplicate => return Err("convert: duplicate --format option".into()), + OptionArg::MissingValue => return Err("convert: --format requires a value".into()), + OptionArg::Value(value) => Some(value), + }; let paths = positionals(&rest, CONVERT_OPTIONS); let (i, o) = (paths.first().ok_or_else(missing_argument)?.to_string(), paths.get(1).ok_or_else(missing_argument)?.to_string()); let markup = rest.iter().any(|a| a == "--markup"); diff --git a/apps/wordcraft-cli/src/tests.rs b/apps/wordcraft-cli/src/tests.rs index a87f778808..209fb546e7 100644 --- a/apps/wordcraft-cli/src/tests.rs +++ b/apps/wordcraft-cli/src/tests.rs @@ -75,6 +75,22 @@ fn unknown_options_are_rejected_before_file_access() { assert_eq!(run(&args(&["zotero", "refresh", "missing.docx", "--prot", "1"])), Err("zotero: unknown option --prot".into())); } +#[test] +fn convert_rejects_malformed_format_options_before_file_access() { + for (options, error) in [ + (vec!["--format"], "convert: --format requires a value"), + (vec!["--format", "--markup"], "convert: --format requires a value"), + (vec!["--format", "flatopc", "--format", "wordml2003"], "convert: duplicate --format option"), + ] { + let mut argv = args(&["convert", "missing.docx", "out.xml"]); + argv.extend(args(&options)); + assert_eq!(run(&argv), Err(error.into()), "{options:?}"); + } + // A valid single value reaches file access, rather than a format-option error. + let error = run(&args(&["convert", "missing.docx", "out.xml", "--format", "flatopc"])).unwrap_err().to_string(); + assert!(error.starts_with("missing.docx:"), "{error}"); +} + #[test] fn help_or_h_after_a_subcommand_asks_for_the_usage() { for cmd in SUBCOMMANDS { diff --git a/apps/wordcraft-web/Cargo.toml b/apps/wordcraft-web/Cargo.toml index 4a2a9d014e..971daf0cbd 100644 --- a/apps/wordcraft-web/Cargo.toml +++ b/apps/wordcraft-web/Cargo.toml @@ -16,6 +16,8 @@ path = "src/main.rs" [dependencies] wordcraft-engine = { workspace = true } wordcraft-ui-egui = { workspace = true } +# The host messages (storytold/craft-libs): one contract and one bridge for the web builds. +craft-web-host = { git = "https://github.com/storytold/craft-libs", rev = "2e2312ddaf21bc3d85cd3395d0955c7d239306f6", version = "0.1.0" } egui = { workspace = true } log = { workspace = true } serde_json = { workspace = true } @@ -29,4 +31,4 @@ rfd = { workspace = true } wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" js-sys = "0.3" -web-sys = { version = "0.3", features = ["Window", "Document", "Element", "HtmlElement", "HtmlCanvasElement", "HtmlAnchorElement", "HtmlIFrameElement", "Blob", "BlobPropertyBag", "Url", "Location", "CssStyleDeclaration", "Event", "EventTarget", "BeforeUnloadEvent", "ClipboardEvent", "DataTransfer", "FileList", "File", "DomStringList", "IdbFactory", "IdbOpenDbRequest", "IdbRequest", "IdbDatabase", "IdbObjectStore", "IdbTransaction", "IdbTransactionMode", "MediaQueryList", "Storage", "MessageEvent", "UrlSearchParams"] } +web-sys = { version = "0.3", features = ["Window", "Document", "Element", "HtmlElement", "HtmlCanvasElement", "HtmlAnchorElement", "HtmlIFrameElement", "Blob", "BlobPropertyBag", "Url", "Location", "CssStyleDeclaration", "Event", "EventTarget", "BeforeUnloadEvent", "ClipboardEvent", "DataTransfer", "FileList", "File", "DomStringList", "IdbFactory", "IdbOpenDbRequest", "IdbRequest", "IdbDatabase", "IdbObjectStore", "IdbTransaction", "IdbTransactionMode", "MediaQueryList", "Storage", "MessageEvent", "UrlSearchParams", "CustomEvent", "CustomEventInit"] } diff --git a/apps/wordcraft-web/src/host.rs b/apps/wordcraft-web/src/host.rs index 9307e0ed15..5977fd80e9 100644 --- a/apps/wordcraft-web/src/host.rs +++ b/apps/wordcraft-web/src/host.rs @@ -1,14 +1,20 @@ -//! The `postMessage` bridge to a same-origin parent page (`?host=parent`), for pages that embed -//! WordCraft in an `