* Restrict Editing: forms protection keeps a form's content controls
With Filling in forms enforced (w:edit="forms"), Word greys out the
Developer tab's control buttons and Properties, and a field's shortcut
menu offers no Remove Content Control: only the fields' content can be
filled in. WordCraft refused these only outside the fillable fields, so
with the caret in one it removed the control (its content left as
plain, no longer fillable text), inserted new controls inside it, and
renamed it; only lock changes were refused.
Under forms protection, inserting any content control, Properties
(every setting) and Remove Content Control are now refused before they
run. Typing, Toggle Check Box, Choose List Item and Set Date still fill
the fields. Other protection modes are unchanged.
Observed in Word for Mac 16.113 on a protected real-world form
(72 content controls: rich text, check boxes, date pickers); the same
form filled in WordCraft opens in Word still protected, with its values,
ticks and dates.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Restrict Editing: parity row states what forms protection refuses
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Restrict Editing: correct the comment on content-control property edits in forms mode
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>
The top and bottom borders of a paragraph now take their distance plus width
in the text flow, as in Word, and the shading fills that room. Neighbouring
paragraphs with the same borders and indents make one box: the top border goes
above the first only, the bottom one below the last, and the shading and side
borders run on through the space between them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The pane drew each heading with `Button::selectable(..).truncate()`, so a heading wider than the
pane ended in an ellipsis and its text had to be read from the hover tooltip. Word wraps the row
instead.
`nav_heading` now wraps: the button takes `Button::wrap()` and a minimum size of the available width
and one row, so the label continues on further lines inside the pane, the row grows with the text,
and the pane still keeps its width. The trailing grow atom still keeps the text flush left under its
parent (#1199). The hover tooltip goes with the ellipsis: nothing is hidden now, and a word wider
than the pane is broken by the wrap instead of overflowing.
The navigation test asserts the wrap instead of the ellipsis. For a heading well past the width and
for a single word wider than the pane, the label has more than one line, is not elided, stays inside
the pane, does not widen it, and takes a taller row than a one-line heading in the same pane.
`docs/ui-parity.md` and `ROADMAP.md` record the new behaviour.
Co-authored-by: Brandon Thomas <brandon@storyteller.ai>
Every page, area and icon render built its own multi-threaded vello_cpu
RenderContext, which starts and tears down a rayon thread pool: a few
threads per keystroke while typing. Renders now take one kept context,
reset to their size, and give it back; a render that overlaps another
builds its own, and one that panics drops its context.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Insert Table of Figures now opens a Table of Figures dialog (caption label,
include label and number, page numbers, right margin, tab leader) instead of
always building a list of Figures. The label list offers the built-in labels,
the user's own and those the document's captions use, so a document can have
a list of figures beside a list of tables.
references.tableOfFigures takes includeLabel, pageNumbers, rightAlign and
tabLeader and writes the TOC switches for them (ECMA-376 17.16.5.68: \c or \a,
\n, \p). Captions are matched on their whole label (SEQ identifier), a Word
table of figures with its switches in any order (TOC \h \z \c "Figure") is
recognised, and Update Table keeps each list's leader. The table of contents
code treats any \c or \a TOC as a table of figures.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #2853: Word XML, web pages and MHTML saved as .doc open by what they hold
A Word 2003 XML Document named `.doc` went to the Word 97-2003 reader, which refused it ("Invalid
CFB file"), and the window showed a blank page. Word XML (2003 or Flat OPC), a web page and a
Single File Web Page (MHTML) under a `.doc`, `.docx` or `.rtf` name now open by what they hold,
as in Word. MHTML is read for the first time (`.mht`/`.mhtml` too): the MIME parts are split and
decoded, the page is imported as HTML in its charset and its pictures load from the other parts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #2853: leave MHTML to #1104, keep Word XML and web pages saved as .doc
#1104 adds an MHT reader (`wordcraft_formats::mht`), so this branch drops its own MHTML reader and
the `.mht`/`.mhtml` extensions instead of adding a second one. A Word XML Document or a web page
under a `.doc`, `.docx` or `.rtf` name still opens by what it holds (the #2853 fix).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #2853: a web page's signature needs its tag name to end (`<htmlish>` is other XML)
CodeRabbit: `starts_with("<html")` took XML with a root like `<htmlish>` under a `.doc` name for a
web page, though XML that isn't a Word document stays an error. `<html` and `<!DOCTYPE html` now
need white space, `>` or `/` after them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #2853: rustfmt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Layout: a word after a slash wraps whole, like Word (#2963)
UAX #14 (LB13) forbids a break between a space and a slash, and the break
after a slash is dropped on purpose (Word keeps "and/or" whole). Together
"caption /word" had no break opportunity at all, so a line too short for
both filled letter by letter and split the word. Add the break before a
slash that follows whitespace and starts a word.
Co-Authored-By: Claude <noreply@anthropic.com>
* Layout: no break before a slash after a no-break space (#2963)
The break before a slash word took any whitespace, U+00A0, U+2007 and
U+202F included, so "Nr. /12" could wrap after the no-break space.
Only a breakable space counts now. The parity checklist lists the rule
on its own row as untested against Word.
Co-Authored-By: Claude <noreply@anthropic.com>
* Layout: test the slash word in a fixed-width table cell (#2963)
The report came from a table cell, where the cell's own width is the
line width.
Co-Authored-By: Claude <noreply@anthropic.com>
* Docs: gaps and typing parity for the slash-word break (#2963)
Doc wording taken from #2994 (maxm11), with the test names of this PR.
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude (ThinkSystem) <claude@thinksystem.local>
Co-authored-by: Claude <noreply@anthropic.com>
* #662: ribbon groups shrink to fit the window (compact, then one drop-down)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* #1285: collapsed ribbon groups stay open while used; Styles gallery trims before it folds
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* Ribbon collapse: accessible name for folded groups, Tables/Links icons (#662)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* Ribbon: Esc in a collapsed-group popup doesn't leave full screen; tab-strip test ignores same-named ribbon buttons (#1285)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* Ribbon tab-strip test: pick the tab, not a same-named folded group (#662)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* Ribbon: a folded group's open state is keyed by its place in the row, not just its title (#1285)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* rustfmt: collapsed_group signature (#1285)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* File (Backstage): an icon beside each side-menu item (#1714)
The side menu (Home, New, Open, Info, Save, Save As, Print, Export,
Close, Options) was text only. Each item now has an 18 pt icon in the
label colour, greyed out with it when no document is open. Existing
icons where they fit (house, new page, open folder, info, save, printer,
close), and three new ones drawn in code: Save As (the save disk with a
pencil), Export (a page with an arrow leaving it) and Options (a gear).
Original artwork, no asset files.
Test: every item names its own icon, and each one is a drawn icon, not
the letter-tile fallback an unknown name gets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: one Backstage row with both the Close (#1712) and side-menu icon (#1714) notes
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>
Went through the whole Italian catalog. Fixed the ones that were wrong (Mailings is Lettere in Word, Redo is Ripristina, cursor commands say riga) and made some terms consistent (input penna, Disponi testo, Ombreggiatura).
Also marked Italian as reviewed in the localization doc and added myself to people.toml.
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* #1348: WIP
* #1348: keep comment drafts per document, keep them on a refused edit, write them before save/close/new/open
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #1348: a refused comment draft can be dropped; fields read-only where comments can't change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #1348: ui-parity: one Task panes and Context menus row after the rebase
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Docs after rebasing on main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #1348: keep the window open while a web save is unconfirmed; split the roadmap row by operation
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* #1348: pending comment drafts count as unsaved changes for the browser; a save error isn't hidden by a draft refusal
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* #1348: an agent can't replace the document over a pending comment draft without force
Co-Authored-By: Claude Sonnet 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: Brandon Thomas <echelon@gmail.com>
* #778: .xls and legacy-encoding recipient lists; filter and sort recipients
- Recipient lists: legacy Excel 97-2003 .xls (BIFF8 reader on the cfb crate already in the
tree); Excel 5.0/95 and password-protected .xls refused with a clear message; a CSV named
.xls reads as text, an HTML one gets an error. .xls added to the picker filters (desktop,
web, built-in browser) and drop handling.
- Text lists (and plain-text import) detect legacy encodings when not UTF-8/UTF-16: GBK/GB18030,
Big5, Shift_JIS, EUC-KR, Windows code pages (encoding_rs + chardetng, MIT/Apache); an
`encoding` param overrides.
- mailings.filterRecipients / mailings.sortRecipients: field, comparison (equal, notEqual,
less, greater, lessOrEqual, greaterOrEqual, blank, notBlank, contains, notContains), value,
And/Or joins; sort keys. Preview, Finish & Merge and labels use only the matching records
in sort order. Edit Recipient List edits every record and keeps the filter.
- Recipient List dialog: Filter and Sort section and a merge-order column; catalog rows;
strings in every catalog; docs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* i18n: Hungarian and French strings for this change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Review fixes for #885: total order for recipient sort, Bulgarian strings
- compare_cells now ranks numbers (compared numerically) before text (compared
case-insensitively), so it is a total order; a column mixing 9, 10 and 1a
could make slice::sort_by panic. Regression test sorts mixed columns.
- Bulgarian catalog: the 24 Filter and Sort strings.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #1287: placeholder (work in progress)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #1287: keep the filter on a failed Edit Recipients; cap .xls/.xlsx cell text; dialog drops rules on unknown fields and caches the merge order
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #1287: rustfmt
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: Brandon Thomas <echelon@gmail.com>
* References: Word sources file import in Manage Sources (#2640)
Manage Sources gains Import… and references.sources an "import": path
parameter: it reads a b:Sources document (Word's own Sources.xml) into the
document's sources with the same reader as a document's own bibliography
part. A tag already here is left alone, an untagged entry is matched by
title and author or gets a tag like a new source, the whole import is one
undo step, and a file that isn't b:Sources is refused. Desktop only; the
web build hides the button.
The docx reader now shares the b:Sources parser (crates/docx/src/
bibliography.rs) with the import, with the same dedupe and 10,000-source
cap; the hostile-input cap test still passes.
Tests: docx unit tests (names, kinds, accessed/DOI fallbacks, repeated
tags, empty entries, wrong root), engine import test (add, undo, second
import, untagged matching, refused file), ui tests (the dialog button asks
for a "sources" file; finish_pick imports), wordcraft-cli end to end
(import, cite, bibliography, save, reopen; the package's customXml
carries the sources). The button's label is in every interface catalogue.
ROADMAP progress log and docs/roadmap.md, gaps.md, file-format-parity.md
and target-app-parity.md get their rows.
* References: review fixes for the sources import (#2640)
- read_sources validates the root namespace instead of the local name alone:
an un-namespaced or unrelated <Sources> is refused, and both bibliography
namespaces read — OOXML's and Word's own 2004/10 (the VBA Source.XML
format), the latter mapped onto the canonical b prefix with parse_ns.
Tests: the 2004/10 namespace is accepted; a no-namespace or unrelated
root is refused.
- The import loop builds the tag and (title, author-or-editor) sets once and
keeps a per-stem counter, with the stem rule shared with auto_tag
(auto_tag_base). Importing thousands of untagged sources no longer costs
O(n^3). Test: untagged sources sharing a stem get Riv21, Riv211, Src, and
a second import adds none.
- docs/target-app-parity.md and docs/file-format-parity.md no longer claim
bibliography sources aren't saved in DOCX: #169 and #532 are closed and
the round trip exists (#790).
* References: doc comments for the sources import helpers (#2640)
Hoist the untagged-source matching helper (by_author) to module level and
document sources, auto_tag_base and sources_ui, so the functions this PR
touches meet CodeRabbit's docstring-coverage pre-merge check.
* References: re-apply the sources import's progress notes (#2640)
The rebase onto current main took upstream's copies of ROADMAP.md,
docs/file-format-parity.md and docs/gaps.md, because the rows this PR
adds conflicted with upstream's own appends. Re-apply them on the current
text: the progress log and revision rows, the bibliography row's
source-format note, and #15's evidence, with each status line's change
note. The other two documents (docs/roadmap.md, docs/target-app-parity.md)
merged cleanly and keep their rows.
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* #2573: Picture Format › Size takes sizes in any unit, pixels too, and opens a Size dialog
The picture size options were too limited (#2573, and #1901's request to enter pixels without
deforming the picture): the ribbon's W/H fields were points only, rejected "300 px", resized on
every keystroke (one undo step per digit), and there was no way to scale from the original
size, lock or unlock the aspect ratio, or reset the size.
- Picture Format › Size: W/H show the interface unit (Options › Advanced) and take a size typed
in any unit, `px` included; it applies on Enter as one undo step, and the other side follows
so the picture keeps its proportions. A drag still applies live.
- The Size group's launcher (and `picture.size` run without a size) opens a Size dialog: height
and width, scale of the original size or of the size it opened with, Lock aspect ratio,
Relative to original picture size, the original size with its pixels, and Reset.
- `picture.size {"original": true, "scale"?}` sizes from the picture's original size (its pixels
at 96 ppi, read from the image adjustments started from, less what is cropped). A size past
4000 pt that keeps the proportions now shrinks as a whole instead of flattening.
- New strings translated in every interface catalog.
The crop tool already exists (Picture Format › Size › Crop) and is being extended in #2027 and
#2440; options cut off in a narrow window are what #708 and #1293 (ribbon groups that shrink to
fit) address.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZArmeAT48gF84aKj7Zx4C
* contributors: credit @matteo-andreuzza by their GitHub profile name
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZArmeAT48gF84aKj7Zx4C
* #2573: Size keeps the proportions at the 1–4000 pt limits and follows the selection
Review follow-ups (CodeRabbit on #2889):
- Size dialog Reset on a photo larger than 4000 pt (a 6000 px wide one is 4500 pt) set it to
the original size, which `picture.size` then clamped side by side: the picture was flattened.
Reset now shrinks both sides by one factor.
- Locked, a side typed past the limit clamped the other on its own (15×30 pt with width 4000
became 4000×4000). Both sides now scale by one factor.
- `fit_size` (engine) only shrank: a proportional size under 1 pt (scale 1% of 50×200 pt) became
1×2 pt. It now picks the factor nearest 1 that brings both sides within 1–4000 pt, falling
back to side-by-side clamping only for shapes too long and thin for any; the dialog uses it.
- Dialogs aren't modal: picking another picture while the Size dialog was open made OK size it
with the first one's numbers. The form now follows the selection (starts over on the new
object, closes when nothing is left to size).
- Doc comments on the Size form's methods.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZArmeAT48gF84aKj7Zx4C
* #2573: Size dialog reads the picture again after a crop, change or resize
Review follow-ups (CodeRabbit on #2889):
- The open Size form only compared the selected object's position. A crop from the ribbon,
Change Picture or a handle drag while the dialog is open left Reset and OK working from the
old crop and size. The form now remembers the picture, crop and size it was read from (bit for
bit, without comparing whole objects that may hold large embedded data) and reads them again
when any changes.
- An egui harness test drives the dialog end to end: launcher, a height typed in pixels, nothing
applied before OK, OK sizes in proportion as one undo step and closes the dialog.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZArmeAT48gF84aKj7Zx4C
* #2573: size fields never resize a picture just by showing it
Review follow-up (CodeRabbit on #2889): egui's DragValue clamps a value already outside its
range when it is drawn and reports that as a change. The Size fields act on changes, so:
- Picture Format's W/H resized a picture smaller than 1 pt (a 1×1 px spacer is 0.75 pt) or
larger than 4000 pt as soon as the tab was shown, an edit and an undo step nobody asked for.
The code before this PR had the same problem with its 4–2000 pt range.
- The Size dialog's scale fields silently changed a picture enlarged past 10000% (a small icon
made large), and its lengths a size outside 1–4000 pt, which OK then applied.
The range now bounds only what is typed or dragged (`clamp_existing_to_range(false)`). Both
regression tests fail without it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZArmeAT48gF84aKj7Zx4C
* #2573: Shape Format and Chart Design size fields leave existing sizes alone too
Review follow-up (CodeRabbit on #2889, outside the diff): the same egui clamp as in d56a105.
Shape Format's W/H (4–2000 pt) and Chart Design's (36–2000 pt) clamped a size outside their
range as soon as the tab was shown and resized the object unasked. The new Size dialog makes this
easier to reach, since it takes shapes up to 4000 pt, but a thin line under 4 pt was already cut.
Both now show such a size as it is and act only on a new value. Shape Format's range follows
`picture.size` (1–4000 pt), so dragging a 3000 pt shape no longer snaps it back to 2000.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZArmeAT48gF84aKj7Zx4C
* #2573: Esc cancels a size typed in Picture Format; a typed size applies when the field is left
Review follow-up (CodeRabbit on #2889, outside the diff) asked to apply typed sizes on Enter only.
That is not done: a field keeps what was typed when it loses focus, as text fields do, and
otherwise typing a height in the Size dialog and clicking OK would throw it away. A harness test
now pins that path with a real click (press, then release frames later).
Checking it turned up a real bug: Esc did not cancel in the ribbon's W/H fields. egui 0.36 keeps
a DragValue's typed text after Esc and applies it the next frame, when the field still counts as
having just lost focus but Esc is no longer pressed. The fields now remember when Esc ended the
typing and drop that late value. (In the dialog Esc cancels the whole dialog, so nothing applies
there either; both are tested.)
Docs and comments now say "applied once typed (Enter, Tab or a click elsewhere; Esc cancels)"
instead of "applied on Enter".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZArmeAT48gF84aKj7Zx4C
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* Proofing: say when a dictionary is installed but unreadable, with file and reason (#2830)
* proof test: use SHIFT_JIS as the unsupported encoding (ISO 8859-1 is decoded since #2904)
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* #2108: File › Print scales pages to another paper size
Scale to paper size on File › Print (Word: Pages per sheet › Scale to
paper size): No Scaling or any Layout › Size paper (Letter, Legal, A4, …).
Every page is scaled to the paper and centred, the paper turned to the
page's orientation, in the preview, the print job and Save these pages
as PDF. Native jobs also ask the spooler for that media. The document's
page size is unchanged. New `paper` param on ui.print/ui.printSubmit and
file.printPdf; unknown papers are errors.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* pdf: bookmark destinations from #2364 use the scaled Fit too
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* Keep the ODT paragraph 'Keep with next' option on import and export (#2813)
* file-format-parity: keep with next on the ODT row
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* #1230: Insert Caption on pictures and shapes; Page Setup header and footer options
- Right-clicking a picture, shape, text box or chart offers Insert Caption…, as in Word.
- references.caption with a picture or shape selected puts the caption next to the
paragraph holding it, in the same cell or text box (it used to go after the whole table).
- The Caption dialog proposes Figure for a picture selected in a table, not Table.
- Page Setup: Headers and footers check boxes (Different Odd & Even Pages, Different First
Page), applied on OK only if changed, in one undo step; a title page can go unnumbered.
- Tests: engine caption_for_an_object_in_a_cell_stays_in_the_cell; kittest
right_click_on_a_picture_offers_insert_caption and
page_setup_different_first_page_leaves_the_title_page_unnumbered.
- Docs: ui-parity, target-app-parity, ROADMAP progress log.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P8veLveuUsJJm6UEcQPEuW
* ui-parity: keep Insert Caption on the context-menu row
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
- Math straight in the body or a cell (m:oMathPara/m:oMath without w:p,
allowed by EG_BlockLevelElts) gets its own paragraph instead of vanishing.
- mc:AlternateContent Requires="m" picks the equation, not its fallback.
- Inside an equation, runs in w:hyperlink, w:fldSimple, w:dir, w:bdo and
mc:AlternateContent are kept (EG_PContentMath); depth stays bounded.
- w:sym, w:noBreakHyphen and Symbol-font text in math runs become Unicode.
- Layout: n-ary operators, delimiters, accents and group characters the math
font lacks use a fallback font instead of a missing-glyph box.
- Coverage test reads every ECMA-376 §22.1 element and checks no argument's
text is dropped; tests for body-level math, Requires="m", symbols, hostile
nesting and the font fallback. Parity docs and progress log updated.
Claude-Session: https://claude.ai/code/session_01P8veLveuUsJJm6UEcQPEuW
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* #2601: Drop Cap Options dialog
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* gaps: keep the Drop Cap Options note on the dialog-depth row
* i18n: translate the two Drop Cap disabled reasons in the audited catalogs
---------
Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* #2551: dragging the scrollbar names the page at the top of the window
While the canvas's vertical scrollbar is dragged, a tip beside the pointer
says which page is at the top of the window, in the status bar's words
("Page 7 of 10"), so a drag through a long document shows where it will land.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #2551: the scrollbar tip names the page whose visible band is at the top, also with Hide White Space
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>