* Fix#4750: walk note references and formatting runs together
* docs: keep the gaps.md note in the status line and revision table
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* #4696: built-in heading styles have their outline level without w:outlineLvl
Some producers write "heading 1"…"heading 9" in styles.xml without w:outlineLvl. Word
gives those built-in styles their outline level anyway (checked: Word for Windows reports
OutlineLevel 1 and 2, whatever the style id), so their headings show in the Navigation
pane. WordCraft read no level, and the Headings tab stayed empty.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #4696: review — w:customStyle="on" marks a custom style too
A custom style named "heading 4" with customStyle="on" (ST_OnOff) was taken for Word's
built-in heading and got an outline level.
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>
* #4548: comment ranges inside footnotes and endnotes are kept on read
read_opened read footnotes.xml and endnotes.xml before comments.xml, so
a comment range inside a note looked its id up in an empty comment map
and was dropped. Comments are now read first. read_comments uses nothing
the notes set up.
Regression test: tests/it/note_comments.rs (synthetic markup).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: file-format-parity row for comment ranges in notes (#4548)
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
The RTF reader only recognised \pngblip and \jpegblip, so a \pict
holding \wmetafile8 (how Word writes pasted and floating pictures) or
\emfblip was dropped and the document opened without its pictures.
Keep them as wmf/emf media when the bytes are a metafile (the extension
comes from the bytes; raster bytes go through the usual image path,
anything else is dropped), sized from \picwgoal/\pichgoal and the scale,
else from \picw/\pich (0.01 mm, or pixels under \wmetafile1; zero or
negative falls back to the default). The metafile renderer already
draws them and the DOCX writer saves them as .wmf/.emf.
RTF export dropped WMF/EMF pictures as well (it re-encoded every other
format through the raster decoder): it now writes \emfblip with the raw
bytes and \wmetafile8 without the placeable header, \picw/\pich in
0.01 mm.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* M1 #4658: bound Markdown reference-label work
* #4658: align Markdown progress status dates
* docs: keep ROADMAP's second status line as on main
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* Formats: preserve HTML input newlines (#4810)
* docs: fold the #4810 notes into the existing status lines
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
File › Options › Proofing › AutoCorrect Options did nothing on the Start
screen: tools.autocorrect wasn't in works_without_document, so the click
was dropped. Its options are user preferences (session.prefs), like the
other File › Options settings, so it now works without a document.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* Shading buttons show the last picked colour as their bar (#4412)
The paragraph and table Shading buttons always drew the icon's yellow bar,
whatever colour a click applied. They now draw the remembered colour as the
bar, as Font Color and Text Highlight Color do (#4087), on an icon without a
bar of its own.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* docs: ui-parity row for the Shading button colour (#4412)
---------
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* Options: a blank User Name stays blank after a restart (#4368)
* docs: ui-parity row for the blank User Name (#4368)
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* Layout parity: field results take \* DollarText, \* Hex and \* ArabicDash
docs/layout-parity.md gets a row for the three field switches that #4226
added, a revision entry and a new status-line clause. The row describes
main as it is after 8c035fbb, where \* ArabicDash formats any number
field and table formulas, not PAGE alone.
* Layout parity: dollar text keeps its digits only past 999,999.99
Cardinal and ordinal text keep their digits past 999,999. `\* DollarText` writes
results up to 999,999.99 (crates/layout/src/fields.rs dollar_text).
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* M14: validate window fallback geometry and avoid duplicate symbol names
Verified regression cases and full cargo xtask ci before publication.
* M14: document review helpers and regression contracts
Documentation-only follow-up; full cargo xtask ci passed.
---------
Co-authored-by: kalmarr <680152+kalmarr@users.noreply.github.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Ported onto current main (title_stem now lives in app/frame.rs; the window
title is built in windows.rs).
Co-authored-by: Lucenx9 <185146821+Lucenx9@users.noreply.github.com>
* i18n: Traditional Chinese interface draws hanzi with an installed TC font
The zh-hant interface shared the Simplified Chinese font order, so its first
CJK face was the embedded Noto Sans CJK SC and traditional characters were
drawn with mainland glyph shapes (說, 資, 這, 為, 戶).
On the desktop, a Traditional Chinese interface now puts an installed
Traditional Chinese font before every CJK face: PingFang TC on macOS,
Microsoft JhengHei on Windows, Noto Sans CJK TC on Linux. Noto Sans CJK SC
stays after it as the fallback. Without an installed TC font, and on wasm,
the order is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Credits: add TobyWu666 to contributors/people.toml
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* i18n: find Traditional Chinese fonts at the root of a font folder
Linux user font folders (~/.fonts, ~/.local/share/fonts) often hold font
files directly; the Traditional Chinese candidates only named files in
distribution subfolders, so those fonts were missed (CodeRabbit review).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* i18n: skip the Traditional Chinese font test without embedded catalogs
Since the catalogs come from craft-i18n (#4072), a build without
CRAFT_I18N_DIR is English only, so the test now skips like the other
catalog tests. Also rustfmt hant_font_chars.
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>
* #1103: ignore macOS launch arguments and name the real cause when a file won't open
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* #1103: filter launch args on macOS only; leave Backstage after a failed Finder open
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* #1103: leave Backstage after a failed drag-and-drop open
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* #1103: name the file when an open fails after the Save changes prompt
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* #1103: report failed opens from every deferred path in execute_user
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* #1103: keep the named failed-open message after a browser save
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* #1103: only opens held back by a prompt or save leave Backstage on failure
A direct open from Recent keeps File open and reports there (#2938).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* #1103: re-apply open-failure reporting on main's split ui-egui modules
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* Qualify i18n paths in report_open_failure after merging main
---------
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>
* Tables: share span minima by preferred widths (#1883)
* 1222: Match nested preferred span weights
* docs: word the #1883 layout-parity entries
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
The package is dual-scope, so the separate -windows-user MSI was the same package under a
second name. Build and policy-check the single plain-named MSI before signing, which is the
name every sibling app, the launcher and the shared windows-arm64 workflow use. Replace the
loop test with one that checks the MSI is policy-checked once, before it is signed.
dpkruse's Genuine Steps Certificate: a bulleted text paragraph closes a
two-column continuous section, then an empty bulleted one closes another.
Word draws no bullet for the empty one; it is now quiet (takes no room) and
draws no label, still counted. A stacked mark that doesn't fit keeps its
line for the caret but draws nothing below the margin (CodeRabbit).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A continuous section moves the column top down below the text above. at_top()
then held at every new section start, so a paragraph that did not fit was
placed anyway, as on an empty page. A run of one-line continuous sections ran
off the bottom of page 1 (100 of them reached 2,480 pt down a 792 pt page).
The overflow checks for paragraphs now use fresh(): at the top with nothing
above on this page. at_top() still drives the spacing rules, unchanged.
Empty paragraphs that close a continuous section right after another
section's mark took no room. Measured in Word on synthetic files ("Start", N
such marks, "End"): 10 put "End" about 9 cm down page 1; 50, 100 and 200 all
put it on the first line of page 2, the same with 24 pt marks or no paragraph
spacing. So each takes its line while it fits, then stays at the page's
bottom. A mark right after text stays quiet, as measured before.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CX1hMKX28764Lrx5moxs1o
- A package storing WORD/FONTTABLE.XML (part names are case-insensitive) loaded no
embedded fonts and a save dropped the table and every font: lookups used the exact
constant spelling. They now find the key case-insensitively.
- scrub_private re-pushed attribute values raw (quick-xml push_attribute does not
escape), so a value read from single quotes became malformed XML. The value is now
unescaped and escaped again.
- rel_targets matches _rels/ case-insensitively.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HUodYU9r4mPHed4pPsjHC2
* Task panes: a pane dropped over a docked pane's outer or inner third docks outside or inside it, and the order is kept (craft-libs#357)
* Pin craft-libs at b74f1b6 (pane order on an edge, craft-libs#357)
* Pin craft-libs at b926b5c (craft-libs main)
- docs/zotero.md and peer.rs module docs: a read error, or an open error other than NotFound,
refuses (sandboxes denying /proc/net/tcp: AppArmor, Snap, Flatpak, are refused).
- read_line_capped retries ErrorKind::Interrupted like std's read_line.
- New scan_tables (what owner_check calls) takes the table opener; the 70 MiB test drives it,
so reinstating take(64 MiB) there fails the test. Added tests for EINTR and a denied open.
- Row parsing uses split_whitespace().nth() instead of collecting a Vec.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>