Commit Graph
1045 Commits
Author SHA1 Message Date
pakiatandClaude Opus 5.5 2df2bfc30e Show fresh SEQ, STYLEREF and REF results in PDF export and printing (#5162)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 16:01:58 +01:00
ReesandClaude Opus 5.5 958867b7e8 Walk Print Markup balloon anchors once (#3614) (#4785)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 15:51:39 +01:00
LQRDandClaude Opus 5.5 604ac6ddb2 #641: print N-up sheets and folded booklets (#3916)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 15:29:12 +01:00
ReesandClaude Opus 5.5 ed231fd027 Walk Print Markup comment objects once (#3614) (#4744)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 14:49:31 +01:00
VoiceLessQ 560565cdd7 Audit fixes for 12 issues: import limits, escaping, link schemes, table depth (#3862) 2026-11-04 14:13:36 +01:00
.CooCoo 688cce4731 Read Mode: ink and drag previews follow the Page color, which is kept between entries (#4228) 2026-11-04 13:41:06 +01:00
6ec85141d5 Arabic interface: mirror the remaining label/field dialogs (#5449)
* Arabic interface: mirrored right-to-left window and Arabic UI fonts

Adds the Arabic (`ar`) interface language's code: its catalogs are craft-i18n's
`locales/ar`, so this changes no catalog.

- `ar` is registered in `i18n::LANGUAGES` and `Lang::rtl()` says it is written
  right to left; its translations are used as written (egui's text layout
  orders each line's bidi text itself). A ribbon location reads from the right
  with a leftwards mark.
- `rtl.rs`: the window is mirrored. Containers open in `rtl::root`; columns,
  grids, checkboxes, radio buttons, menus, rows, panels, the dialog tab strip
  and the ribbon's scrolling row follow the language's direction. Title bar,
  status bar, ribbon tabs and groups, File pages (including Print, with the
  settings on the right and a solid scrollbar gutter), dialogs, menus and the
  task panes (their docking edge swaps) are laid out from the right. egui's
  `Grid` panics in a right-aligned layout, so grids go through `rtl::grid`.
- Arabic UI font fallback: the craft-fonts Arabic face, else an installed
  Arabic font, loaded when the interface is Arabic.
- The "Auto (200%)" size label keeps its percent sign inside the isolated
  number.
- Tests: Arabic locale, saved preference and lookup order on fixture catalogs;
  an interface audit (skipped without the craft-i18n Arabic catalog) that lays
  the app out right to left at several widths, checks tab, group, pane, Print
  and Go To positions and that nothing panics.

The Arabic work builds on Abdelhaq El Amraoui's mirrored-interface PR (#737).

Co-Authored-By: Abdelhaq El Amraoui <abdelhaqelamraoui@gmail.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: pin craft-i18n at a commit with the Arabic catalog; review fixes

- craft-i18n.rev and the Flatpak manifest pin 19358491 (craft-i18n main), the
  first commit line that has locales/ar/wordcraft.tsv. The old pin had no
  Arabic catalog, so `ar` was registered but not embedded and two i18n tests
  (the_language_setting_is_a_ui_command_and_persists,
  the_languages_offered_are_the_embedded_ones_of_the_list) failed in CI.
- The Arabic font fallback is requested for any right-to-left interface
  (`Lang::rtl()`), not only after the language picker sets the flag, so an
  automatic or saved Arabic gets the installed Arabic face.
- The file browser, the update window and Reading Mode's toolbar run their
  bodies in `rtl::root`, so their far-side buttons and rows are mirrored.
- A group in a right-to-left ribbon row is measured from the right edge: the
  cursor's left edge is negative infinity there, so its width was NaN and the
  ribbon planner dropped every group, never compacting a narrow Arabic window.
  A narrow window now folds groups into drop-downs.
- The mirrored checkbox and radio marks are labelled by their text, so screen
  readers name them.
- Tests: group width in a right-to-left row; the Arabic interface audit checks
  Reading Mode's toolbar.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: ask for the installed Arabic font separately from the CJK one

A previous commit made every right-to-left interface request the installed CJK
fallback font (`system_cjk`) so that the installed Arabic font would load. That
also made every Arabic launch read a large system CJK font file when no
craft-fonts input is embedded (the Flatpak build has none).

`install_ui_fonts` now passes a separate `system_arabic` flag (`Lang::rtl()`):
the installed Arabic font is read for it, and `system_cjk` is again set only
by a CJK interface or by CJK text on screen. `WordApp::fonts_system_arabic`
remembers what was installed, so a language change reinstalls the fonts.

Tests: the_installed_arabic_font_is_asked_for_by_arabic_alone (the Arabic flag
adds the installed font only when none is embedded, and the CJK request alone
adds no Arabic font). Checked a headless screenshot of the Arabic interface
without craft-fonts: the installed Arabic font draws the labels.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix the AutoSave switch knob: on is at the right, mirrored in Arabic

The title bar's AutoSave knob was placed with `lead_x(rtl == on, ..)`, which
reverses main's mapping in both directions: left to right it drew the knob at
the left when the switch was on, and right to left at the right. main draws it
at the right when on and at the left when off, so the mirrored interface must
draw it at the left when on: `rtl != on`.

The position is now `autosave_knob_x(rtl, on, track)`, pinned by a test for all
four cases. A headless screenshot of the off switch shows the knob at the left
in English and at the right in Arabic.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: file names and paths in right-to-left lines; kerning row order

Tester feedback on the Arabic interface:

- File > Open's Recent list, the built-in file browser and the title bar drew
  file names and paths raw, from the left edge. In an Arabic line the marks of
  a name ("(نهائي) 2.docx") and the folders of a path with Arabic parts were
  scrambled. Rows now start at the side reading starts from (`rtl::lead_x`),
  names go through `i18n::isolate` (a first-strong isolate, with a left-to-right
  mark before the extension so `2.docx` stays `2.docx`) and paths through
  `i18n::isolate_path` (a left-to-right isolate with a mark after every
  separator, so neighbouring Arabic folders do not swap). Other languages get
  the text untouched; saved and spoken text never carries the marks.
- Font dialog, Kerning row: the dialog's grid is drawn left to right inside a
  right-to-left window, so "Points and above" came after its number; in an
  Arabic interface it now comes first, so the line reads "14 نقطة فأكثر" from the
  right. (The grid's columns themselves still keep their left-to-right order.)

Tests: names_and_paths_are_isolated_in_a_right_to_left_interface.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: mirror through craft_ui::direction and Style::right_to_left

The suite's craft-ui now has the direction helpers (`craft_ui::direction`) and
its egui fork a `Style::right_to_left` that mirrors egui's own chrome. Use them
instead of our parallel wrappers:

- `rtl::sync(ctx)` applies the interface direction every frame the language's
  changes (`direction::apply`): it sets the shared direction state and
  `Style::right_to_left` on every theme, which draws check boxes and radio
  buttons with the mark at the reading start, mirrors submenus, scroll bars,
  title bars and the combo boxes' arrows (the Print page's choice lists, the
  font list) and opens combo menus from the right.
- `rtl::checkbox`, `radio_value`, `radio` and `indeterminate_checkbox` are
  gone: about 200 call sites use plain `ui.checkbox`, `ui.radio_value`, ... and
  egui does the mirroring (and names the control by its text, as a plain widget).
- `lead_x`, `lead_center`, `lead_top`, `start_panel` and `end_panel` delegate to
  `craft_ui::direction`. `root`, `flows`, `island`, `grid`, `menu`, `vertical`,
  `far_side` and the other layout helpers stay: the shared crate has no
  equivalent that fits them.

Visual changes: the combo boxes' drop-down arrows and lists are mirrored in
Arabic; nothing changes in left-to-right languages (checked headless
screenshots of the English main window, Font dialog and Print page).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Recent files and the file browser: full path on hover, long names keep their start

Review feedback:

- Each row of File > Open's Recent list shows the document's full path as its
  tooltip (the path line under the name can be longer than the row).
- A long name in the built-in file browser is laid out in one row, with an
  ellipsis at its end, from the side reading starts from, instead of being
  clipped at the row's edge: in a right-to-left interface the old text anchored
  at the right edge cut the end of an Arabic name and the start of a Latin one.
  The whole name is the row's tooltip when it was shortened.

Checked headless screenshots of the file browser with a long English and a long
Arabic name.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Font combos in a right-to-left row: the arrow joins its field on the left

The ribbon's font name and size boxes are drawn from a field and a separate
arrow box that share one outline: the field is square and the arrow's box is
rounded on the side where the arrow goes, painted a border width under the
field. That assumed the arrow is right of the field. In a right-to-left row
(the Arabic ribbon) the arrow comes after the field on its left, so the field
was square on the wrong side and the arrow box rounded on the side facing the
field: two boxes with a gap-like seam, the arrow looking outside the frame.

`arrow_box_shape(rtl, ..)` mirrors the radii and the underlap, and the field's
square corners are chosen by the row's direction (the nw/sw pair in right to
left). Left-to-right rows are drawn exactly as before (English before/after
crops are identical).

Test: the_arrow_box_is_rounded_away_from_its_field.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Pin craft-i18n 4612850 (merged Arabic WordCraft rows, craft-i18n#76)

The pin and the Flatpak manifest commit move from 1935849 to 4612850, which is on
craft-i18n main and adds the 70 Arabic rows this branch relies on.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Pin craft-i18n cac2cf0 (Arabic number agreement and status-bar rows)

Moves the pin and the Flatpak manifest commit from 4612850 to the current craft-i18n
main, which includes craft-i18n#95 (48bed03) and #81 (ef58ff3).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic: isolate paths shown beside labels; mirror the Print page zoom

File > Info shows Location as its own left-to-right path label (cut short with the full path on hover, not wrapped), and the open-failure, Exported and dictionary-file messages isolate their paths. The Print preview zoom puts minus at the slider's left end and plus at its right in Arabic, as the status bar does.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic: mirror the label/field rows of the Font, Info, Paragraph, Page Setup, Insert Table and Options forms

rtl::Table lays a form out as an egui Grid in a left-to-right interface (same id, columns and spacing, so the output is unchanged) and, where the interface is mirrored, with each row's cells running from the right, every column as wide as its widest cell. File > Info puts Properties at the right and Statistics after it, and the Font dialog's kerning row reads 14 points and above.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Docs: record the mirrored Arabic interface in the roadmap, gaps and localization parity

Progress log, the Arabic language row, gap 11 and the status lines and revision histories of the three docs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: Insert Hyperlink, Word Count, Phonetic Guide, New Style, Modify Style, Encrypt, merge rule and Match Fields dialogs read right to left

Their label-and-field rows use rtl::Table, so in a mirrored interface the label is at the right with its field to its left. rtl::Table gains striped() for Match Fields. English renders are pixel-identical (only a caret-blink strip differs in an untouched dialog).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: Line Numbers, Hyphenation, Drop Cap, Caption, Cross-reference, Index, Mark Index Entry and Source dialogs read right to left

Their label-and-field rows use rtl::Table (label at the right, field to its left). English renders are pixel-identical.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: Picture Size, Split Cells, Convert Text to Table, Footnote and Endnote, Table Properties, Cell Options and Custom Properties dialogs read right to left

Their label-and-field rows use rtl::Table. Picture Size's Height and Width pairs read Height first at the right. English renders are pixel-identical.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: Define New Multilevel List, Track Changes Options, content control properties, custom colours and table style dialogs read right to left

Label, field and swatch rows use rtl::Table. English renders are pixel-identical.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: Columns widths, Special Characters, Compare, AutoCorrect and About Models tables read right to left

Table columns now start at the right edge (rtl::Table gains top(), min_row_height() and an unset column count). About > Models stays a left-to-right scroll box with its columns listed from the right. English renders are pixel-identical (only the caret blink differs).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: table-of-contents styles, recipient filter and sort, and the ribbon Paragraph group read right to left

rtl::Table now stacks its rows top to bottom whatever way the area around it runs (a ribbon group lays out in a row). English renders are pixel-identical (caret blink and a status toast differ in untouched dialogs). The TOC options and recipient filter/sort rows are converted by pattern and not seen in an image.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: Columns preset tiles and Preview label, Macros, Add/Remove arrows, Zoom slider and the Recipient List grid

A preset tile is as wide as its caption and centres it (the long Arabic captions ran into the next tile); the Preview column keeps its width so its label no longer wraps letter by letter; Macros puts the name box and list at the reading start with the buttons beside them; the Add >> and << Remove arrows swap in a mirrored interface so they point the way the items move; the Zoom slider is drawn left to right as in English; the Recipient List data grid scrolls left to right instead of running past the left edge. English renders are pixel-identical.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: the chart type and SmartArt layout galleries list their tiles from the right

The chart type dialog, the Insert SmartArt dialog and the ribbon's SmartArt Layouts gallery use rtl::Table rows, so the first tile sits at the reading start. English renders are pixel-identical.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Take main's panes/host.rs after the merge

The merge kept a use of mirrored() that main's pane-dock fix removed; this branch does not touch the panes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: Columns preset captions are translated in the mirrored tile

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic: one Arabic and one French row in the localization parity table; About > Models columns read from the right

The merge left the Arabic and French rows twice in docs/localization-parity.md; each
is now a single row (main's current French text, the Arabic row with the dialogs
note). About > Models keeps main's fitted table but lists its columns, their
alignments and grow weights reversed when the interface is mirrored, so Company
starts at the reading edge. The credits.rs change comes from tareq's helper merge.

Co-authored-by: tareq <tareq.halaby@gmail.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* About > Models: the mirrored table keeps its own widths and scroll position

The columns are listed in reverse when the interface is mirrored, and egui keeps the
resizable column widths and the scroll offset by id. A language switched at run time
would apply one direction's widths to the other's columns, so the mirrored table uses
its own id.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: About > Models alignment mirrors as its comment says

The mirrored Models table reversed the per-column right-align flags but
did not negate them, so in Arabic the text columns stayed left-aligned and
the counts right-aligned, the opposite of the comment ("counts line up on
the right (left in RTL)"). Negate after reversing so the text sits at the
reading edge and the counts on the left. Keep this line when touching
models_ui.

* About > Models: a mirrored table that overflows opens at its reading edge

The reversed Arabic table puts Company in the rightmost column, but the
horizontal scroll area started at the left, so when the table was wider
than the dialog (narrow window, widened columns) Company and Model were
offscreen. Stick the scroll area to the right in a mirrored interface.

---------

Co-authored-by: Abdelhaq El Amraoui <abdelhaqelamraoui@gmail.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: email <email@email.com>
Co-authored-by: tareq <tareq.halaby@gmail.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-04 13:36:55 +01:00
midasdfandClaude Opus 5.5 2d6dff96cc Layout: 行頭禁則 lists small kana and the prolonged sound mark (JIS X 4051 §4), with the emergency-break gap documented (#2558)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 13:31:39 +01:00
.CooCoo e847b2e5e3 AutoFormat: a tracked heading or border line replaces another author's formatting change (#4231) 2026-11-04 12:27:08 +01:00
Aleksander HelgakerandClaude Opus 5.5 ba58e70cc8 Flag document fonts that aren't installed (#4770)
* Gap 4: flag document fonts that aren't installed

The font box (ribbon, mini toolbar, both Font dialog boxes) shows a
warning mark when the current font isn't installed; its hover note
names the font drawn instead. The status bar says "N fonts not
installed" and lists each with the faces drawn instead, plus Add Font….
Agents get `font.missing` and `format.state.fontShownAs`.

Layout records, where it picks a face per text segment, the fonts the
shown text asks for that aren't installed and the faces drawn instead
(ParaLayout::substituted, DocLayout::substituted_fonts), so hidden
text, unused styles and orphaned stories never count; list labels,
field results and East Asian and complex-script text do, and so does a
missing roman font drawn in Cambria. Metric-compatible substitutes and
symbol fonts drawn as Unicode aren't flagged. Bounded for hostile
files: 64 pairs a paragraph, 1024 a document, names kept to 256
characters, 20 rows in the popup.

Ported from alehel/wordcraft#1 onto current main; English strings only
(translations belong in storytold/craft-i18n).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Gap 4: missing-font review fixes

- Judge a padded font name by the face layout drew for it, and skip blank names.
- Name the face CJK text is drawn in for a missing East Asian font, not Cambria.
- Keep the missing-fonts list per window, so several windows don't rebuild it every frame.
- Expose the font box's warning to screen readers as its description.
- Count missing fonts with craft-i18n plurals (`i18n::tn`).
- One table of metric twins (`fonts::word::METRIC_TWINS`): a missing font is drawn in an
  installed twin first, and the warning reads the same table.
- Find the status-bar item by part of its label in the click test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Gap 4: warn for a font picked at the caret; drop fonts of hidden list items

- At a collapsed caret the font box warns for a missing font typing will use, also at the end
  of text in another font (it waited for the first letter).
- A list item that shows nothing (#3982) reports no missing font: its number was shaped, and
  its font recorded, before layout dropped it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Gap 4: say where Add Font… is, and that it needs the font file

The font box's note said "Add Font… installs it": Add Font… opens a file picker at the end of
the list, so it only helps with a font file at hand.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Gap 4: docs say the popup lists 20, and when the font box warns ahead

CodeRabbit review: the status-bar popup lists the first 20 missing fonts, then a count; the font
box also warns at a collapsed caret for a font no shown text uses yet; `fontShownAs` is the
font's substitute, fallback faces aside.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Gap 4: the Font dialog warns for a missing font over a selection

CodeRabbit review: the dialog's boxes show the fonts OK applies, which no shown text may use
yet (an Asian text font over Latin text, a font typed into the dialog), so they name the
substitute whatever is selected. The ribbon's box over a selection still reads the list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Gap 4: the Asian font box names the face CJK text gets

CodeRabbit review: the status bar's list is by font name, so for a font Latin text also uses
it named the Latin text's substitute. The Asian text box now always looks up the face layout
draws Chinese, Japanese and Korean text in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Gap 4: gaps.md status on the current line, missing-font scope and twin wording

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Gap 4: gaps.md says which missing fonts are flagged and what font.missing lists

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Gap 4: font.missing lists what the current view lays out

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 11:48:48 +01:00
Martin Ball 96e63ee96b Merge remote-tracking branch 'origin/fix/missing-pack-bar' into fix/options-language
; Conflicts:
;	docs/localization-parity.md
2026-11-04 02:42:49 +00:00
Dylan M. Taylor d9e2b92e41 Merge main into fix/missing-pack-bar
Keep the missing-pack-bar entry, the one-language-list entry and main's
craft-i18n 9d6d54d region-name pin in the parity changelog.
2026-11-03 21:39:38 -05:00
Dylan M. Taylor 03fba6cb10 Merge main into fix/one-language-list
Resolve the localization-parity changelog conflict by keeping both the
one-language-list entry and main's craft-i18n 9d6d54d region-name pin.
2026-11-03 21:18:15 -05:00
Martin BallandClaude Opus 5.5 ea25e5dd3a CP4.3: craft-i18n.rev at 9d6d54d (craft-i18n#145): region names and the Language (Region) template in 35 locales (#5522)
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 03:12:45 +01:00
Martin BallandClaude Sonnet 5.5 68512842aa CP4.3: merge fix/one-language-list
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco
2026-11-04 01:24:26 +00:00
Martin BallandClaude Sonnet 5.5 3e9e36796c CP4.3: localization-parity proofing bullet reads once
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco
2026-11-04 01:24:26 +00:00
Martin BallandClaude Sonnet 5.5 3122c16e38 CP4.3: merge fix/missing-pack-bar
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco
2026-11-04 01:24:26 +00:00
Martin Ball 3b37679f7c CP4.3: merge fix/missing-pack-bar
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco

; Conflicts:
;	ROADMAP.md
;	docs/gaps.md
;	docs/localization-parity.md
2026-11-04 01:14:59 +00:00
Martin BallandClaude Sonnet 5.5 fa37c9adbe CP4.3: gap 8 names the missing-pack bar on a fresh install and the caret's typing language
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco
2026-11-04 01:14:30 +00:00
Martin Ball 26c662961d CP4.3: merge fix/one-language-list
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco

; Conflicts:
;	ROADMAP.md
;	docs/gaps.md
;	docs/localization-parity.md
2026-11-04 01:14:25 +00:00
Martin BallandClaude Sonnet 5.5 29f99006e0 CP4.3: a language and region name is translated in parts, not looked up whole
Swedish (Finland) is built at run time, so no catalog row can match it. One helper
(ribbon::display_name) now translates the language, the region and the {language} ({region})
template separately and joins them; the Set Proofing Language list, the Language menu, the status
bar and the dialog all use it. English output is unchanged and matching never uses a name.
gap 8 no longer describes the missing-pack bar, which is in its own branch.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco
2026-11-04 01:14:05 +00:00
Martin Ball 26a8182e91 CP4.3: merge origin/main (craft-i18n at cde4900)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco

; Conflicts:
;	ROADMAP.md
;	docs/gaps.md
;	docs/localization-parity.md
2026-11-04 01:00:54 +00:00
Martin BallandClaude Opus 5.5 d64ef7c3f9 CP4.3: craft-i18n.rev at cde4900 (craft-i18n#136): Options › Language, missing-pack bar and Language pack language-name rows in 35 locales (#5518)
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 00:57:30 +00:00
Martin BallandClaude Sonnet 5.5 bff0d1d925 #3867 follow-up: header repeats count canvas members, one budget per layout; contours and chain widths don't depend on cache history (#4385)
* #3867: review — header repeats, picture outlines and linked-box widths bounded the same way every layout

- Header repeats: a Clip (floating Drawing Canvas) counts its members, depth-bounded, so a 1000-member canvas no longer counts as one item (CodeRabbit thread 4373103686); the budget is per layout (Ctx), not per table.
- Tight-wrap outlines: each cache entry stores its picture's pixel cost; a cached hit is charged to the layout's decode budget like a decode, so cold and warm layouts (and the CLI) wrap alike.
- Linked boxes: widths are budgeted by laid-out work (MAX_FLOW_WORK), not 16 widths, so ordinary stories keep exact widths for every box.
- header_rows.contains -> index compare; layout-parity doc revision.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HUodYU9r4mPHed4pPsjHC2

* #3867: review — a picture that fails to decode still costs its pixels when cached; header repeats restored on retry

- contour: Alphas records the pixels each picture charged (costs map), also when the body then fails to decode, so the cache entry's cost is right and warm layouts charge it like cold ones.
- Snap saves and restores ctx.header_repeats so balance_pass retries don't keep their charge.
- Tests: truncated large PNG cold vs warm; canvas header row end to end through place_table; linked-chain bound <= 8; vertical box's layout differs from every other box's.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HUodYU9r4mPHed4pPsjHC2

* #3867: CodeRabbit — header and linked-box budgets count every clip descendant

placed_cost counts iteratively (explicit stack, stops past the limit) and is shared by flow_work.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HUodYU9r4mPHed4pPsjHC2

* #3867: docs — progress log, gap 20 note for layout resource caps and linear-time passes

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HUodYU9r4mPHed4pPsjHC2

* #3867: review — roadmap gives each cap its unit: header items, wrap-cache pixels, linked text box lines and items

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* #3867: CodeRabbit — the vertical-box check runs past the work cap too

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #3867: review — a linked chain's work counts the story it lays out, not only the lines it shows

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #3867: review — header-row cost import follows main's explicit layout imports (#4501)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #3867: review — a test pins the header repeats that column balancing gives back; docs keep main's caps row and both gap status lines

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-04 00:45:19 +00:00
Martin Ball 8fb57e1f6b Merge branch 'fix/missing-pack-bar' into fix/options-language 2026-11-04 00:12:22 +00:00
Martin Ball 9819939d98 Merge branch 'fix/one-language-list' into fix/missing-pack-bar 2026-11-04 00:12:20 +00:00
Martin BallandClaude Opus 5.5 94b89d95d6 CP4.3: review — Set Proofing Language lists every built-in and Language pack language, not 38 (CodeRabbit)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco
2026-11-04 00:12:18 +00:00
Martin BallandClaude Sonnet 5.5 c45945a2ea CP4.3: Options > Language: Your languages with proofing status, Add a language picker, Set as default
The Dictionaries folder moves here from Proofing with the Dictionary files list (#1063) kept. Set as
default sets only the saved default proofing language (the new pure review.language.preferred command), and
proof.packs returns the languages rows.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco
2026-11-03 23:59:42 +00:00
Martin BallandClaude Sonnet 5.5 efb5071526 CP4.3: the missing-pack bar works on a fresh install and counts the caret's language
With no list of packs yet the bar offers a language with no dictionary and Install fetches the
list, then the pack. The caret's typing language counts, the spelling context menu heading is in
the interface language, and closing the bar is remembered per document, pack locale and tag.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco
2026-11-03 23:58:37 +00:00
Martin BallandClaude Sonnet 5.5 ae151ff341 CP4.3: one language list: Language pack languages in Set Proofing Language, Review > Language and the status bar
Every published pack is named in English, Valencian is ca-ES-valencia, and rows are matched by
tag (language, script, region, variant), never by the name shown. One region helper
(packs::is_region, packs::without_region) next to pack_for_tag serves the engine and the UI.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco
2026-11-03 23:58:24 +00:00
Martin BallandClaude Opus 5.5 682ce4318a CP4.3: craft-proof pin at craft-libs 01315d9: French elision suggestions first; Valencian reads its pack (#5509)
* CP4.3: craft-proof pin at craft-libs main 01315d9 (#589, #590): French elision suggestions first; ca-ES-valencia reads the ca-valencia pack

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco

* CP4.3: review — ROADMAP has one status record; the older copy left by a merge is dropped (CodeRabbit)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco

* CP4.3: review — French is proofed from its Language pack in the support tables, not "no proofing" (CodeRabbit)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 23:06:35 +00:00
Luis VacaandClaude Opus 5.5 a591879294 Comments: a long comment's card and balloon stop at ten lines (#3382) (#3899)
* #3382: a long comment's card and balloon stop at ten lines

A comment or reply field, in the Comments pane and in a selected balloon,
is at most ten lines tall and scrolls beyond that, keeping its caret in
view. A balloon that isn't selected shows the first ten lines of the
comment and of each reply and cuts off the rest; clicking it opens the
scrolling field. The buttons and the next comment stay in view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #3382: record the ten-line comment cap in the UI parity doc; test the drawn rows

The Comments entry of the UI parity doc notes that a long comment's card,
balloon and fields stop at ten lines. A new test checks what an unselected
long balloon paints: its first ten rows inside the card's clip and none of
the rows after them, in Latin and Arabic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #3382: check the shown balloon rows start inside the clip

The drawn-rows test now also checks that each of the first ten rows starts
at or below the top of the balloon body's clip, so a clip that hid the
first rows would fail it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 20:45:39 +00:00
Dylan M. TaylorandBrandon Thomas ae5c65b9dd Paste: charge copied text box stories for the formatting they clone (#5379)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-03 09:05:14 -05:00
1f8f9e8e2c DOC import: keep one override per table cell instead of a copy per repeated sprm (#5374)
* fix(docbin): keep one override per table cell instead of a copy per repeated sprm

* DOC import: vertical alignment reads only the cells a row can hold, like the other cell-range sprms

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>
2026-11-03 09:04:13 -05:00
Dylan M. TaylorandBrandon Thomas cf23ca73c9 DOC import: attach sections to their paragraphs through an index of paragraph ends (#5373)
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-03 09:03:10 -05:00
1ff68d64e3 i18n: Arabic interface with mirrored RTL shell (+ parity docs) (#5370)
* Arabic interface: mirrored right-to-left window and Arabic UI fonts

Adds the Arabic (`ar`) interface language's code: its catalogs are craft-i18n's
`locales/ar`, so this changes no catalog.

- `ar` is registered in `i18n::LANGUAGES` and `Lang::rtl()` says it is written
  right to left; its translations are used as written (egui's text layout
  orders each line's bidi text itself). A ribbon location reads from the right
  with a leftwards mark.
- `rtl.rs`: the window is mirrored. Containers open in `rtl::root`; columns,
  grids, checkboxes, radio buttons, menus, rows, panels, the dialog tab strip
  and the ribbon's scrolling row follow the language's direction. Title bar,
  status bar, ribbon tabs and groups, File pages (including Print, with the
  settings on the right and a solid scrollbar gutter), dialogs, menus and the
  task panes (their docking edge swaps) are laid out from the right. egui's
  `Grid` panics in a right-aligned layout, so grids go through `rtl::grid`.
- Arabic UI font fallback: the craft-fonts Arabic face, else an installed
  Arabic font, loaded when the interface is Arabic.
- The "Auto (200%)" size label keeps its percent sign inside the isolated
  number.
- Tests: Arabic locale, saved preference and lookup order on fixture catalogs;
  an interface audit (skipped without the craft-i18n Arabic catalog) that lays
  the app out right to left at several widths, checks tab, group, pane, Print
  and Go To positions and that nothing panics.

The Arabic work builds on Abdelhaq El Amraoui's mirrored-interface PR (#737).

Co-Authored-By: Abdelhaq El Amraoui <abdelhaqelamraoui@gmail.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: pin craft-i18n at a commit with the Arabic catalog; review fixes

- craft-i18n.rev and the Flatpak manifest pin 19358491 (craft-i18n main), the
  first commit line that has locales/ar/wordcraft.tsv. The old pin had no
  Arabic catalog, so `ar` was registered but not embedded and two i18n tests
  (the_language_setting_is_a_ui_command_and_persists,
  the_languages_offered_are_the_embedded_ones_of_the_list) failed in CI.
- The Arabic font fallback is requested for any right-to-left interface
  (`Lang::rtl()`), not only after the language picker sets the flag, so an
  automatic or saved Arabic gets the installed Arabic face.
- The file browser, the update window and Reading Mode's toolbar run their
  bodies in `rtl::root`, so their far-side buttons and rows are mirrored.
- A group in a right-to-left ribbon row is measured from the right edge: the
  cursor's left edge is negative infinity there, so its width was NaN and the
  ribbon planner dropped every group, never compacting a narrow Arabic window.
  A narrow window now folds groups into drop-downs.
- The mirrored checkbox and radio marks are labelled by their text, so screen
  readers name them.
- Tests: group width in a right-to-left row; the Arabic interface audit checks
  Reading Mode's toolbar.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: ask for the installed Arabic font separately from the CJK one

A previous commit made every right-to-left interface request the installed CJK
fallback font (`system_cjk`) so that the installed Arabic font would load. That
also made every Arabic launch read a large system CJK font file when no
craft-fonts input is embedded (the Flatpak build has none).

`install_ui_fonts` now passes a separate `system_arabic` flag (`Lang::rtl()`):
the installed Arabic font is read for it, and `system_cjk` is again set only
by a CJK interface or by CJK text on screen. `WordApp::fonts_system_arabic`
remembers what was installed, so a language change reinstalls the fonts.

Tests: the_installed_arabic_font_is_asked_for_by_arabic_alone (the Arabic flag
adds the installed font only when none is embedded, and the CJK request alone
adds no Arabic font). Checked a headless screenshot of the Arabic interface
without craft-fonts: the installed Arabic font draws the labels.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix the AutoSave switch knob: on is at the right, mirrored in Arabic

The title bar's AutoSave knob was placed with `lead_x(rtl == on, ..)`, which
reverses main's mapping in both directions: left to right it drew the knob at
the left when the switch was on, and right to left at the right. main draws it
at the right when on and at the left when off, so the mirrored interface must
draw it at the left when on: `rtl != on`.

The position is now `autosave_knob_x(rtl, on, track)`, pinned by a test for all
four cases. A headless screenshot of the off switch shows the knob at the left
in English and at the right in Arabic.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: file names and paths in right-to-left lines; kerning row order

Tester feedback on the Arabic interface:

- File > Open's Recent list, the built-in file browser and the title bar drew
  file names and paths raw, from the left edge. In an Arabic line the marks of
  a name ("(نهائي) 2.docx") and the folders of a path with Arabic parts were
  scrambled. Rows now start at the side reading starts from (`rtl::lead_x`),
  names go through `i18n::isolate` (a first-strong isolate, with a left-to-right
  mark before the extension so `2.docx` stays `2.docx`) and paths through
  `i18n::isolate_path` (a left-to-right isolate with a mark after every
  separator, so neighbouring Arabic folders do not swap). Other languages get
  the text untouched; saved and spoken text never carries the marks.
- Font dialog, Kerning row: the dialog's grid is drawn left to right inside a
  right-to-left window, so "Points and above" came after its number; in an
  Arabic interface it now comes first, so the line reads "14 نقطة فأكثر" from the
  right. (The grid's columns themselves still keep their left-to-right order.)

Tests: names_and_paths_are_isolated_in_a_right_to_left_interface.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic interface: mirror through craft_ui::direction and Style::right_to_left

The suite's craft-ui now has the direction helpers (`craft_ui::direction`) and
its egui fork a `Style::right_to_left` that mirrors egui's own chrome. Use them
instead of our parallel wrappers:

- `rtl::sync(ctx)` applies the interface direction every frame the language's
  changes (`direction::apply`): it sets the shared direction state and
  `Style::right_to_left` on every theme, which draws check boxes and radio
  buttons with the mark at the reading start, mirrors submenus, scroll bars,
  title bars and the combo boxes' arrows (the Print page's choice lists, the
  font list) and opens combo menus from the right.
- `rtl::checkbox`, `radio_value`, `radio` and `indeterminate_checkbox` are
  gone: about 200 call sites use plain `ui.checkbox`, `ui.radio_value`, ... and
  egui does the mirroring (and names the control by its text, as a plain widget).
- `lead_x`, `lead_center`, `lead_top`, `start_panel` and `end_panel` delegate to
  `craft_ui::direction`. `root`, `flows`, `island`, `grid`, `menu`, `vertical`,
  `far_side` and the other layout helpers stay: the shared crate has no
  equivalent that fits them.

Visual changes: the combo boxes' drop-down arrows and lists are mirrored in
Arabic; nothing changes in left-to-right languages (checked headless
screenshots of the English main window, Font dialog and Print page).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Recent files and the file browser: full path on hover, long names keep their start

Review feedback:

- Each row of File > Open's Recent list shows the document's full path as its
  tooltip (the path line under the name can be longer than the row).
- A long name in the built-in file browser is laid out in one row, with an
  ellipsis at its end, from the side reading starts from, instead of being
  clipped at the row's edge: in a right-to-left interface the old text anchored
  at the right edge cut the end of an Arabic name and the start of a Latin one.
  The whole name is the row's tooltip when it was shortened.

Checked headless screenshots of the file browser with a long English and a long
Arabic name.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Font combos in a right-to-left row: the arrow joins its field on the left

The ribbon's font name and size boxes are drawn from a field and a separate
arrow box that share one outline: the field is square and the arrow's box is
rounded on the side where the arrow goes, painted a border width under the
field. That assumed the arrow is right of the field. In a right-to-left row
(the Arabic ribbon) the arrow comes after the field on its left, so the field
was square on the wrong side and the arrow box rounded on the side facing the
field: two boxes with a gap-like seam, the arrow looking outside the frame.

`arrow_box_shape(rtl, ..)` mirrors the radii and the underlap, and the field's
square corners are chosen by the row's direction (the nw/sw pair in right to
left). Left-to-right rows are drawn exactly as before (English before/after
crops are identical).

Test: the_arrow_box_is_rounded_away_from_its_field.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Pin craft-i18n 4612850 (merged Arabic WordCraft rows, craft-i18n#76)

The pin and the Flatpak manifest commit move from 1935849 to 4612850, which is on
craft-i18n main and adds the 70 Arabic rows this branch relies on.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Pin craft-i18n cac2cf0 (Arabic number agreement and status-bar rows)

Moves the pin and the Flatpak manifest commit from 4612850 to the current craft-i18n
main, which includes craft-i18n#95 (48bed03) and #81 (ef58ff3).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic: isolate paths shown beside labels; mirror the Print page zoom

File > Info shows Location as its own left-to-right path label (cut short with the full path on hover, not wrapped), and the open-failure, Exported and dictionary-file messages isolate their paths. The Print preview zoom puts minus at the slider's left end and plus at its right in Arabic, as the status bar does.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Arabic: mirror the label/field rows of the Font, Info, Paragraph, Page Setup, Insert Table and Options forms

rtl::Table lays a form out as an egui Grid in a left-to-right interface (same id, columns and spacing, so the output is unchanged) and, where the interface is mirrored, with each row's cells running from the right, every column as wide as its widest cell. File > Info puts Properties at the right and Statistics after it, and the Font dialog's kerning row reads 14 points and above.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* docs: record Arabic mirrored interface landing (#1195)

Update the language counts, Arabic parity row, gap #11, and UI/ROADMAP
status so they match the craft-i18n catalog and mirrored shell already
on this branch.

* Fix Organizer Copy arrow in RTL and refresh roadmap status.

Point the Copy glyph at the Document column when the shell is mirrored,
and bump docs/roadmap.md status/revision history for Arabic UI (#1195).

* fix(ui): keep pane dock left/right physical in RTL

ui.paneDock and view.stylesPaneDock now store and report physical window sides; only unset defaults still open on the reading-start edge. Also wrap the language-packs grid for RTL, document the contract, and load a system Arabic face for Arabic names in LTR UIs.

* docs: clarify mirrored default pane edges in RTL

Start-default panes open on the physical right in Arabic; end-default
panes open on the physical left — not every never-docked pane on the right.

* refactor(ui): one PaneState for a saved pane place

The four saved-dock arms built the same PaneState; only the place and
whether it was set explicitly differ.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* style(ui): rustfmt the panes re-exports

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: The Legend Of MTS Dev <tlo.mts.tsh@gmail.com>
Co-authored-by: Abdelhaq El Amraoui <abdelhaqelamraoui@gmail.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: email <email@email.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-03 15:00:45 +01:00
dd2a651093 References: Remove and Replace Table of Contents treat a title above a section break as Word does (#5152)
Word's TOC over entries in columns keeps its TOC Heading title in a one-column
section above a blank paragraph that ends it; Update Table moves the field into
that blank paragraph. Replace (references.toc with settings) put the new title
under the break, inside the two-column section, and Remove kept the blank
paragraph and its break.

Observed black-box in Word for Mac 16.114.3 on a synthetic document: Insert
Table of Contents keeps the title, the blank paragraph and the break and only
changes the field; Remove Table of Contents takes the title, the blank
paragraph and its break with the entries.

Replace now keeps the title above the break (renamed when a title is given)
and rebuilds the field and entries in place; Remove takes the title and the
blank section-ending paragraph with the table. A paragraph of another style
above the break stays.

Co-authored-by: Harrison Smith <harrison@hsmith.dev>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 22:47:03 -05:00
Michael MuandClaude Sonnet 5.5 ab5ee42049 A command line file's Password box survives the startup document's replacement (#5334)
When a region is chosen in File › Options, start-up replaces the first blank document with one
on that region's paper through `session.set_document`. That changes the session's active
document, but the window still showed the old one, so on the first frame `sync_document` took
the change for a switch of document and cleared the dialog. A password-protected file named on
the command line (a double-click in the file manager) had just asked for its password with
`file.open`, so the Password box was dropped before it was drawn and a blank Document1 stayed.

`WordApp::replace_startup_document` swaps the document and lets the window follow at once; the
start-up code uses it. Before the file is opened, so nothing is open to lose.

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-02 22:43:19 -05:00
Martin BallandClaude Opus 5.5 8865455cfb CP4.4: review — gap 8 and the localization parity rows say the compounding languages are packs (CodeRabbit)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCYmv6UJmY2QcuhfXco
2026-11-03 02:07:54 +00:00
Martin BallandClaude Opus 5.5 0842d4faec CP4.4: language-packs-2 pinned (75 packs, adds the compounding languages); craft-proof at craft-libs main's merge of #497 (with #496, en-AU)
- PACK_INDEX: language-packs-2 index.json, sha256 b35c7aef…, built from craft-i18n 20467b63
- craft-proof pinned at storytold/craft-libs 47c9f625 (flag-based compounding, #497; review follow-ups and en-AU, #496)
- Options › Language: ProofLang::EnAu has no Hunspell dictionary name of its own (English uses SCOWL)
- docs: Danish, German, Dutch, Swedish, Norwegian, Hungarian, Estonian, Croatian, Persian and Esperanto are packs; Mongolian and Thai stay hidden

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 01:55:16 +00:00
Dylan M. Taylor 0bb9add551 Merge main into language packs PR 2026-11-02 16:53:31 -05:00
Dylan M. Taylor 52a8a5db76 Merge main into SCOWL spelling PR 2026-11-02 16:23:38 -05:00
Dylan M. Taylor 3ce9a84f81 Merge main into proofing move PR 2026-11-02 15:57:35 -05:00
FredApps 389fa90c29 Merge remote-tracking branch 'origin/main' into pr1104
# Conflicts:
#	ROADMAP.md
2026-11-02 18:47:20 +01:00
FredApps 84b4623e14 Merge pull request #4471 from totoz64/feat/spelling-review-dialog
Review: add a Word-style Proofing task pane with clickable suggestions
2026-11-02 18:40:33 +01:00
FredApps e2bc9e017e Merge remote-tracking branch 'origin/main' into pr1104
# Conflicts:
#	docs/file-format-parity.md
2026-11-02 18:25:52 +01:00
41d46625e0 DOCX: VML horizontal rules take their line (#3956)
* DOCX: VML horizontal rules take their line

A web page's <hr> pasted into Word is a VML rule: `v:rect` with
`o:hr="t"`, often `width:0`. WordCraft took the width as written and
drew a 1 pt dot where Word draws a line across the page.

Measured on Word with a synthetic document: a rule with no width and
no `o:hrpct` spans the line inside the paragraph's indents; `o:hrpct`
is a share of it in tenths of a percent (500 = half); `o:hrpct="0"`
keeps the shape's own width; `o:hralign` places a shorter one (left,
centre, right); `fillcolor` and `stroked` apply as to any VML shape.
WordCraft now matches each case within 0.1 pt.

- wordcraft-doc: ShapeExtra::hr (HorizontalRule: share, alignment,
  Word's standard look).
- wordcraft-docx: `o:hr`, `o:hrpct`, `o:hralign`, `o:hrstd` read; a rule
  is written back as the same VML rule (DrawingML has none), and Word
  opens the re-saved file with the same lines.
- wordcraft-layout: a rule takes its whole line and is drawn at its
  share; measured for a table column it asks for no width, so it
  follows its column. (Word draws a rule in a cell at the page's text
  width, centred on the cell and past its edges; it stays in the cell
  here.)

docs/file-format-parity.md is updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Horizontal rules: only an inline, shown rule is one

Review: the rule arm of the writer ignored the shape's placement, so a
rule imported with position:absolute or visibility:hidden came back
inline and visible. Only a rule in the text and shown is read as a rule
now (a pasted <hr> is one); a positioned or hidden one stays a plain
shape, which keeps both when saved. The writer checks the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Horizontal rules: a see-through fill is kept; column measuring asks for the right width

Review: `write_hr` wrote only the fill's colour, so a rule with `v:fill
opacity` came back opaque after a save; the opacity now goes back as `v:fill`.

Review: measured for a table column, every rule asked for no width, so one of
its own width (`o:hrpct="0"`) could end up clipped by a narrow column; it now
asks for its width. AutoFit to contents measures on a line of its own width
that the rule took for a real line, so a rule sharing its line made the
column as wide as it could go; any measuring width now counts.

`Placed::Shape` boxes its extras: with the rule, `Placed` went past clippy's
large_enum_variant limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Horizontal rules: placed in what the line has left; rotation and flips kept on save

Review: a whole-line rule ignores a first-line indent or a line narrowed by a
float. Measured in Word, it does too: the width stays the share of the
paragraph's width and the rule runs past the margin, or under a float on its
right. What did differ was the placement: Word centres and right-aligns a rule
in what the line has left, with a first-line indent moving the end of that room
along, and a right-aligned rule beside a float was drawn off the page here. The
display now places it that way (`ParaLayout::rule_room`).

Review: a save dropped a rule's rotation and flips; they now go back in its
style, as Word writes them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: VML horizontal-rule revision row at the top of the history

---------

Co-authored-by: Daniele Mori <Dinasty@hotmail.it>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 10:55:20 -05:00
Fin WarmanandBrandon Thomas 4f2d0da04c Shapes: align soft-edge paint and caret opacity (#1600)
* Shapes: a solid fill keeps its transparency

A shape's fill colour can carry a:alpha, its opacity. WordCraft dropped
it, so a translucent white wash laid over a picture was drawn opaque and
hid the picture. The transparency is now read into the shape, drawn on
screen and in the PDF, and written back.

* Fix #1600 freeform and soft-edge fill opacity

* #1600: wrap canonical caret sampler signature

* #1600: format canonical integration

* #1600: assert canonical DOCX alpha round-trip

* #1600: document canonical shape opacity API

* Adapt alpha fixture to rectangle render bounds

* docs: one file-format-parity row for soft-edge fill opacity, status line

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 10:53:00 -05:00
Martin BallandClaude Opus 5.5 72327bdd36 CP4.4: pin language-packs-1 index
craft-i18n's first Language pack release is published
(https://github.com/storytold/craft-i18n/releases/tag/language-packs-1, 61 packs,
built from craft-i18n main 4504e288). PACK_INDEX now pins its index.json sha256
instead of the all-zero placeholder. Docs say which languages it covers and which
wait on craft-proof (compounding) or are excluded on licence grounds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FypgCX8LsYYE8fsj4byBm2
2026-11-02 09:40:07 +00:00
NaxvogandClaude Opus 5.5 89c0d516ae Files: documents keep their embedded alternative format chunks, and MHT opens
Word brings a document's alternative format chunks (w:altChunk) in where they
stand when it opens the file; WordCraft left them out, so a document made of
one (as generators and mail-merge tools write them) opened empty.

- docx: read_with/ReadOptions with a ChunkImporter for formats other than
  WordprocessingML; nested Word documents are read here (at most 4 deep,
  256 chunks and 512 MB of chunk bytes a file, XML depth counted on).
- doc: Document::adopt (moved from paste) brings another document's media,
  lists, styles, notes, comments and revisions along under new ids; pictures
  in groups and charts are relinked. Insert > Text from File uses it and now
  keeps the file's pictures and lists.
- engine: chunks in MHT, HTML (in their charset), RTF and plain text go
  through the format importers.
- formats: MHT web archives open (MIME, quoted-printable/base64, charsets,
  pictures by Content-Location or cid). HTML reads style element rules
  (simple selectors, cascade, budgets), paragraph margins, indents, line
  height, cell widths and borders; an opened page takes Word's web-page
  defaults (Times New Roman 12 pt, single lines, black headings, automatic
  spacing). html::decode knows the single-byte Windows code pages.

docxide-pdf suite: croatian_regulations_altchunk goes from one empty page to
Word's 8 pages, SSIM 2.7% -> 78.7%; no other document changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 07:04:31 +01:00