Commit Graph
50 Commits
Author SHA1 Message Date
Tony Ganesh PrajapatiandTony bcfe9111ca #147: wire Picture Format UI for inserted pictures (#150)
* #147: wire Picture Format UI for inserted pictures

* #147: fix Picture Format state bugs from review (alt/crop buffers, undo coalescing, pending target, tab fallback)

* #147: review round 2 (cancel pending change on next action, alt media check, drag-only undo join)

---------

Co-authored-by: Tony <gittonyp@gmail.com>
2026-10-10 06:34:46 -04:00
MarekSpodBiedry 59d96995bd Find and Replace: Replace All now respects Track Changes (#88) (#92) 2026-10-10 06:34:40 -04:00
c0ccda288c Find/Replace skips text deleted under Track Changes (#89); a failed command keeps undo history (#153)
* Find/Replace: skip text deleted under Track Changes

With Track Changes on, Replace marks the match deleted and leaves it in
the paragraph text, then inserts the replacement in front of it. The
search helper matched the raw paragraph text, so the next step found that
same deleted "cat" right after the caret and replaced it again: four
Replaces on "one cat two cat" gave "one dogdogdogdog two cat" and
`remaining` never dropped.

`search` (used by Find, Find Next/Previous, Replace, its `remaining`
count and Replace All) now skips any match that overlaps a run marked
deleted, so deleted text is never found, as in Word. A match that would
run across deleted text is skipped too: that string is not in the
document as it now reads.

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

* Undo: a failed command keeps the redo stack and the oldest undo step

`run` checkpoints a mutating command before running it, and the
checkpoint clears the redo stack (and, once the history is at its limit,
drops the oldest step). When the command then failed, the error path put
back the document, selection and typing group and truncated the history,
but the cleared redo stack stayed cleared. Insert, Undo, then any
command that fails on its parameters (`text.insert {}`,
`para.align {value:"bogus"}`) made the undone work unrecoverable. At the
limit, truncating to the old length also kept the failed command's empty
step and lost the oldest real one.

The checkpoint now hands back what it removed, and the error path
restores both. join_next is deliberately left consumed: the drag that
set it re-arms it every frame, and restoring it would merge the next
unrelated command into the drag's undo step.

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

* Find/Replace: find live text next to a tracked deletion

The previous fix rejected any regex match that overlapped tracked-deleted
text, but `find_iter` had already consumed those positions, so a valid
match overlapping the rejected one was never tried. "aaa" with the first
"a" deleted reads "aa", yet Find "aa" found nothing (raw 0..2 was
rejected and the scan resumed at 2) and Replace All replaced nothing.
Searching the raw text also let deleted characters decide word
boundaries: deleting the space in "cat fish" still matched whole-word
"fish".

`search` now builds each paragraph as it reads, without deleted runs,
and searches each stretch of live text separately with
`regex_automata::Input::range`. A match stays within one stretch, as
before, and `\b`, `^` and `$` see the neighbouring live text, so a
deletion neither creates nor hides a word boundary. `regex::Regex` cannot
bound a search's end without slicing the haystack, which turns the slice
end into a word boundary; regex-automata is the engine `regex` already
uses (0.4.18, already in the lockfile), so no new code is built.

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

* Undo: a failed command restores history changed by nested commands

The previous fix had the checkpoint report what it evicted and put that
back on failure, but it only saw the outer command's own checkpoint.
Commands run nested commands, and a nested one that succeeds checkpoints
too. `file.inspect {"remove":["comments","revisions"]}` in a
comments-only document runs `review.deleteComment` (allowed) and then
`review.acceptAll` (refused). With 499 undo steps, the nested checkpoint
evicted the oldest step and the rollback, truncating to 499, kept the
outer command's empty step instead. At 500, only one of the two
evictions came back. Nested undo, redo and version restore change the
stacks in ways a length cannot describe either.

Undo steps are now `Arc<Undo>`, and `run` snapshots both stacks whole
before a mutating command and puts them back on failure, so the
history is exact whatever ran inside. The snapshot copies one pointer
per step, under 1,000 refcount bumps and an 8 KB allocation at
MAX_UNDO, beside the two document clones every mutating command
already makes. Undo and Redo are not mutating commands, so a top-level
Undo still moves its document out of the step without cloning it. Only
an undo nested inside a mutating command (a macro) clones, because the
snapshot still holds the step. This replaces the eviction-return
plumbing, so `checkpoint` is back to its original form.

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

* Tests: compare undo timelines without comment timestamps

failed_command_restores_history_changed_by_nested_commands builds the
same session twice and compares their documents. Comments are stamped
with the time to the second, so when the clock crossed a second between
the two builds the documents differed and the test failed (about 1 run
in 12). Clear the stamp in the compared copies; the test still checks
every other part of each document in the timeline.

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

* Undo: wrap the typing-parity undo step in Arc after merging main

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>
2026-10-10 06:34:35 -04:00
Brandon ThomasandClaude Opus 5.5 bbe89c2d86 i18n: pt-BR strings for the dark page option and the link scheme message
#128's coverage test requires every English string; #72 and #194 added three in the same batch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:17:59 -04:00
97aad95d4d Zoom the page with Ctrl+scroll and pinch (#139) (#179)
The canvas ignored egui's zoom delta, so Ctrl/Cmd+wheel and trackpad pinch
did nothing over the document. Apply it through view.zoom, starting from the
shown scale so fit modes (Page Width etc.) zoom from where they are.

Co-authored-by: Simon Geljic <simon.geljic2@det.nsw.edu.au>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:17:33 -04:00
loganjandClaude Sonnet 5.5 bd123c3808 Desktop: send the window title only when it changes (#117) (#180)
Every viewport command schedules a repaint, so sending the title at the
end of each frame kept the app redrawing at the monitor's refresh rate
while idle. Remember the last title sent and skip identical ones.

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-10 06:17:28 -04:00
Eduardo Soares ae79726ab6 i18n: add Brazilian Portuguese (pt-br) interface translation (#127) (#128)
771-entry pt-br.tsv catalog written clean-room from the English labels,
one LANGUAGES row, locale/persistence/coverage/font regression tests,
and README, ROADMAP, control-protocol and ATTRIBUTION updates.
2026-10-10 06:17:23 -04:00
3fcc1e2694 Lists: honour a list's own level definitions (w:lvlOverride/w:lvl) (#134)
A w:num can redefine any of its abstract list's levels with a whole
w:lvl inside w:lvlOverride. We kept only the start value from it and
numbered with the abstract list's levels, so documents that rely on it
showed the wrong labels: a construction specification (SpecLink) read
"A. PART 1 GENERAL" and "I. SECTION INCLUDES" where Word shows "PART 1
GENERAL" and "1.01 SECTION INCLUDES". Saving such a document also
dropped the definitions, so Word showed the wrong labels afterwards.

Num::level_overrides keeps them; Numbering::level and the list counters
prefer them over the abstract list's levels; the .docx reader reads them
with the abstract levels' parser and the writer writes them back (one
w:lvlOverride per level with its startOverride and/or lvl).

In docxide-pdf's Word reference corpus 6 of 382 documents carry such
definitions; the specification's SSIM goes 13% -> 41%, the others
restate their abstract lists and are unchanged.

Tests: counters use a list's own levels ("" and "%2.%3" in decimalZero
give "1.01", "1.02", "2.01") and fall back to the abstract list for the
rest; level overrides round-trip through .docx beside start overrides.

Co-authored-by: Oliver Zieschang <4963183+naxvog@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:17:17 -04:00
fbb688657d PDF: draw fonts krilla can't subset as outlines instead of failing (#132)
krilla subsets fonts only when the document is finished, so one font its
subsetter rejects ("failed to subset font: malformed font") failed the
whole PDF export. Two of the 365 documents in docxide-pdf's Word
reference corpus hit this on Linux: Caladea Italic and Bold Italic
(ttf-caladea, our metric-compatible stand-in for Cambria) and Noto Sans
New Tai Lue Bold.

When finishing fails on a font, the exporter finds the face krilla
names, logs a warning and writes the document again with that face's
glyphs drawn as filled outlines (FontDb::outline), including in the
watermark; every other font is still embedded as selectable text. At
most 32 faces fall back before the export gives up with the error.

kurbo moves from dev-dependencies to dependencies of wordcraft-pdf (it
was already in the workspace).

Test: a copy of the bundled Source Sans 3 with one glyph turned into a
truncated composite fails the old export exactly as the corpus documents
did; it now exports, with no text glyphs from that font and its glyphs
drawn as paths.

Co-authored-by: Oliver Zieschang <4963183+naxvog@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:17:11 -04:00
Dr. Gled GuriandClaude Opus 5.5 21415e7bde View › Switch Modes: dark page with inverted document colours (#194)
View › Switch Modes (and File › Options › Dark page) shows the page as dark
grey (80% black, #333333) with every document colour's lightness inverted
and its hue kept, so black text turns white and dark-blue headings light
blue. Pictures are untouched and the caret turns white. Screen only: saving,
printing and PDFs are unchanged. The setting is remembered between runs.

Refs #185.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:16:53 -04:00
AiBizzAppsandClaude Opus 5.5 5ee2bda8fc M6: TOC follow-ups from #52 review, and a whole TOC heading in LibreOffice (#74)
* M6: close the TOC field in its last entry, not in a text box inside it

`para_inner` took `toc_end_here` only after writing the paragraph's content,
so a nested story in the last TOC entry (a text box) reached `para_inner`
first, took the flag, and wrote the field's end inside `w:txbxContent`.
Take it before the content.

Review follow-up on #52.

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

* M6: Update Table reads a heading above the TOC at its own index

Pass 1 shifted every heading by `entries.len()` to account for the entries
now in the body, but entries go in below the TOC heading, so a heading above
it never moves. Its lookup landed on a TOC entry and took that page (a
Preface on page 1 above a TOC on page 2 showed 2). Shift only headings below
the TOC.

Review follow-up on #52.

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

* M6: start the TOC field in the first entry, as Word does

The writer opened the TOC field at the end of the "Contents" heading.
Word reads that fine, but LibreOffice splits the heading: "Content" as
body text, then "s" as the TOC title (on the next page when the TOC
follows a page break). Word itself writes the heading before the field
and begins the field in the first entry; written that way, LibreOffice
shows the heading whole.

Hold the heading's field back and write its begin/instruction/separate
at the start of the first entry, taken before the paragraph content so
a text box in the heading or an entry can't claim it (as with the end).

The reader moves a TOC field that starts a paragraph right after a TOC
Heading back to the end of the heading, so WordCraft's own files read
back as before and a TOC saved by Word now updates in WordCraft too
(before, Update Table left Word's first entry behind as a duplicate).

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:16:48 -04:00
AiBizzAppsandCodex 871f64e73e Import: HTML without </head> keeps its body; RTF pictures inside \shppict are kept (#154)
* HTML import: keep body text when </head> is omitted

Close an open head implicitly on body-content start tags, before skipped raw-text handling. Preserve head metadata and title capture while allowing body paragraphs and inline text to import.

Co-Authored-By: Codex <noreply@openai.com>

* RTF import: read pictures inside shppict wrappers

Recognize shppict as a transparent destination so nested pict groups are decoded instead of inheriting Skip. Continue skipping nonshppict legacy duplicates and pictures under other skipped destinations.

Co-Authored-By: Codex <noreply@openai.com>

---------

Co-authored-by: Codex <noreply@openai.com>
2026-10-10 06:16:42 -04:00
AiBizzAppsandClaude Opus 5.5 c2f21bf572 Tests: don't read the sample document aloud on every run (#75)
`hostile_params_never_panic` runs every command four times, Read Aloud
included, and on macOS that spawns `say` with the whole sample document:
four overlapping voices for minutes after `cargo test` returns. Skip it
with the other commands that reach outside the session; it ignores its
params, so junk payloads had nothing to exercise there.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:16:34 -04:00
780fd7a5af Control server closes on non-JSON input; hyperlinks follow only http/https/mailto (#34) (#72)
The control server answered a line that wasn't JSON with an error and kept
reading, so an HTTP request to the port (for example a web page's fetch to
127.0.0.1) could carry a command such as file.saveAs in its body. It now
replies once and closes the connection on the first bad line; HTTP request
lines never parse, so nothing after them runs.

Ctrl/Cmd+click on a hyperlink passed any URL to the system. It now follows
only http, https and mailto links, and shows a status message otherwise, so
a document can't launch file: paths or custom-scheme handlers.

Tests cover JSON requests, closing on bad JSON, an HTTP POST carrying a
command, and the link allow-list. The control protocol docs note the
closing behaviour.

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:16:28 -04:00
MarekSpodBiedry 6f282df367 HTML import: tables without borders stay borderless in .docx (#99) (#102) 2026-10-10 06:16:21 -04:00
MarekSpodBiedry f71fa219ca Page break (Ctrl+Enter) survives ODT/TXT/Markdown/HTML export and no longer glues words (#84) (#86) 2026-10-10 06:16:15 -04:00
MarekSpodBiedry 6b1f7a2741 DOCX: keep a line break written directly in a paragraph (#96) (#101) 2026-10-10 06:16:08 -04:00
MarekSpodBiedry 1633cbcfaa Desktop: keep the off-screen check until the monitor size is known (#23) (#76) 2026-10-10 06:01:48 -04:00
Brandon ThomasandClaude Opus 5.5 869ac16110 Typing parity with Word: lists, AutoFormat and AutoCorrect as you type (#204)
* Typing parity with Word: lists, AutoFormat and AutoCorrect as you type

Typed side by side with Word (same keystrokes, results read back) and matched it:

- Enter after a list no longer gets stuck: the paragraph that leaves a list goes back to
  Normal, and later Enters make blank paragraphs (the `num: 0` marker counted as a list item,
  so every Enter re-ran "leave the list" and did nothing; the list indent also stuck to every
  following paragraph).
- Enter on an empty nested item moves it up a level before leaving the list.
- Second Backspace at the start of an un-numbered list paragraph returns it to Normal
  instead of joining it to the paragraph above.
- "1. " always starts numbering at 1; "a. " and "I. " start lettered/roman lists; "- " makes
  a dash bullet.
- Undo right after an AutoFormat/AutoCorrect change undoes only that change.
- AutoCorrect: sentence capitals (with abbreviation/initial exceptions), runs on Enter too,
  "word -- word" en dash, "wait..." ellipsis, 1/2 1/4 3/4, ordinal superscripts, web
  addresses become links.
- Border lines: Enter after ---, ===, ***, ___, ~~~, ### draws a bottom border.
- Layout: no line break right after a slash ("and/or", URLs), as in Word.
- ui_shot: UI_SHOT_FULL=1 prints whole replies for scripted checks.

Regression tests in crates/engine/src/tests_typing.rs and the layout tests.

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

* Typing parity: record Word's observed typing rules, two more tests

docs/typing-parity.md lists what Word does for each key sequence (lists, Backspace, Tab,
AutoCorrect, AutoFormat, slash line breaks) with the test that pins it, the known gaps, and how
to compare without taking over the shared machine. CLAUDE.md/AGENTS.md point at it.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 04:52:10 -04:00
d7d9702bda Interface languages: follow the system, or pick one in Options (#8) (#12)
WordCraft's interface can now be shown in Simplified Chinese, Traditional
Chinese or Japanese as well as English. The new `language` setting is
`auto` by default: the UI follows the operating system's preferred
languages (Windows display language, macOS preferred languages,
LANG/LC_* on Unix, via sys-locale; WORDCRAFT_LANGUAGE overrides) when
there is a catalog for one of them, and English otherwise. File > Options
> Interface language picks one by hand, and the `ui.language` command does
the same for scripts and agents. The setting persists with the other UI
preferences.

The i18n module is PdfCraft's (catalog format, parser, locale matching),
trimmed to plain entries. English strings in the code are the keys; the
ribbon helpers (group, big, small, split, menu_button, menu items,
tooltips and ribbon locations), tabs, Backstage, Options, dialogs, panes,
the status bar, the context menu and command search translate at draw
time. Command ids, documents, the CLI, MCP and the control channel stay
English. Catalogs hold ~780 entries per language, written clean-room from
the English meaning.

Chinese interfaces put the craft-fonts Chinese face before the Japanese
one so a line never mixes glyph styles; fonts are reinstalled when the
language changes.

Fixes #8.


Claude-Session: https://claude.ai/code/session_019FczntrDNYd6DupyBdpbL5

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <shared2@storyteller.ai>
2026-10-09 09:22:42 -04:00
MarekSpodBiedryandBrandon Thomas 78369fd2e9 Desktop: remember the window size and position (#23) (#38)
Co-authored-by: Brandon Thomas <shared2@storyteller.ai>
2026-10-09 09:13:23 -04:00
d646d38921 M6: TOC page numbers, and save the TOC as a field Word can update (#52)
* M6: Update Table puts each heading on its real page

The second pass removed the entries and laid the document out again before
looking headings up at `path + entries.len()`, so every lookup landed past
its heading: later entries showed the next heading's page and the last fell
back to page 1. Lay out with the entries still in place, then replace them.

A heading typed after a manual page break also starts with the break, so its
page is now read after any leading breaks rather than before them.

The existing test only had a heading on page 1; the new one puts headings on
pages 2, 3 and 4 (before: 4, 1, 1).

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

* M6: save the table of contents as a TOC field Word can update

The writer saved the TOC heading's field empty (begin, instruction, separate
and end all at the end of "Contents"), with the entries as plain paragraphs
after it. Word showed them as ordinary text: no TOC frame, and no Update
Table or Update Field on the entries.

Write the field so its result spans the entries (closed at the end of the
last entry) and wrap heading and entries in the Table of Contents content
control (w:sdt with docPartGallery "Table of Contents", ECMA-376 17.5.2).

The reader already keeps a multi-paragraph field's start as an empty field
in its first paragraph and the rest as text, so WordCraft reads the TOC back
exactly as before; the new round-trip test checks both the file and that.

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 <shared2@storyteller.ai>
2026-10-09 09:02:22 -04:00
MarekSpodBiedryandBrandon Thomas 8588fb908a Options: remember the user name between runs (#32) (#35)
Co-authored-by: Brandon Thomas <shared2@storyteller.ai>
2026-10-09 09:02:16 -04:00
MarekSpodBiedry 0edb87e3da draw Symbol and Wingdings bullets as Unicode when the font is missing (#29) (#37) 2026-10-09 08:48:57 -04:00
AiBizzAppsandClaude Opus 5.5 5a94aa77d9 M6: footnotes no longer cite themselves in saved .docx files (#53)
references.footnote starts the note's text with a NoteRef to the note itself,
so the editor shows its number. The writer already puts the w:footnoteRef
mark at the start of every note, then also wrote that NoteRef as a
w:footnoteReference, so each note referenced itself. LibreOffice refuses to
open such a file ("source file could not be loaded").

Skip a note's reference to itself while writing that note; the mark stands
in for it. Notes read from Word files never contain one, so they are
unaffected.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:48:51 -04:00
MarekSpodBiedry 61e2152250 Ruler: dragging an indent marker is one undo step (#57) (#62) 2026-10-09 08:48:37 -04:00
MarekSpodBiedry eec54c635b Ctrl+-, Ctrl+= and Ctrl+0 no longer zoom the whole window (#14) (#36)
egui's built-in keyboard zoom fired on the same keys as Word's shortcuts (optional hyphen, subscript, space before), so Ctrl+- looked like zoom out while it also typed an optional hyphen over the selection. Turn it off once at startup; document zoom stays under View > Zoom and the status bar.
2026-10-09 08:48:30 -04:00
DWAA1660 7ab2bdb1f8 Issue #5: prevent font dropdown preview deadlock (#9) 2026-10-09 08:48:22 -04:00
daf9a99eb2 Layout: first-page header test no longer depends on installed fonts (#65)
tall_first_page_header_pushes_body_down compared page 1's first line with
the last paragraph on the last page. Where Aptos falls back to Liberation
Sans (Linux without Carlito), the last page is nearly full and that
paragraph sits below page 1's first line, so the test failed although
layout was correct. Compare with the first paragraph on page 2 instead,
which is what the test means: later pages don't reserve the tall
first-page header's space.

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:48:15 -04:00
810e176303 Apply heading/Title clears a paragraph's list numbering (#13)
apply_style's guard ended with `&& id == "Normal"`, making the
`id.starts_with("Heading") || id == "Title"` terms dead: only Normal
cleared a numbered paragraph's direct numbering, so applying Heading 1/2/3
or Title to a list item left the number behind — contradicting the
comment right above it. Drop the redundant term and cover it with a
regression test.

Also clears the clippy overly_complex_bool_expr error this expression
raised, which was failing `cargo xtask ci`.

Co-authored-by: justinjohn0306 <babyjjbabyjj549@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-09 08:48:07 -04:00
Brandon ThomasandClaude Opus 5.5 906d4faca3 About: contributor and model credits compiled in (grab bag + table, self-submitted names) (#6)
* About: contributors compiled in from contributors.json (grab bag + table, sortable, name toggle)

Adds About ▸ Contributors and About ▸ Models tabs per the craftrules standard
(standards/contributors.md): contributors/contributors.json is generated by
craftrules/scripts/contributors.py and baked into the binary by crates/ui-egui/build.rs as
static tables. Each contributor line: @username, opt-in display/real name, PRs, commits,
lines +/−/Δ, binary assets +/−, first/last commit. Sortable by every column; alphabetical
ignores case and the leading @. `ui.dialog` also accepts `contributors` / `models` to open
the About window on that tab.

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

* Contributors: self-submitted names in contributors/people.toml; AGENTS.md credit-yourself section

build.rs reads contributors/people.toml next to the generated contributors.json and shows a name only
for entries the generator verified as written by that person (craftrules standards/contributors.md).

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

* Contributors: regenerate (verified people.toml entries)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:17:02 -04:00
Sirsyorrz 05d0b41b7e truncate style gallery labels and keep hanging previews in view (#2) 2026-10-07 17:25:33 -04:00
Sirsyorrz a9ce05d2db fix first-page header layout and tiff header images (#1)
- body on a titlePg first page now starts below the first-page header
- decode tiff pictures
- fade images through an opacity layer; vello_cpu panics on image sampler alpha
2026-10-07 17:25:27 -04:00
Brandon ThomasandClaude Opus 5.5 56942da7a1 M14: clean wasm build warnings; macOS CLI zip without AppleDouble files
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 02:14:18 -04:00
Brandon ThomasandClaude Opus 5.5 6e9dc4bab4 M7/M14: comment balloons in the margin; ROADMAP alpha and parity estimates; README Review and Layout screenshots; cargo xtask alias
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:38:55 -04:00
Brandon ThomasandClaude Opus 5.5 f38710fcb6 Layout: automatic hyphenation (dictionary + patterns, 0.25" zone), soft hyphens show a hyphen at line end
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:27:02 -04:00
Brandon ThomasandClaude Opus 5.5 4c63bb0230 Layout: drop caps (dropped letter sized to N lines, text indented beside it)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:17:56 -04:00
Brandon ThomasandClaude Opus 5.5 e8c50e9dde Layout: table rows split across pages between lines (cantSplit honoured, header rows repeat)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:09:16 -04:00
Brandon ThomasandClaude Opus 5.5 6379a25ce6 Layout: text wrap around floating objects, text box contents, page borders (from page edge), column separators, vertical alignment, line numbers; cli run --page/--scale
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:04:48 -04:00
Brandon ThomasandClaude Opus 5.5 7b4a526fdf Release pipeline (macOS universal signed/notarized DMG, Windows x64/x86 MSI, Linux AppImage/deb/rpm/tar/Flatpak, FreeBSD, web zip) adapted from DesignCraft; Windows exe resources; version in --version/About; multithreaded page raster
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:50:50 -04:00
Brandon ThomasandClaude Opus 5.5 f3dbc31a57 README with screenshots, Crafting Apps table, community links; proofing ignores deletions/objects; comment shading; hhea line metrics; watermark tuning
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:18:42 -04:00
Brandon ThomasandClaude Opus 5.5 d95e09ba25 Clippy/fmt clean workspace, ROADMAP with honest parity estimate; xtask ci green
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:11:08 -04:00
Brandon ThomasandClaude Opus 5.5 72262a2ea9 M3/M6/M12: PDF export (krilla), TXT/MD/HTML/RTF/ODT import+export, citations & bibliography, index, table of figures, cross-references, tools (repeat, macros, AutoCorrect, compare, accessibility, inspector, protection, versions, Quick Parts)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:57:36 -04:00
Brandon ThomasandClaude Opus 5.5 c29182e8bc M1: DOCX read/write (OOXML) wired into open/save; floating objects; picture & shape tools; mail merge, envelopes, labels; contextual spacing; export without proofing marks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:46:40 -04:00
Brandon ThomasandClaude Opus 5.5 5a56dda633 M6.1: footnotes at page bottom, endnotes at document end, click-to-edit notes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:40:59 -04:00
Brandon ThomasandClaude Opus 5.5 d1a0ed39c0 M7.1: proofing — spelling with suggestions, grammar checks, squiggles, F7, right-click menu, thesaurus; web app; hyphenation dictionary
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:38:37 -04:00
Brandon ThomasandClaude Opus 5.5 435194f7c2 M0.9–M0.12: CLI, MCP server, xtask (layers/assets/parity/ci), icon placeholder, AGENTS/ATTRIBUTION/NOTICE, protocol docs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:21:35 -04:00
Brandon ThomasandClaude Opus 5.5 98bbfbed4e M0.8: Word-style egui UI — ribbon (all tabs), page canvas, rulers, panes, dialogs, Backstage, control channel; desktop app
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:16:02 -04:00
Brandon ThomasandClaude Opus 5.5 b8dd46ccb5 M0.7: engine — session, undo, 200+ commands, Word feature catalog, samples
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 22:47:26 -04:00
Brandon ThomasandClaude Opus 5.5 d1e80df4da M0.1–M0.6: workspace, geom, document model, fonts, layout, render
Clean-room foundations for WordCraft: Arc-shared document model with
paragraph/run editing, styles, lists, sections and tables; Word-style
font substitution; first-fit line breaking with tabs, lists, alignment,
pagination, tables, headers/footers and hit testing; vello_cpu page
rasteriser.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 22:30:16 -04:00