mirror of
https://github.com/aphrody-labs/wordcraft.git
synced 2026-10-13 19:26:53 +00:00
0acf6bd5124c57b6ef3c6e0b78de0de7f6d56e4e
32
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0acf6bd512 |
fix(windows): start 32-bit builds on OpenGL so launch no longer exits (#839)
* fix(windows): start 32-bit builds on OpenGL so launch no longer exits DirectX 12 graphics pipeline creation fails on 32-bit Windows, so the app quit before the window appeared. Co-authored-by: Cursor <cursoragent@cursor.com> * Add @odedigo to the contributor names list The About window credits this username; no real name or display name was chosen. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Brandon Thomas <echelon@gmail.com> |
||
|
|
e619b12ceb |
i18n: add Bulgarian (bg) interface translation (#825)
* i18n: add Bulgarian (bg) interface translation
A 2,386-entry Bulgarian catalog: every key of the reference catalog, the equation gallery's
labels and everything the interface audit finds. Written from the meaning of the English
labels in ordinary Bulgarian computing vocabulary; no other product's localisation and no other
catalog in this repository was used. Counts use count-neutral wording ("Думи: 21").
- bg, bg-BG, bg_BG.UTF-8 select it automatically; "Български" in Options and
ui.language with {"value":"bg"}.
- The interface audit checks Bulgarian coverage the way it checks Russian.
- Tests: locales and saved preference, catalog coverage and key translations, count wording,
and the bundled Inter/JetBrains Mono faces covering the Bulgarian letters.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Review fixes for #825: Bulgarian built-in style names
Adds the built-in style names Russian translates (Normal Table, Default
Paragraph Font, Annotation Text/Reference/Subject, Envelope Address/Return,
Index Heading, Index {n}, Line Number, Normal Indent, Table of Figures, TOA
Heading, TOC {n}) and Good afternoon; updates the entry count in the docs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
|
||
|
|
64319e0039 |
MCP: confine file access with --automation-read-root and --automation-write-root (#769) (#798)
* Engine: check automation read and write roots on every path a command reads or writes (#769) * MCP: confine the headless session to the automation roots (#769) * CLI: add --automation-read-root and --automation-write-root to mcp (#769) * Docs: document --automation-read-root and --automation-write-root for mcp (#769) * Review fixes for #798: confine file.printPdf; guard all of engine/src - print.rs::print_pdf_to_file (file.printPdf, added on main) wrote with std::fs::write directly, so a confined agent could print a PDF anywhere. It now goes through io::write_file, which checks the automation write root. - The guard test now walks every file under crates/engine/src (not only cmd/), except io.rs, file_access.rs and the tests*.rs modules, and also flags OpenOptions. - Tests: an engine test that file.printPdf is refused outside the write root, works inside and is unchanged without roots; the MCP integration test covers it too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Review fixes for #798: list file.printPdf among the confined writes in docs/mcp.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Font files added by path go through io, inside the automation read root (#769) --------- Co-authored-by: Brandon Thomas <echelon@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
e22ce1d05e |
i18n(hu): complete the Hungarian catalog again (#842)
* i18n: add Hungarian (hu) interface translation
- crates/ui-egui/src/i18n/hu.tsv: complete catalog, all 1,572 keys of
es.tsv in the same order, written clean-room from the plain meaning
of the English labels; placeholders, escapes and trailing ellipses
kept. Commands are nouns, messages use the informal second person,
and only the first word of a label is capitalised. A noun after a
number stays singular in Hungarian, so the context-free format needs
no plural forms.
- LANGUAGES gains `hu` (Magyar); `hu`, `hu-HU` and `hu_HU.UTF-8`
resolve to it.
- The Font dialog's preview sample is "AaBbYyZz ŐőŰű", so All Caps
shows the double acute capitals.
- Tests: locale resolution and saved preference, key parity with the
Spanish catalog, sample translations, count wording, the sample's
capitals and Hungarian letters in the bundled interface fonts.
- Docs: new localization-hu.md (conventions, terminology, scope);
README, ROADMAP, localization-parity and control-protocol list the
new language; ATTRIBUTION row for hu.tsv.
* i18n(hu): built-in style names, equation gallery and citation styles
- hu.tsv now carries every key of the Russian catalog: built-in style
names (Normal, No Spacing, Subtitle, TOC {n}…), the equation gallery
and structure labels, paper sizes, watermarks and the Backstage
greetings, plus the citation style names (1,946 entries).
- The interface audit (untranslated_interface_text) checks Hungarian
alongside Russian and reports every language's gaps in one run.
- Tests: Hungarian keys cover the Russian catalog; built-in style
names and numbered style templates show in Hungarian.
- Docs: entry counts and scope in localization-hu, localization-parity
and ROADMAP.
* Review fixes for #731: Hungarian stays a partial catalog
- The i18n audit requires completeness from Russian only again: hu.tsv lacks ~280 strings of the
dialogs that landed since (Compare Documents, Math AutoCorrect, …), so it can't claim to be
complete. The catalog test no longer asserts it holds every Russian/Spanish key.
- 43 Hungarian rows for tab and command labels that reached main since (charts, content controls,
Developer tab, templates and the styles organizer, WordArt), which every_tab_and_command_is_translated
requires.
- Docs say partial, with the entry count (1,989); localization-parity's header keeps its quote
marker and the #505 note.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Review fixes for #731: Hungarian rows for the Outlining tab
24 rows for Outline view's tab and commands, which landed on main meanwhile; 2,013 entries.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Review fixes for #731: ROADMAP header keeps main's SmartArt note
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* i18n(hu): complete the Hungarian catalog again
- hu.tsv: 374 new rows for the strings that reached main while #731 was
in review (Compare Documents, Restrict Editing, Math AutoCorrect,
charts, SmartArt, the Options sections, the print page and more).
The catalog now holds every key of ru.tsv again: 2,397 entries.
- The completeness checks are back: the interface audit requires
Hungarian alongside Russian, and the catalog test asserts hu.tsv holds
every key of ru.tsv and es.tsv. The docs describe a complete catalog.
- Seven review rows follow the catalog's existing patterns: Text Pane
(Szöveg panel, like the other panes), Design Mode (Tervezőmód, one
compound), Picture and Date Picker Content Control (clearer compounds),
Promote to Heading 1 / Demote to Body Text (style name after a colon,
no case ending) and Reset Graphic (Ábra visszaállítása, shorter).
* Hungarian: translate interface strings added on main since this PR
Adds the 10 strings main gained with Polish proofing (spelling and grammar
messages, Do Not Check Spelling or Grammar, comment/browse buttons), so
hu.tsv again covers every key of the other catalogs (2,419 entries), and
drops the stale "Wildcards (regex)" row; updates the documented counts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <brandon@storyteller.ai>
|
||
|
|
feaff0f22b |
i18n: add French (fr) interface (#729)
* i18n: add French (fr) interface A complete 1813-entry catalog with the same key set and order as ru.tsv (the most complete reference), written from the meaning of the English source. Registered in LANGUAGES after Turkish. The locale-resolution tests that used fr-FR as the example of a language without a catalog now assert the French mapping and use Italian, which has no catalog, to keep testing the unsupported path. * i18n: complete the French catalog and apply review fixes Rebase onto main (1805 uk.tsv keys, up from 1812 rows at the original PR): 357 new translations for the charts, Draw, content controls, Caption/Index/TOC dialogs and formatting features that landed after the PR was opened. Also applied the reviewer's five fixes: Bring Forward → Avancer d'un niveau, Print Layout → Mode Page, Not used by any command → N'est utilisé par aucune commande, Through → Au travers, and consistent U+2019 apostrophes throughout. * Review fixes for #729: attribution, French tests, language lists - ATTRIBUTION row for fr.tsv, in the form the other catalogs use. - French locale/saved-preference test and bundled-font coverage test (accents, œ, « », ’, and the no-break spaces in Inter). - Tests that need a language without a catalog use a private-use tag (qaa-QM, qtz) instead of it-IT/de-DE, so they keep passing as real languages land. - 11 French rows for commands that landed on main since (templates, styles organizer, Overtype, Move with Text), which every_tab_and_command_is_translated requires. - fr in docs/control-protocol.md, README and localization-parity. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Review fixes for #729: French rows for Outline view and SmartArt 34 rows for the Outlining and SmartArt Design tabs and their commands, which landed on main meanwhile and every_tab_and_command_is_translated requires; 1,850 entries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * French: translate interface strings added on main since this PR Adds 174 French entries (fr.tsv now covers every key in the other catalogs, 2,023 entries) and drops the stale "Wildcards (regex)" row; updates the documented entry count. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * French: translate interface strings added on main since this PR Adds the 10 strings main gained with Polish proofing (spelling and grammar messages, Do Not Check Spelling or Grammar, comment/browse buttons): 2,033 entries; documented count updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * French: strings main added since the last merge (default app, numerals, KeyTips, Reading Mode) --------- Co-authored-by: sanches <cfic34@ya.ru> Co-authored-by: Brandon Thomas <echelon@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <brandon@storyteller.ai> |
||
|
|
326d695335 |
Linux: default to XWayland for file drag-and-drop on Wayland desktops (#220)
Co-authored-by: Brandon Thomas <echelon@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
199ac88a2e |
i18n: add Czech (cs) interface translation (#387)
* i18n: add Czech (cs) interface translation Translate the 1,246-entry interface catalog clean-room from the English source labels (cross-referenced with PdfCraft, VectorCraft, and PhotoCraft Czech catalogs) and register Czech (Čeština) for system locale detection and persisted selection. Add tests for Czech locale resolution, full catalog key parity, count-neutral word count formatting, and bundled UI font glyph coverage for Czech diacritics. # Conflicts: # ROADMAP.md * Czech: translate interface strings added on main since this PR Adds 221 Czech entries so cs.tsv again has the full zh-hans key set (2,021 entries) and drops the stale "Wildcards (regex)" row; updates the documented entry count. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Brandon Thomas <echelon@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <brandon@storyteller.ai> |
||
|
|
1fa5333b26 |
M15: Polish interface, and Polish spelling, grammar and hyphenation (#346)
* M15: Polish interface, and Polish spelling, grammar and hyphenation
Interface
- Polish is the tenth interface language ("Polski", pl.tsv, 1,045 entries);
pl, pl-PL and pl_PL.UTF-8 system locales select it automatically.
- Right-click menu labels now go through translation in every language.
- Review > Language is a menu (English US/UK, Polski, Do not check spelling
or grammar); the status bar shows the language at the caret.
- With a Polish interface, new blank documents and opened .txt/.md files
default to pl-PL.
Proofing
- Each run is checked in its own language (w:lang, resolved through
styles): squiggles, F7, review.issues, suggestions and hyphenation.
Text in languages without proofing tools is no longer flagged as English.
- Polish spelling from the SJP.PL Hunspell dictionary (Apache-2.0 option),
read by a new Rust affix engine (crates/proof/src/affix.rs); 875 KB asset,
~4.5M word forms. Regenerate with the pl_dictionary example.
- Polish suggestions: case, missing diacritics, rz/ż, ó/u, ch/h confusions,
missing spaces (napewno -> na pewno), edit distance.
- Conservative Polish grammar rules: repeated words, spacing, doubled
punctuation, sentence capitals, missing comma before że/który/ponieważ/
aby/żeby/jeśli…, we/ze forms.
- Polish hyphenation with the hyph-utf8 hyph-pl.tex patterns (MIT option);
pattern keys widened to 20 letters, TeX exceptions parsed; the heuristic
no longer treats ł, ż, ś… as vowels.
review.language validates and normalizes tags, can set noProof alone and
the document default; format.state reports lang and noProof.
Tests for every part, docs and ATTRIBUTION.md/NOTICE updated;
cargo xtask ci passes (fmt, clippy, test, assets, layers, wasm).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Layout: rustfmt the test module order left unformatted by #391
cargo fmt --check failed on main after #391 added mod tests_grid.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Review fixes for #346: read Polish spelling from the installed Hunspell dictionary
- Polish spelling uses the Hunspell pl_PL dictionary installed on the
system (OS packages, Homebrew, LibreOffice, ~/.local/share/hunspell, or
WORDCRAFT_DICTIONARIES) instead of a bundled 870 KB SJP.PL file;
without one, Polish text gets no spelling marks, like Word without the
language's proofing tools. .aff/.dic are size-capped and decoded from
UTF-8 or ISO 8859-2 (crates/proof/src/hunspell.rs).
- The dictionary can be replaced at runtime (install_dictionary) or
re-searched (reload_dictionary); an empty one accepts every word.
- Tests use small synthetic dictionaries written for them, so they don't
depend on what the machine has installed.
- The bundled pl.dic, its ATTRIBUTION/NOTICE entries and the generator
example are removed; docs describe the installed dictionary.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* M15: Polish catalog covers the interface text merged from main
The merge of main (98456ac) brought ~575 new interface strings (charts,
SmartArt, content controls, Developer tab, AutoCorrect, outline view,
protection, compare, print, accessibility, references and Language/
Hyphenation dialogs, Draw additions). pl.tsv lacked them, so
polish_covers_every_key_of_every_other_catalog and
every_tab_and_command_is_translated failed. All are now translated.
cargo xtask ci: all 6 steps pass.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
|
||
|
|
55f7b894c6 |
Add German (de) interface language (#574)
* Add German (de) interface language
New catalog crates/ui-egui/src/i18n/de.tsv (1,307 entries), key set
byte-identical to zh-hans.tsv; original translations written from the
meaning of the English UI strings in standard German word-processor
vocabulary; MIT OR Apache-2.0.
- LangInfo for de (Deutsch) registered in i18n::LANGUAGES
- Tests: German locale resolution (de, de-DE, de-AT, de-CH,
de_DE.UTF-8@euro), saved-preference/document-content isolation,
catalog key-set parity with zh-hans, count-neutral wording,
bundled-font glyph coverage for ÄäÖöÜüß
- Count strings use count-neutral wording (Wörter: {n}), the
convention the other catalogs' tests pin
- Docs: localization-parity.md, gaps.md, roadmap.md, ROADMAP.md,
README.md, control-protocol.md; ATTRIBUTION.md row for de.tsv
cargo test -p wordcraft-ui-egui i18n: 28 passed; --lib: 162 passed.
* rustfmt after merging main
* German: translate interface strings added on main since this PR
Adds 636 German entries so de.tsv again has the full zh-hans key set
(2,021 entries) and drops the stale "Wildcards (regex)" row; updates the
documented entry count.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Fourteen interface languages with German and Italian
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <brandon@storyteller.ai>
|
||
|
|
99fbd1861a |
i18n: add Italian interface (it) (#598)
* i18n: add Italian interface (it) New it.tsv catalog with 1,378 entries: every key of the existing catalogs plus 51 strings that go through tl! but were in no catalog yet (File › Info properties, File › Home greeting, list levels, Equation tab gallery and tooltips, Draw Table, About tabs). Ribbon tabs, groups and command names use the names Italian Word users know; all other text is written from the meaning of the English. Registers it in LANGUAGES (it, it-IT, it-CH resolve here), adds locale, saved-preference, coverage and bundled-font tests, and updates README, control protocol, localization parity and roadmap. Refs #594. * i18n(it): shorter Wrap Text Sides label Lati del testo a capo matches its parent menu, Testo a capo. * i18n(it): translate the 590 strings main added since the rebase Options, accessibility, alt text, content controls, document grid, templates, index, citations and the other labels every catalog gained on main. The Italian coverage test (every key of the other catalogs) passes again. * i18n(it): Issue is Fascicolo in the bibliography source form * i18n(it): translate the 351 strings main added (equation gallery, built-in styles, paper sizes, animation settings, file browser) --------- Co-authored-by: Brandon Thomas <echelon@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
48b2468f19 |
Windows: compile DX12 shaders with FXC so startup needs no DXC DLLs (#603) (#609)
wgpu 30's default DX12 compiler (Auto) uses DXC and loads whichever
dxcompiler.dll the DLL search path finds first. WordCraft ships none, so
that copy belongs to another program; without a matching dxil.dll, DXC
warns that the DXIL is unsigned, wgpu treats the warning as a compile
error, its indirect-validation pipeline fails, the device is lost and
eframe exits before the first frame ("Parent device is lost").
The window's wgpu instance (and the DirectX 12 adapter probe) now pins
the DX12 shader compiler to FXC (d3dcompiler_47.dll, part of Windows)
unless WGPU_DX12_COMPILER names another. Same approach as
storytold/lightcraft#484. README troubleshooting note and ROADMAP log.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
|
||
|
|
191d8fd48e |
#509: README names the three AUR packages and when to pick each (#616)
Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com> |
||
|
|
41bbaf51bf |
i18n: add Russian (ru) interface translation (#300)
* I18N.et: add Estonian interface translation * I18N.et: record the verified headless fork push step * i18n: send interface text that skipped translation through the catalog A test-only pseudo-language wraps every catalog lookup in ⟦…⟧ marks; a new audit test lays the app out in it (every tab, File page, dialog and pane, the right-click menu, and a hover and a click on every ribbon control, including the Table and Equation tabs) and fails on any visible text outside the marks. The document is drawn as an image, so only interface text is checked; document text, font and style names, shortcuts, icon lettering, contributor handles and command error messages are allowed. What it found, now translated in every language that has the strings: - Right-click menu items (Cut, Paste, Font…, Paragraph…, Link…, New Comment). - Paragraph dialog: the alignment choices showed code values (`left`); the label now sits before the dropdown. - Table Design › Table Style Options checkboxes. - Table Layout › Alignment tooltips showed code values (`topLeft`). - Design › Fonts: the theme's name is translated, its font names are not. - `pt` units, the Insert › Table grid label, the default watermark text, the font dialog's preview sample, and the untitled document's name. - Contributors and Models dialogs: headings, sort and name choices, summary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtHKQ7wrZm3uBuaG1Ye8po * i18n: add Russian (ru) interface translation - ru.tsv: 1,068 entries covering every interface string, written clean-room from the English labels and reviewed by a native speaker. `ru`, `ru-RU`, `ru_RU.UTF-8` and other regions resolve to it; File > Options picks it by hand. - Built-in style names (Normal, Heading 2, TOC 3, Strong…) show in the interface language in the Styles gallery, the Styles pane and the Style Inspector. Display only: documents, commands and saved files keep the English names, and styles the author made keep theirs. - Rendered previews use the interface language: the Styles gallery samples (`АаБбВвГг`) and the Design tab's style-set tiles. - Catalogs gain a `preview` context for sample text that must fit a small tile (`Title` is «Заголовок» as a style but «Пример» in the tiles); it falls back to the plain entry, and unknown contexts are still rejected. - Tests: locale detection and saved preference, full coverage, Cyrillic glyphs in the bundled interface fonts, style-name display, catalog contexts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * i18n(ru): translate everything the interface audit finds Adds 356 Russian entries: the equation gallery (categories, templates and built-in equations), equation options, themes, watermark presets, paper sizes, table styles, greetings, outline levels, the strings #313 routes through the catalog, and the new AutoSave messages. The two rows #305 made obsolete (📂 Browse…, ➕ New comment) are gone. The interface audit now also fails when a string it sees translated has no Russian entry, so Russian stays complete as the interface grows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtHKQ7wrZm3uBuaG1Ye8po * Draw Table and Eraser: draw tables and split or merge cells with a pen (#303) Insert › Tables › Draw Table and Table Layout › Draw › Draw Table / Eraser. table.draw takes a pen stroke in page points: a rectangle outside a table inserts a one-cell table of that size at the paragraph under its start; a straight vertical or horizontal line inside a table splits the cells it crosses (new grid column or row; untouched cells span it). table.eraser merges the two cells beside the border nearest a point. Each stroke is one undo step. In the app the buttons toggle pen and eraser modes with a live preview, a crosshair with the tool's icon, and Esc to stop; canvas clicks don't move the caret while a tool is on. Splitting through part of a vertically merged cell and erasing beside one are refused with a clear error. Catalog 384/430 -> 387/430. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Draw tab: pen, pencil and highlighter ink, stroke eraser and Hide Ink (#307) Ink strokes are floating freeform shapes: a new Freeform geometry (paths in shape-local coordinates, opacity, and the pen that drew it) on InlineObject::Shape with ShapeKind::Freeform. draw.stroke inserts one anchored to the paragraph under the first point (one undo step; points capped per stroke, strokes capped per page, NaN dropped); draw.erase / draw.eraser with a point deletes the stroke under it; draw.pen, draw.pencil, draw.highlighter, draw.eraser and draw.select set the Draw tab's tool in the session view state; review.hideInk toggles showing ink on screen. The canvas draws a live stroke while a pen is dragged and commits it on release; the eraser deletes strokes it passes over (one undo step per drag); Esc or Select goes back to selecting. Draw tab buttons show the tool in use, with colour and thickness menus; Review gets an Ink group with Hide Ink. Ink renders with round caps and joins on screen and in PDF; highlighters are translucent and behind the text. DOCX writes freeforms as wps:wsp with a:custGeom (moveTo/lnTo) in a wp:anchor and reads them back, along with simple custom-geometry freeforms from other files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * #315 review fixes: eraser undo test, sanitized tap dots, custGeom path cap, ink docs - draw.eraser with a point erases through draw.erase: test that it is one undo step (undo/redo) and marks the document dirty. - Render and PDF: a single-point stroke's dot is drawn at the sanitized point, not the raw first one. - DOCX custGeom reading stops once MAX_PATHS paths (subpaths included) are collected, across a:path elements. - docs/file-format-parity.md: ink is saved as custom geometry, not InkML, so Word shows it as a freeform. - widgets test: theme::apply takes an Appearance (#317). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * i18n: send interface text that skipped translation through the catalog A test-only pseudo-language wraps every catalog lookup in ⟦…⟧ marks; a new audit test lays the app out in it (every tab, File page, dialog and pane, the right-click menu, and a hover and a click on every ribbon control, including the Table and Equation tabs) and fails on any visible text outside the marks. The document is drawn as an image, so only interface text is checked; document text, font and style names, shortcuts, icon lettering, contributor handles and command error messages are allowed. What it found, now translated in every language that has the strings: - Right-click menu items (Cut, Paste, Font…, Paragraph…, Link…, New Comment). - Paragraph dialog: the alignment choices showed code values (`left`); the label now sits before the dropdown. - Table Design › Table Style Options checkboxes. - Table Layout › Alignment tooltips showed code values (`topLeft`). - Design › Fonts: the theme's name is translated, its font names are not. - `pt` units, the Insert › Table grid label, the default watermark text, the font dialog's preview sample, and the untitled document's name. - Contributors and Models dialogs: headings, sort and name choices, summary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtHKQ7wrZm3uBuaG1Ye8po * i18n audit: start every ribbon click from a fresh app; translate the table style preview The sweep pressed Escape after each click, and in an equation Escape leaves it, so the Equation tab vanished after its first control and the rest of its menus (Convert, Justification, …) were never opened. Each control now gets a fresh app set up the same way. The narrower allowance for short text (only icon lettering and initials) also catches short words. It found the sample table in the Table Style dialog (Mon, Tue, North, Total, …), now translated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtHKQ7wrZm3uBuaG1Ye8po * #313: catalog rows for the newly translated interface text Rows in all eight catalogs for the strings #313 now sends through the catalog (cell alignment tooltips, credits columns and summary, theme names, context-menu items, table picker, pt suffix, Document1, the Font dialog sample) and for the Table Style preview's sample table, which the untranslated-text audit flagged after main's table style editor landed. The audit runs headless (no host services: no file pickers or speech) in about 20 s, so it stays enabled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * i18n audit: click the ribbon's bottom row too The sweep only clicked controls centred between y = 52 and 125, which took in the tab row and left out each group's bottom row (Equation › Convert and Justification among them). The band is now taken from the layout: below the tab row and above the document area. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtHKQ7wrZm3uBuaG1Ye8po * i18n audit: lay the app out wide enough that no ribbon tab overflows At 1440 pt the Equation tab ran past the window, so its last controls (Justification among them) sat behind the ribbon's scroll arrow and were never clicked. The audit window is now 2560 pt wide. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtHKQ7wrZm3uBuaG1Ye8po * i18n: add Russian (ru) interface translation - ru.tsv: 1,068 entries covering every interface string, written clean-room from the English labels and reviewed by a native speaker. `ru`, `ru-RU`, `ru_RU.UTF-8` and other regions resolve to it; File > Options picks it by hand. - Built-in style names (Normal, Heading 2, TOC 3, Strong…) show in the interface language in the Styles gallery, the Styles pane and the Style Inspector. Display only: documents, commands and saved files keep the English names, and styles the author made keep theirs. - Rendered previews use the interface language: the Styles gallery samples (`АаБбВвГг`) and the Design tab's style-set tiles. - Catalogs gain a `preview` context for sample text that must fit a small tile (`Title` is «Заголовок» as a style but «Пример» in the tiles); it falls back to the plain entry, and unknown contexts are still rejected. - Tests: locale detection and saved preference, full coverage, Cyrillic glyphs in the bundled interface fonts, style-name display, catalog contexts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * i18n(ru): translate everything the interface audit finds Adds 356 Russian entries: the equation gallery (categories, templates and built-in equations), equation options, themes, watermark presets, paper sizes, table styles, greetings, outline levels, the strings #313 routes through the catalog, and the new AutoSave messages. The two rows #305 made obsolete (📂 Browse…, ➕ New comment) are gone. The interface audit now also fails when a string it sees translated has no Russian entry, so Russian stays complete as the interface grows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtHKQ7wrZm3uBuaG1Ye8po * i18n(ru): native-speaker review corrections Add Note, Move Past Citation, equation display/inline, accents, stacks, operators, Column Selection, Reading Highlight, ASAP and Tools, as reviewed; the Accent gallery button wraps onto two lines. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtHKQ7wrZm3uBuaG1Ye8po * i18n(ru): translate what the improved audit and today's main add The audit now opens every ribbon menu (bottom rows and the Equation tab's last controls included), which surfaced Equation › Convert and Justification, and the Table Style dialog's sample table. Also covers password protection, Manage Styles, the clipboard pane, Shape Effects and Asian typography from main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtHKQ7wrZm3uBuaG1Ye8po * i18n: translate the Table Layout 'Draw Table' ribbon label in every catalog #308's two-line ribbon label had no catalog rows; #300's Russian audit (ru covers everything the interface looks up) found it. Rows in all ten catalogs keep et == es and ru covering zh-hans. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * i18n: Borders and Shading line widths through the catalog ({n} pt) #313's untranslated-text audit flagged main's new dialog (#327). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * land-294: Estonian rows for main's newer dialogs Define New Multilevel List and Track Changes Options (#342), rotation (#332), Tabs and Borders and Shading (#327), Columns, Symbol and Field (#335): et keys equal es again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * i18n audit: run on demand (#[ignore]) until its rare failure under load is understood It failed once in ~46 runs on a heavily loaded machine and passed 35 straight reruns, so CI shouldn't depend on it yet. Run it with --ignored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * i18n(ru): restore the review corrections a merge reverted; narrow and hide labels A merge of older copies of this branch's commits put back the pre-review wording of 20 entries (Add Note, Tools, the equation accents and operators, Column Selection, Reading Highlight, ASAP, …) and dropped six that are still in use (Equation › Convert, Centered as Group, the hyphenation menu's ✓ None). They're back as reviewed. Also: 1/4 Em Space → «Узкий пробел», and the Draw tab's Hide Ink button reads «Скрыть». Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtHKQ7wrZm3uBuaG1Ye8po * i18n(ru): restore the reviewed wording a merge rewrote The same merge reworded 24 reviewed entries (password protection, Shape Effects, Asian typography, the clipboard pane, the table style sample); they're back as a native speaker reviewed them. Clipboard Pane keeps «Область буфера обмена», like the other panes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtHKQ7wrZm3uBuaG1Ye8po --------- Co-authored-by: Henno Täht <henno.taht@gmail.com> Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: vangel76 <vangel1976@googlemail.com> Co-authored-by: Brandon Thomas <echelon@gmail.com> |
||
|
|
2c8439b24c |
i18n: add Turkish (tr) interface translation (#494)
* chore(lints): satisfy nonminimal_bool on Rust 1.96 Clippy Four boolean expressions rewritten into their equivalent minimal forms (De Morgan / is_none_or) so `cargo xtask ci` passes `clippy -D warnings` on current stable. No behaviour change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * i18n(tr): Turkish interface (Türkçe) - crates/ui-egui/src/i18n/tr.tsv: complete catalog, all 1,307 keys of es.tsv, written clean-room from the plain meaning of the English labels; placeholders, escapes and "…" kept. A noun after a number stays singular in Turkish, so the context-free format needs no plural forms. - Registry entry `tr` / "Türkçe": tr-TR, tr-CY and tr_*.UTF-8 locales resolve by the generic prefix match; saved preference and English fallback use the existing machinery. - Command search folds case the Turkish way (İ→i, I→ı) for translated labels and locations, while English labels and ASCII command ids keep their existing Unicode case-insensitive matching ("italik" finds "İtalik", "INSERT.TABLE" still finds insert.table). - The Font dialog's preview sample is "AaBbYyZz ĞğİıŞş": it has no lowercase i, so the All Caps preview (to_uppercase) gets the Turkish capitals right. - Tests: catalog key and placeholder parity, locale resolution, saved preference, Turkish folding, the sample's capitals, a real egui command-dialog regression, and ÇçĞğİıÖöŞşÜü in the bundled UI fonts. - Docs: README, ROADMAP, localization-parity, control-protocol, new localization-tr.md (terminology, scope); ATTRIBUTION row for tr.tsv. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(paste): an absolute picture path that is absolute on Windows too `/tmp/b.JPG` has no drive, so `Path::is_absolute` is false on Windows and `paste_inserts_clipboard_pixels` failed there; the test uses `C:\tmp\b.JPG` on Windows. Test-only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com> |
||
|
|
e4b7d155f1 |
Bump version to 0.5.0; add Linux riscv64 release build (#394)
- release.yml: new `linux-riscv64` job ported from GridCraft. Cross-compiles wordcraft and wordcraft-cli on ubuntu-24.04 with riscv64 libs from ports.ubuntu.com (riscv64 variants of the Linux job's -dev packages), packages a tar.gz, and smoke-tests the CLI under QEMU. The draft-release job needs it, so its tar.gz is uploaded and covered by SHA256SUMS. - packaging/linux/package.sh: CROSS_ARCH/CROSS_TARGET/CROSS_COMPILE/EMULATOR support (as in GridCraft). - README and docs/releasing.md list the riscv64 tarball. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
afb4720644 |
Add Estonian interface translation (#294)
* I18N.et: add Estonian interface translation * I18N.et: record the verified headless fork push step * i18n: send interface text that skipped translation through the catalog A test-only pseudo-language wraps every catalog lookup in ⟦…⟧ marks; a new audit test lays the app out in it (every tab, File page, dialog and pane, the right-click menu, and a hover and a click on every ribbon control, including the Table and Equation tabs) and fails on any visible text outside the marks. The document is drawn as an image, so only interface text is checked; document text, font and style names, shortcuts, icon lettering, contributor handles and command error messages are allowed. What it found, now translated in every language that has the strings: - Right-click menu items (Cut, Paste, Font…, Paragraph…, Link…, New Comment). - Paragraph dialog: the alignment choices showed code values (`left`); the label now sits before the dropdown. - Table Design › Table Style Options checkboxes. - Table Layout › Alignment tooltips showed code values (`topLeft`). - Design › Fonts: the theme's name is translated, its font names are not. - `pt` units, the Insert › Table grid label, the default watermark text, the font dialog's preview sample, and the untitled document's name. - Contributors and Models dialogs: headings, sort and name choices, summary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtHKQ7wrZm3uBuaG1Ye8po * Draw Table and Eraser: draw tables and split or merge cells with a pen (#303) Insert › Tables › Draw Table and Table Layout › Draw › Draw Table / Eraser. table.draw takes a pen stroke in page points: a rectangle outside a table inserts a one-cell table of that size at the paragraph under its start; a straight vertical or horizontal line inside a table splits the cells it crosses (new grid column or row; untouched cells span it). table.eraser merges the two cells beside the border nearest a point. Each stroke is one undo step. In the app the buttons toggle pen and eraser modes with a live preview, a crosshair with the tool's icon, and Esc to stop; canvas clicks don't move the caret while a tool is on. Splitting through part of a vertically merged cell and erasing beside one are refused with a clear error. Catalog 384/430 -> 387/430. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Draw tab: pen, pencil and highlighter ink, stroke eraser and Hide Ink (#307) Ink strokes are floating freeform shapes: a new Freeform geometry (paths in shape-local coordinates, opacity, and the pen that drew it) on InlineObject::Shape with ShapeKind::Freeform. draw.stroke inserts one anchored to the paragraph under the first point (one undo step; points capped per stroke, strokes capped per page, NaN dropped); draw.erase / draw.eraser with a point deletes the stroke under it; draw.pen, draw.pencil, draw.highlighter, draw.eraser and draw.select set the Draw tab's tool in the session view state; review.hideInk toggles showing ink on screen. The canvas draws a live stroke while a pen is dragged and commits it on release; the eraser deletes strokes it passes over (one undo step per drag); Esc or Select goes back to selecting. Draw tab buttons show the tool in use, with colour and thickness menus; Review gets an Ink group with Hide Ink. Ink renders with round caps and joins on screen and in PDF; highlighters are translucent and behind the text. DOCX writes freeforms as wps:wsp with a:custGeom (moveTo/lnTo) in a wp:anchor and reads them back, along with simple custom-geometry freeforms from other files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * #315 review fixes: eraser undo test, sanitized tap dots, custGeom path cap, ink docs - draw.eraser with a point erases through draw.erase: test that it is one undo step (undo/redo) and marks the document dirty. - Render and PDF: a single-point stroke's dot is drawn at the sanitized point, not the raw first one. - DOCX custGeom reading stops once MAX_PATHS paths (subpaths included) are collected, across a:path elements. - docs/file-format-parity.md: ink is saved as custom geometry, not InkML, so Word shows it as a freeform. - widgets test: theme::apply takes an Appearance (#317). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * #313: catalog rows for the newly translated interface text Rows in all eight catalogs for the strings #313 now sends through the catalog (cell alignment tooltips, credits columns and summary, theme names, context-menu items, table picker, pt suffix, Document1, the Font dialog sample) and for the Table Style preview's sample table, which the untranslated-text audit flagged after main's table style editor landed. The audit runs headless (no host services: no file pickers or speech) in about 20 s, so it stays enabled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * i18n: Borders and Shading line widths through the catalog ({n} pt) #313's untranslated-text audit flagged main's new dialog (#327). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * land-294: Estonian rows for main's newer dialogs Define New Multilevel List and Track Changes Options (#342), rotation (#332), Tabs and Borders and Shading (#327), Columns, Symbol and Field (#335): et keys equal es again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * i18n audit: run on demand (#[ignore]) until its rare failure under load is understood It failed once in ~46 runs on a heavily loaded machine and passed 35 straight reruns, so CI shouldn't depend on it yet. Run it with --ignored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: vangel76 <vangel1976@googlemail.com> Co-authored-by: Brandon Thomas <echelon@gmail.com> |
||
|
|
1800007463 |
Windows: use OpenGL when DirectX 12 has no GPU driver (#316) (#325)
Since Windows defaults to DirectX 12 only (#50), PCs whose graphics chip has no DirectX 12 driver (Intel 4th generation on Windows 11) fall back to WARP, Microsoft's software renderer, and the app lags. Before eframe creates its instance, WordCraft now probes DirectX 12 with a short-lived instance: a hardware adapter that meets eframe's device limits keeps DirectX 12 only; WARP only enables OpenGL next to DirectX 12 (GPU preferred, WARP as last resort); no adapter, or only GPUs below the limits, uses OpenGL alone. WGPU_BACKEND still overrides everything. The choice is logged, and the decision is a pure function with unit tests. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com> |
||
|
|
eb31860917 |
Progress docs: target-app parity, gaps, alpha gate, readiness by audience (#277)
Progress docs per craftrules standards/progress-docs.md: target-app parity, gaps, roadmap with alpha gate, readiness by audience (full / mainstream / essentials) with Opus 5.5 hours, and feature, format, layout, hardware, UI and localization parity docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
663904a2e2 |
Import Word 97-2003 .doc files (#28) (#145)
* D0+D1: open Word 97-2003 .doc — container, FIB, piece table text (#28) New wordcraft-docbin crate (L2) reads the OLE2 container via the cfb crate (MIT) and parses the FIB and piece table from the [MS-DOC] specification: text pieces decode as UTF-16LE or Windows-1252 (table moved to wordcraft-doc::encoding), subdocument CP ranges, and Word's special characters map to the model's (tabs, breaks, hyphens). .doc/.dot registered in OPEN_EXTS and the I/O dispatch. Encrypted and Word 6/95 files give clear errors; every length is checked and proptest truncation/flips never panic. * D2: .doc formatting — stylesheet, fonts, CHPX/PAPX FKPs, sprms (#28) Sprm decoder with operand-size rules (incl. sprmTDefTable/sprmPChgTabs exceptions and the Prm0 isprm table), bin tables + ChpxFkp/PapxFkp page lookup, STSH styles (StdfBase layout validated against real Word files: bchUpe == cbStd, sti 0 = Normal) and the SttbfFfn font table in both extended and self-delimiting flavours. The CP walk now splits runs on formatting changes and resolves paragraph styles: bold/italic/strike/ underline/caps/hidden, colours (Ico palette + COLORREF), half-point sizes, super/subscript, fonts, highlights; alignment, indents, spacing, keep options, outline levels. Unknown sprms are skipped leniently; an env-gated corpus test opens real files (styles + text asserted). * D3: .doc structure — sections, headers/footers, tables, lists (#28) - Sections: PlcfSed/Sepx with 16-bit measurement sprms (sprmSXaPage & co), explicit sprmSBOrientation with a width/height fallback; even/odd/first header and footer stories from Plcfhdd become document parts. - Tables: sprmTDefTable grids (operand length fixed to cb+1 per the spec), horizontal merges (sprmTMerge), vertical merges (sprmTVertMerge), cell shading (sprmTSetShd / sprmTDefTableShd80), cell widths, valign, row height/header/cant-split, and table borders (sprmTTableBorders80 Brc80s). - Lists: PlfLst (LSTF + appended LVLs) and PlfLfo (LFO + LFOLVL overrides) resolved into the numbering model; sprmPIlvl/sprmPIlfo mark paragraphs. - Combined fixture (intro + table + list + 2 sections + header) round-trips through Document JSON; hostile proptests now mutate the structured fixture. * D4: .doc notes, fields, bookmarks and inline pictures (#28) - Footnotes/endnotes: PlcffndRef/PlcfEndRef reference CPs paired with the PlcffndTxt/PlcfEndTxt story ranges; each story walks into a Footnote or Endnote part and the 0x02 anchor becomes a NoteRef object. - Fields: 0x13/0x14/0x15 state machine in the walker — instruction text is hidden, the cached result kept; HYPERLINK fields keep their result as linked runs, everything else becomes one Field object. - Bookmarks: SttbfBkmk names + Plcfbkf/Plcfbkl CPs become BookmarkStart/ BookmarkEnd objects at their anchors. - Pictures: sprmCPicLocation points into the Data stream; the PICF header gives the display size (dxaGoal/dyaGoal scaled by mx/my) and the payload is format-sniffed (PNG/JPEG/GIF/BMP; metafiles are dropped with a warn). - Hostile proptests now truncate/flip a fixture with all of the above. * D5: .doc import hardening, caps and roadmap (#28) - Cap inline pictures at 5 000 per document. - Engine test: .doc/.dot bytes dispatch through the Word 97-2003 reader (garbage must error, never panic or open empty). - ROADMAP: Word 97-2003 import row (60% — text, formatting, styles, sections, headers/footers, tables, lists, notes, fields, bookmarks, raster pictures). Real-corpus validation stays opt-in: WORDCRAFT_DOCBIN_FIXTURES=<dir> cargo test -p wordcraft-docbin corpus_files_open. * Corpus fixes: compressed-piece FC space, PAPX query point, none-level labels (#28) Validated against two real files (kept locally under plan/word/fixtures, gitignored): a 1 MB Lorem-ipsum sample and a 2003 styles/lists/table sample. - FKP bin tables and pages address the WordDocument stream in true byte offsets; a compressed piece stores its base fc doubled (byte = fc/2), so fc_of_cp now unwinds the doubling. Before, every PAPX/CHPX lookup in compressed (cp1252) files landed on the wrong entry — tables collapsed to one row, lists and heading styles were lost. - The paragraph-properties query now uses the paragraph mark's own FC (inside the paragraph) instead of the FC after it, which picked up the next paragraph's FKP entry. - Fixture papx entries re-keyed to paragraph-start CPs, the real rgfc convention. - Counters::next_label returns nothing for NumFormat::None levels (Word's numFmt none shows no label; also fixes a latent docx-reader case). - Symbol/Wingdings bullet chars map to Unicode glyphs (• ▪ ○ ●). With this, both corpus files render headings, styles, nested and numbered lists, the tables and the PAGE field correctly; metafile-wrapped images and OLE objects stay dropped by policy (logged). * docbin: bound the text walk by real text; dedupe and cap pictures (#28) Hostile CP numbers no longer drive the work: - header/footnote/endnote story ranges from the Table stream are clamped to their subdocument (ccpHdd/ccpFtn/ccpEdn) with checked base additions, and every walk stops at the last piece's CP; a story spanning [0, 4e9) used to push billions of U+FFFD; - characters are found by binary search over the pieces (PieceTable::char_at), and an unreadable stretch (gap, truncated or out-of-stream piece) is skipped in one step rather than one U+FFFD per CP; the old per-character scan was O(chars x pieces); - the piece CPs are made non-decreasing at parse, so inverted pieces are empty and binary search stays sound; surrogate pairs now decode; - note references are looked up by binary search; the style's CharProps is borrowed, not cloned, per character; - pictures are interned by fc_pic (5000 anchors on one picture share one media entry and one copy) and the bytes copied per document are capped at 256 MB. Each fix has a crafted-bytes regression test; against the previous code the story, piece-claim, last-piece and many-pieces tests hang (killed at 60 s) and the shared picture test copies the picture once per anchor (80 GB). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docbin: checked offset arithmetic in lists, sections and table rows (#28) - list.rs: PlfLst/PlfLfo/LVL offsets (at + 2 + cLst*28, at + 4 + lfoMac*16, off += len, ...) saturate, which matters on 32-bit targets (wasm32) where fc + n can overflow usize; the LFO override path no longer indexes abstracts directly. - sections.rs: the Sepx range (fc_sepx + 2 + cb) is checked; Plcfhdd is read only as far as the stories a capped section count can use (it used to reserve lcb/4 entries). - table.rs: sprmTDyaRowHeight = i16::MIN negated in i16 (overflow panic in debug builds); now -(v as f32). Regression tests: the row height test failed before (overflow panic with debug assertions, a 0 pt height without); the list test pins the saturating offsets (it only overflowed on 32-bit targets). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Format the merged OPEN_EXTS list Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Brandon Thomas <echelon@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
0811a80f31 |
Add Ukrainian (uk) interface translation (#91)
* i18n #85: add Ukrainian interface translation Translate the existing 771-entry interface catalog and register Ukrainian for locale detection and persisted selection. Check full catalog coverage, count-neutral labels, preference persistence, and bundled Ukrainian glyph coverage. Validate the translation against Ukrainian dictionaries. Co-authored-by: Codex <noreply@openai.com> * i18n: Ukrainian rows for strings added on main Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * i18n: Ukrainian label for Character Border (lands after #60) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Codex <noreply@openai.com> Co-authored-by: Brandon Thomas <echelon@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
7d592ce19a |
Add Spanish interface language, and make ribbon overflow visible (#129)
* Spanish interface language (es) Adds a Spanish catalog beside the Chinese and Japanese ones and registers it in LANGUAGES, so it appears in File ▸ Options ▸ Interface language and follows Spanish system locales (es-ES, es-MX, es-419 …). Neutral Spanish: tú for sentences, infinitives for commands, sentence case. Written from the English meaning; no Microsoft Word localisation was consulted or copied. Covers the 771 keys of the existing catalogs, plus the two ribbon-edge tooltips added in the next commit. The bundled-catalog and every-command-translated tests pass. * Ribbon: show and scroll past the edge when a tab overflows The ribbon scrolls horizontally, but its scrollbar is hidden, so groups that run past the window edge were clipped with no sign they existed. Spanish labels make the Review and Home tabs wider than the window at 1440 pt. Overflowing rows now show ‹ and › chevrons at the edges. Clicking one scrolls the row by 160 pt; the chevron disappears at each end. The tooltips are in the Spanish catalog and show in English in other languages until translated. * i18n: Spanish rows for strings added on main; ribbon scroll labels in every catalog Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Brandon Thomas <echelon@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
02e2a51bb4 |
LaTeX (.tex) import and export (#7) (#11)
* LaTeX (.tex) import and export (#7) Open and save LaTeX source as a document format, next to Markdown and HTML. Export writes a standalone article (fontenc, ulem, xcolor, multirow, amsmath, hyperref, loaded only when used): unnumbered sections, itemize/enumerate, quote, center/flushright, verbatim, tabular with the document's column widths and merged cells, equations as $..$ / \[..\], character formatting, colours and links; metadata goes to \hypersetup. Import reads the everyday subset: preamble \title/\author, sectioning (\part/\chapter shift levels), paragraphs, lists with labels, quote, alignment environments, verbatim-like environments, tabular with \multicolumn/\multirow/\cellcolor and p{} widths, inline and display math, formatting commands and declarations, colours, links, refs, citations, footnotes, accents, TeX ligatures and special characters. Unknown commands keep their arguments' text; layout and definition commands are dropped with their arguments. Nesting is depth-limited and input is capped, so hostile files can't overflow the stack. The flow model gains an Equation inline so equations survive LaTeX round trips; the other text formats write their linear text as before. Wired into open/save dispatch, the file dialog filter, Backstage Export, the web app, CLI/MCP help, docs and the Linux desktop entry. Fixes #7. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019FczntrDNYd6DupyBdpbL5 * #7: bound LaTeX column specs and equation export (review) - spec_widths: `*{n}{…}` repeats recurse with a depth argument and stop at MAX_NEST, so a deeply nested column spec no longer overflows the stack or exhausts memory. Column counts saturate and widths stop at MAX_COLS. - Column specs read from the source are capped at MAX_SPEC (4096) chars. - balanced() looks groups up in a table of closers built in one stack pass, so linear_to_latex no longer rescans to the end of the string for every unmatched `(` (quadratic: 50k took seconds). spec_widths uses it too. - env_name restores the position when `\begin{` / `\end{` has no `}` within 64 chars, so the `{` is no longer lost. - Regression tests: the 100k-deep `*{1}{` spec and a 200k-`(` equation in deep_nesting_is_bounded; unclosed_begin_keeps_its_brace and spec_widths_repeats_are_bounded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LyVbT6Vv4BwWZ4hY8973qD * #7: linear-time labels, brackets and \begin{; no commands from the document in exports Applies @HaringIbon's review suggestions: 1. Parser::anchor keeps at most MAX_ANCHOR_RUN (64) bookmarks in a row with no text between them; text() looked back past every one, so a file of labels imported in quadratic time. Labels separated by text are all kept. 2. linear_to_latex_at checks for the `/` of a fraction before copying the group out, so deeply nested matched brackets export in linear time. 3. env_name searches only the next 65 bytes for `}`, so a run of unclosed `\begin{` imports in linear time. 4. An equation's `\name` is written as a command only when it is a known symbol, function or font/spacing command (MATH_COMMANDS); anything else becomes `\backslash name`. Two carets are never written side by side in equations or anchor names, since TeX reads `^^5c` as a backslash. Compiling an export can no longer `\input` files or `\write18` named by the document. Regression tests: three cases added to deep_nesting_is_bounded, plus latex_export_carries_no_commands_from_the_document and latex_labels_in_a_row_are_read_in_linear_time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LyVbT6Vv4BwWZ4hY8973qD * Merge follow-ups: FTable.borderless (from #102) in the LaTeX importer; rustfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com> |
||
|
|
ae79726ab6 |
i18n: add Brazilian Portuguese (pt-br) interface translation (#127) (#128)
771-entry pt-br.tsv catalog written clean-room from the English labels, one LANGUAGES row, locale/persistence/coverage/font regression tests, and README, ROADMAP, control-protocol and ATTRIBUTION updates. |
||
|
|
d7d9702bda |
Interface languages: follow the system, or pick one in Options (#8) (#12)
WordCraft's interface can now be shown in Simplified Chinese, Traditional Chinese or Japanese as well as English. The new `language` setting is `auto` by default: the UI follows the operating system's preferred languages (Windows display language, macOS preferred languages, LANG/LC_* on Unix, via sys-locale; WORDCRAFT_LANGUAGE overrides) when there is a catalog for one of them, and English otherwise. File > Options > Interface language picks one by hand, and the `ui.language` command does the same for scripts and agents. The setting persists with the other UI preferences. The i18n module is PdfCraft's (catalog format, parser, locale matching), trimmed to plain entries. English strings in the code are the keys; the ribbon helpers (group, big, small, split, menu_button, menu items, tooltips and ribbon locations), tabs, Backstage, Options, dialogs, panes, the status bar, the context menu and command search translate at draw time. Command ids, documents, the CLI, MCP and the control channel stay English. Catalogs hold ~780 entries per language, written clean-room from the English meaning. Chinese interfaces put the craft-fonts Chinese face before the Japanese one so a line never mixes glyph styles; fonts are reinstalled when the language changes. Fixes #8. Claude-Session: https://claude.ai/code/session_019FczntrDNYd6DupyBdpbL5 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <shared2@storyteller.ai> |
||
|
|
9b6f42dd5f |
Desktop: write log records to standard error and a rotating log file (#17)
* Desktop: write log records to standard error and a rotating log file The desktop app installed no logger, so every log::warn!/log::error! in the workspace was discarded: an unreadable part of a .docx, a picture or font a PDF export had to leave out, a PNG that would not encode. A launch from a desktop menu has no terminal either, and a panic's message went to that missing terminal, so there was nothing to attach to a bug report. apps/wordcraft/src/logging.rs (no new dependency): - standard error plus logs/wordcraft.log next to the preferences (~/.config/wordcraft/logs, or under $XDG_CONFIG_HOME); each launch rotates the previous log to wordcraft.1.log and .2.log, so the log of a run that crashed survives the next start; the file is capped at 16 MiB - records logged before the settings directory is known are buffered (bounded) and written once the file is attached - default levels: info for wordcraft*, warn for everything else; RUST_LOG replaces them with env_logger-style directives - never panics: an unusable directory or a failed write leaves standard error as the only sink - runs with WORDCRAFT_NO_PREFS (agents' test runs) log to standard error only, so they don't rotate away the user's own logs - a panic hook reports every panic, also those Session::run's guard recovers from, through the logger; text the message quotes between backticks (std quotes the string it failed to slice, which can be the user's writing) is left out The logger is installed first in main, before the panic hook, and the file is opened after argument parsing (--version leaves no file). The control server's and file-open messages go through the logger and drop their "wordcraft: " prefix, which the record's target now shows. Documented in README.md (Logs). * Desktop: no eprintln! on the log and panic paths eprintln! panics when standard error is a broken pipe (a GUI launch on Windows), and a panic inside the panic hook aborts. The "no log file" message goes through log::warn! (standard error only by then); the panic hook's fallback writes to standard error with write_fmt and ignores the error. Same fix as storytold/vectorcraft#465. --------- Co-authored-by: Brandon Thomas <shared2@storyteller.ai> |
||
|
|
f2a8420679 |
Default Windows startup to DirectX 12 (#50)
eframe's default wgpu instance enables PRIMARY | GL on Windows. Creating the OpenGL backend can crash inside AMD's atio6axx.dll before the window appears, so the app exits silently at launch. When WGPU_BACKEND is not set, the Windows instance now enables only DirectX 12; an explicit WGPU_BACKEND is still honoured. macOS, Linux and web are unchanged. Same fix as storytold/designcraft#168 and storytold/filmcraft#179. Claude-Session: https://claude.ai/code/session_01LyVbT6Vv4BwWZ4hY8973qD Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
e04372aa83 |
README Downloads: where to get it first, then builds with Windows before macOS (#26)
Also fix the .deb/.rpm description in packaging/linux/nfpm.yaml, which still described PhotoCraft. Co-authored-by: Brandon Thomas <shared2@storyteller.ai> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
b830fae017 |
Release: Flatpak x86_64 + aarch64 bundles, AppImage zsync auto-update, README Downloads (#22)
- packaging/linux/package.sh: embed gh-releases-zsync update information in each AppImage (appimagetool -u) and write the .zsync beside it; the Linux job installs zsync and checks both. - New flatpak job (x86_64 on ubuntu-24.04, aarch64 on ubuntu-24.04-arm) repackages the Linux tarball with packaging/linux/flatpak-bundle.sh and ai.storyteller.wordcraft.bundle.yml; no Rust build, no release environment. The release job needs it. - version, Linux and web jobs drop `environment: release` (they sign nothing), so a branch workflow_dispatch dry-runs every unsigned job; the release job still needs the signed jobs. - FreeBSD release build embeds craft-fonts like the other desktop builds and ships its licences. - Flathub manifest: same finish-args as the bundle (adds xdg-documents), builds the CLI too; packaging-lint checks both manifests agree. - README: Downloads section; docs/releasing.md updated. Co-authored-by: Brandon Thomas <shared2@storyteller.ai> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
5dce7f5ed1 |
Rename PrintCraft to PdfCraft (storytold/pdfcraft) (#3)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
6e9dc4bab4 |
M7/M14: comment balloons in the margin; ROADMAP alpha and parity estimates; README Review and Layout screenshots; cargo xtask alias
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
f3dbc31a57 |
README with screenshots, Crafting Apps table, community links; proofing ignores deletions/objects; comment shading; hhea line metrics; watermark tuning
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
4e1fb3aba9 | first commit |