Files
wordcraft/README.md
T
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

419 lines
30 KiB
Markdown

<p align="center">
<a href="https://getartcraft.com/">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/brand/artcraft-logo-white.svg">
<img alt="ArtCraft" src="docs/brand/artcraft-logo.svg" width="200">
</picture>
</a>
</p>
<p align="center">
<img src="assets/app-icon/hicolor/256x256/apps/ai.storyteller.wordcraft.png" width="128" height="128" alt="WordCraft icon: a document page and pen on a blue tile">
</p>
<h1 align="center">WordCraft</h1>
<p align="center">
<b>Writing and document design; an open-source, modern word processor, built in pure Rust.</b>
</p>
<p align="center">
A fast, open-source word processor with a familiar workflow: the ribbon, styles,
tables, track changes, references and mail merge. It reads and writes .docx, runs natively on
macOS, Windows, Linux and BSD, and in the browser via WebAssembly.<br>
<i>By the ArtCraft team.</i>
</p>
<p align="center">
<img alt="Written in Rust" src="https://img.shields.io/badge/written%20in-Rust-2b47b5?style=flat-square&logo=rust&logoColor=white">
<img alt="Runs on macOS, Windows, Linux, BSD and the web" src="https://img.shields.io/badge/runs%20on-macOS%20%C2%B7%20Windows%20%C2%B7%20Linux%20%C2%B7%20BSD%20%C2%B7%20Web-3b5bdb?style=flat-square">
<img alt="License: MIT OR Apache-2.0" src="https://img.shields.io/badge/license-MIT%20%2F%20Apache--2.0-2b47b5?style=flat-square">
<img alt="Agent-drivable over MCP" src="https://img.shields.io/badge/agents-MCP%20%C2%B7%20CLI-3b5bdb?style=flat-square">
<br>
<a href="https://sonarcloud.io/project/overview?id=storytold_wordcraft"><img alt="Scanned by SonarCloud" src="https://img.shields.io/badge/Scanned_by-SonarCloud-4b9fd5?style=flat-square&logo=sonarqubecloud&logoColor=white"></a>
<a href="https://coderabbit.ai"><img alt="Reviewed by CodeRabbit" src="https://img.shields.io/coderabbit/prs/github/storytold/wordcraft?style=flat-square&label=Reviewed%20by%20CodeRabbit&logo=coderabbit"></a>
</p>
<p align="center">
<a href="https://discord.gg/artcraft"><img alt="Join the ArtCraft community on Discord" src="https://img.shields.io/badge/Join%20us%20on%20Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white" height="40"></a>
</p>
<p align="center">
<a href="https://getartcraft.com/apps/wordcraft"><b>WordCraft on getartcraft.com</b></a> ·
<a href="https://getartcraft.com/">ArtCraft</a> ·
<a href="https://getartcraft.com/apps">All Crafting Apps</a>
</p>
<br>
<p align="center">
<img src="docs/images/hero.png" alt="WordCraft with the Home tab of the ribbon open over a two-page document titled The Open Studio Handbook. The Navigation pane on the left lists the document's headings, the Styles gallery shows live previews of Normal, Heading 1, Title and Subtitle, and a word in the first paragraph is selected." width="100%">
<br><sub><b>The Open Studio Handbook</b>, WordCraft's built-in sample: the ribbon, live Styles gallery, rulers and the Navigation pane.</sub>
</p>
> [!NOTE]
> **ArtCraft is a community of artists from all walks of life.** Painters, photographers,
> filmmakers, illustrators, designers, animators, hobbyists, and people who picked up a pencil
> last week. If you make things, you're one of us. **[Come say hi on Discord](https://discord.gg/artcraft).**
<p align="center">
<a href="#a-tour">A tour</a> ·
<a href="#why-wordcraft">Why WordCraft</a> ·
<a href="#what-works-today">What works today</a> ·
<a href="#quick-start">Quick start</a> ·
<a href="#for-agents-cli-and-mcp">For agents</a> ·
<a href="#architecture">Architecture</a> ·
<a href="#roadmap">Roadmap</a> ·
<a href="#downloads">Downloads</a> ·
<a href="#the-crafting-apps">The Crafting Apps</a> ·
<a href="#license-and-credits">License and credits</a>
</p>
## A tour
Every screenshot below is WordCraft itself, rendered offscreen by its own UI test harness
(`cargo run -p wordcraft-ui-egui --example ui_shot`).
<table>
<tr>
<td width="50%" valign="top"><img src="docs/images/review.png" alt="The Review tab with Track Changes on: the word forty is inserted in magenta and thirty struck through; three commented phrases are shaded and joined by dashed leader lines to comment balloons in a grey markup area to the right of the page" width="100%"><p align="center"><sub><b>Review.</b> Track changes, comment balloons in the margin, accept and reject, spelling and grammar as you type.</sub></p></td>
<td width="50%" valign="top"><img src="docs/images/references.png" alt="The References tab with two pages side by side: a table of contents with dotted leaders and page numbers on page one, and a styled table, numbered list and hyperlink on page two" width="100%"><p align="center"><sub><b>References.</b> Tables of contents, footnotes, citations in APA, MLA, Chicago or IEEE, index and captions.</sub></p></td>
</tr>
<tr>
<td width="50%" valign="top"><img src="docs/images/design.png" alt="The Design tab showing style-set previews; the document is set in a serif theme with plum headings underlined by thin rules and a pale diagonal DRAFT watermark behind the text" width="100%"><p align="center"><sub><b>Design.</b> Themes, style sets, paragraph spacing, watermarks, page colour and borders.</sub></p></td>
<td width="50%" valign="top"><img src="docs/images/dark.png" alt="WordCraft in dark mode with the Insert tab open and formatting marks shown: pilcrows at paragraph ends and dots for spaces" width="100%"><p align="center"><sub><b>Dark mode</b> with formatting marks, and the Insert tab: tables, pictures, shapes, links, headers, footers, fields and symbols.</sub></p></td>
</tr>
<tr>
<td colspan="2"><img src="docs/images/layout.png" alt="The Layout tab at 80% zoom: the first paragraph opens with a three-line drop cap E, a dark blue circle sits beside the second section with its paragraph wrapping around it and hyphenating art-ist at the line end, every line is numbered in the left margin and a thin blue border surrounds the page" width="100%"><p align="center"><sub><b>Layout.</b> Drop caps, text wrapping around pictures and shapes, automatic hyphenation, line numbers and page borders.</sub></p></td>
</tr>
<tr>
<td colspan="2"><img src="docs/images/backstage.png" alt="The File tab start page with a Good morning greeting, thumbnails of the Blank document, Studio handbook, Letter, Résumé and Report templates, and a list of recent documents" width="100%"><p align="center"><sub><b>File.</b> Start from a template, open recent documents, edit properties, export to PDF and other formats.</sub></p></td>
</tr>
</table>
## Why WordCraft
- **Familiar.** Ribbon tabs, groups, shortcuts and behaviour: Enter continues a list,
Tab demotes it, Ctrl/⌘+B bolds the word under the caret, the Styles gallery previews styles live,
F4 repeats, F7 checks spelling, F8 extends the selection.
- **Your files.** Opens and saves .docx (OOXML), and also .odt, .rtf, .html, .md, .tex (LaTeX), .txt; opens legacy 97-2003 .doc; exports PDF
with real, selectable text, links and bookmarks.
- **Fast.** Paragraph layout is cached, so typing in a 188-page document re-lays it out in about
1.4 ms; pages render on demand.
- **Everywhere.** One Rust codebase for macOS, Windows, Linux, BSD and the web. No Electron, no
Tauri: native [egui](https://github.com/emilk/egui) on the GPU.
- **Built for agents.** Every action is a command with an id. The same 422 commands drive the
ribbon, keyboard shortcuts, the command search, a command-line tool, a JSON control channel and
an MCP server.
- **Private.** Spelling, grammar and everything else work offline.
- **Open.** MIT OR Apache-2.0. Clean-room: built from public specifications and observation, with
every asset original or openly licensed.
## What works today
| Area | Highlights |
|---|---|
| **Writing** | Fast typing with IME, smart quotes, AutoCorrect, list autoformat (`* `, `1. `), dashes; word, sentence, paragraph selection; drag-select; clipboard with formatting; undo/redo; find and replace with regex |
| **Formatting** | Fonts, sizes, bold/italic/underline styles, strike, sub/superscript, caps, highlight, colours, character spacing, Format Painter, Change Case, Clear Formatting |
| **Paragraphs** | Alignment, indents (draggable on the ruler), spacing, line spacing, tabs with leaders, borders, shading, keep with next, widow/orphan control |
| **Styles** | Built-in style set, live gallery, Styles pane, create/modify/update styles, style sets, themes |
| **Lists** | Bullets, numbering, multilevel, restart, set value, custom formats |
| **Tables** | Insert by grid, merge/split, styles with banded rows, borders, shading, header rows repeated across pages, rows that split across pages, sort, formulas, text ↔ table |
| **Pages** | Margins, orientation, size, columns, page/column/section breaks, headers and footers (first page, odd/even), page numbers, watermark, page borders, line numbers, vertical alignment, drop caps, automatic hyphenation |
| **Objects** | Pictures (resize, crop, recolour, brightness/contrast, transparency, background removal, picture styles, rotate), shapes, text boxes, floating position with text wrapping (square, top and bottom, behind or in front of text) |
| **References** | Table of contents, footnotes and endnotes, citations and bibliography (APA, MLA, Chicago, IEEE), captions, table of figures, cross-references, index, table of authorities |
| **Review** | Spelling and grammar with suggestions (English and Polish, by each run's language), thesaurus, word count, comments in margin balloons or a pane, track changes, accept/reject, compare documents, restrict editing, accessibility checker, document inspector |
| **Mailings** | Mail merge from CSV, merge fields, address block, greeting line, rules, preview, finish to a document; envelopes and labels |
| **View** | Print layout, web layout, draft, read mode, focus, zoom, one/multiple pages, page width, Navigation pane, rulers, gridlines, dark mode; interface in English, 简体中文, 繁體中文, 日本語, Português (Brasil), Español, Українська, Српски / Srpski, Eesti, Türkçe, Русский, Italiano, Deutsch, Polski, Čeština, Magyar, Français, Български, Tiếng Việt, 한국어, Svenska, Hrvatski, Nederlands, Dansk, Română, العربية (mirrored) or Slovenščina (follows the system language by default) |
| **Files** | .docx read/write, legacy 97-2003 .doc import, PDF export, .odt, .rtf, .html, .md, .tex, .txt import/export, page images |
The honest picture, area by area, is in [ROADMAP.md](ROADMAP.md), the
[parity assessment](docs/target-app-parity.md) and the generated
[feature checklist](docs/parity-checklist.md).
## Quick start
```sh
git clone https://github.com/storytold/wordcraft
cd wordcraft
cargo run --release -p wordcraft -- --sample # the desktop app with the sample document
cargo run --release -p wordcraft -- report.docx # open a document
```
The interface translations and the spelling and hyphenation data come from
[craft-i18n](https://github.com/storytold/craft-i18n), an optional build input. To build with them,
check it out at the commit in `craft-i18n.rev` and point `CRAFT_I18N_DIR` at it (an absolute
path); without it WordCraft builds with an English interface, English spelling falls back to an
installed Hunspell English or craft-proof's built-in word list, and only Bulgarian, Turkish and
Russian hyphenate (by rule):
```sh
git clone https://github.com/storytold/craft-i18n ../craft-i18n
git -C ../craft-i18n checkout "$(cat craft-i18n.rev)"
CRAFT_I18N_DIR="$PWD/../craft-i18n" cargo run --release -p wordcraft -- --sample
```
Command line:
```sh
wordcraft-cli convert report.docx report.pdf # docx, pdf, odt, rtf, html, md, tex, txt, png
wordcraft-cli text report.docx # plain text
wordcraft-cli inspect report.docx # structure as JSON
wordcraft-cli run --template sample \
--cmd 'select.text={"text":"Membership"}' --cmd format.bold --save out.docx
wordcraft-cli run --script job.json # the same from a file: commands, then save to docx and pdf
```
Web: `cd apps/wordcraft-web && trunk serve`, then open <http://127.0.0.1:8771/?sample>.
## For agents: CLI and MCP
WordCraft was designed to be driven by people *and* by AI agents.
```sh
claude mcp add wordcraft -- wordcraft-cli mcp # headless documents
# confine the agent to folders: wordcraft-cli mcp --automation-read-root DIR --automation-write-root DIR
wordcraft --control 7981 & # or drive the running app…
claude mcp add wordcraft-app -- wordcraft-cli mcp --connect 127.0.0.1:7981
```
Tools include `list_commands`, `execute`, `batch`, `type_text`, `select_text`, `inspect_document`,
`render_page`, `save_document`, and, with a running app, `screenshot`, `click` and `key`. Agents
can check their work through `inspect_document` without screenshots. See [docs/mcp.md](docs/mcp.md)
and the [control protocol](docs/control-protocol.md). Macros record any sequence of commands and
play it back (`tools.recordMacro`, `tools.macros`).
## Logs
The desktop app writes its log records to standard error and to `logs/wordcraft.log` next to its
preferences: on Linux `$XDG_CONFIG_HOME/wordcraft/logs/` (by default `~/.config/wordcraft/logs/`),
on macOS `~/Library/Application Support/WordCraft/logs/`, on Windows `%APPDATA%\WordCraft\logs\`.
A start from a desktop menu or the Dock has no terminal, so this file is what to attach to a bug
report: unreadable parts of a .docx, pictures or fonts a PDF export had to leave out and panics the
command guard recovered from land there. Each launch moves the previous log to `wordcraft.1.log`
(and that one to `wordcraft.2.log`), so the log of a run that crashed survives the next start; a
log stops growing at 16 MiB. `--version` writes no file, and runs with `WORDCRAFT_NO_PREFS` (agents'
test runs) log to standard error only. Document text is never logged; a panic message leaves out
the text it quotes.
By default WordCraft's own crates log at `info` and everything else at `warn`. `RUST_LOG` replaces
that with env_logger-style directives, for example `RUST_LOG=debug`,
`RUST_LOG=warn,wordcraft_docx=trace` or `RUST_LOG=info,wgpu_core=warn`; a directive ending in `*`
covers every target starting with it (`wordcraft*=debug`). The logger is
`apps/wordcraft/src/logging.rs`.
## Architecture
| Layer | Crate | Job |
|---|---|---|
| L0 | `wordcraft-geom` | units and measurements |
| L1 | `wordcraft-doc`, `wordcraft-fonts`, `wordcraft-proof` ([`craft-proof`](https://github.com/storytold/craft-libs/tree/main/crates/proof) from craft-libs) | document model and editing; fonts and shaping; spelling, grammar, hyphenation (data: craft-i18n `language-data/`, `CRAFT_I18N_DIR`) |
| L2 | `wordcraft-layout`, `wordcraft-docx`, `wordcraft-formats` | line breaking, pagination, tables, notes, hit testing; OOXML; ODT/RTF/HTML/Markdown/TXT |
| L3 | `wordcraft-render`, `wordcraft-pdf` | rasteriser (vello_cpu); PDF ([craft-pdf](docs/shared-pdf.md), Krilla) |
| L4 | `wordcraft-engine` | session, undo, 422 commands, document feature catalog |
| L5 | `wordcraft-mcp` | MCP server |
| L6 | `wordcraft-ui-egui` | the word processor front end (swappable) |
| apps | `wordcraft`, `wordcraft-cli`, `wordcraft-web` | desktop, command line, browser |
`cargo xtask ci` runs formatting, clippy, ~800 tests, the asset-attribution check, the layering
check and the wasm build. Contributor and agent instructions: [AGENTS.md](AGENTS.md).
## Roadmap
WordCraft is in **alpha**. It has commands for 97% of the ribbon and menu features in its feature catalog
([`docs/parity-checklist.md`](docs/parity-checklist.md)) today; counting
depth, file fidelity, stability and the rest, we estimate it is about 60% ready for real work,
about 55% for a typical professional's weekly work and about 63% for everyday essentials. Beta
needs testing against real-world .docx files, keeping charts and SmartArt through a round trip,
closer pagination fidelity, a stability sweep and native printing. Details and estimates:
[ROADMAP.md](ROADMAP.md) and [where we fall short](docs/gaps.md).
## Downloads
**Download WordCraft** from GitHub: the [latest release](https://github.com/storytold/wordcraft/releases/latest) has every build listed below, and [all releases](https://github.com/storytold/wordcraft/releases) has earlier versions and their notes. `<ver>` in the file names is the version number, and `SHA256SUMS.txt` lists a checksum for every file.
### Windows
| Build | Installer | Portable |
|---|---|---|
| x64 (64-bit Intel/AMD) | `wordcraft-<ver>-windows-x64.msi` | `wordcraft-<ver>-windows-x64-portable.zip` |
| arm64 (Snapdragon and other ARM PCs) | `wordcraft-<ver>-windows-arm64.msi` | `wordcraft-<ver>-windows-arm64-portable.zip` |
| x86 (32-bit) | `wordcraft-<ver>-windows-x86.msi` | `wordcraft-<ver>-windows-x86-portable.zip` |
The installer is one dual-scope package. By default it installs for your account only,
into `%LOCALAPPDATA%\Programs\ArtCraft\WordCraft`, and needs no administrator rights; choosing
"Everyone on this computer" on the first page installs into `C:\Program Files\ArtCraft\WordCraft` (`Program Files (x86)` for the 32-bit build)
and asks for an administrator. Install only one copy: a copy for another scope is refused, so
uninstall first to change who WordCraft is installed for. Installers and executables are code-signed.
**If the app doesn't open on Windows:** the desktop app initializes only DirectX 12 by default.
Letting wgpu also create an OpenGL instance can crash some graphics drivers (AMD's
`atio6axx.dll`) before the window appears, so the app would flash in Task Manager and quit.
`WGPU_BACKEND` overrides the default for troubleshooting (for example `dx12` or `vulkan`). In
PowerShell, from the folder containing the executable:
```powershell
$env:WGPU_BACKEND = "vulkan"
& .\wordcraft.exe
Remove-Item Env:WGPU_BACKEND # restore the default for later launches
```
An explicit `gl` override can bring the driver crash back on affected systems. The macOS, Linux
and web backend defaults are unchanged.
The **32-bit** build uses OpenGL even when a DirectX 12 graphics card is present. On 32-bit
Windows, creating a DirectX 12 graphics pipeline fails immediately and the app exits before the
window appears. `WGPU_BACKEND=vulkan` (or `dx12`) still overrides that.
**If the app quits right after its window appears with "Parent device is lost" in the log:**
WordCraft compiles DirectX 12 shaders with FXC, the compiler built into Windows, so it needs no
`dxcompiler.dll`/`dxil.dll` and ignores any copy another program put on `PATH` (#603).
`WGPU_DX12_COMPILER` (`fxc`, `dxc`, `auto`) overrides this; with `dxc`, a matching
`dxcompiler.dll` *and* `dxil.dll` must sit next to `wordcraft.exe`. `WGPU_BACKEND = "vulkan"`
also avoids DirectX 12 altogether.
**If the app is slow on an older Windows PC:** when DirectX 12 finds no graphics card with a
driver for it (for example Intel 4th-generation graphics on Windows 11), it only offers the built-in
software renderer, which draws every frame on the processor. WordCraft normally uses OpenGL instead,
without setting anything. If OpenGL has no usable adapter, it can use DirectX 12's WARP software
adapter. The log file records the choice (lines starting with
`graphics:`). `WGPU_BACKEND` still overrides it, e.g. `$env:WGPU_BACKEND = "gl"` or `"dx12"`.
### macOS
| Build | File | Notes |
|---|---|---|
| App, universal (Apple silicon + Intel) | `wordcraft-<ver>-macos-universal.dmg` | Signed and notarized |
| Command-line tool, universal | `wordcraft-cli-<ver>-macos-universal.zip` | Signed and notarized |
### Linux
| Format | x86_64 | aarch64 (ARM64) | Notes |
|---|---|---|---|
| AppImage | `wordcraft-<ver>-linux-x86_64.AppImage` | `wordcraft-<ver>-linux-aarch64.AppImage` | Runs anywhere; updates itself with [AppImageUpdate](https://github.com/AppImageCommunity/AppImageUpdate) (`.zsync` files) |
| Flatpak | `wordcraft-<ver>-linux-x86_64.flatpak` | `wordcraft-<ver>-linux-aarch64.flatpak` | Sandboxed; `flatpak install --user <file>` |
| Debian/Ubuntu | `wordcraft-<ver>-linux-x86_64.deb` | `wordcraft-<ver>-linux-aarch64.deb` | |
| Fedora/RHEL/openSUSE | `wordcraft-<ver>-linux-x86_64.rpm` | `wordcraft-<ver>-linux-aarch64.rpm` | |
| Tarball | `wordcraft-<ver>-linux-x86_64.tar.gz` | `wordcraft-<ver>-linux-aarch64.tar.gz` | Unpack anywhere |
RISC-V (riscv64): `wordcraft-<ver>-linux-riscv64.tar.gz`, a tarball cross-compiled for glibc 2.39+
(Ubuntu 24.04, Debian 13 and newer).
**Wayland:** on a Wayland desktop the app runs through XWayland when it is available, because
winit (the windowing library) supports dragging files into the window only on X11. To use the
native Wayland backend instead (for example for sharper text with fractional scaling, at the cost
of file drag-and-drop), start it with `WORDCRAFT_WAYLAND=1`:
```sh
WORDCRAFT_WAYLAND=1 wordcraft
```
**Arch Linux (AUR).** Community members maintain three AUR packages; the project doesn't publish
to the AUR itself. Install one of them:
| Package | What it installs | Choose it when |
|---|---|---|
| [`wordcraft-bin`](https://aur.archlinux.org/packages/wordcraft-bin) | The release tarball above, prebuilt (x86_64, aarch64) | You want the latest release without compiling (quickest) |
| [`wordcraft`](https://aur.archlinux.org/packages/wordcraft) | The latest release, built from source with `cargo` | You prefer to build releases yourself |
| [`wordcraft-git`](https://aur.archlinux.org/packages/wordcraft-git) | The current `main` branch, built from source | You want unreleased changes and accept an occasional broken build |
For example `yay -S wordcraft-bin` or `paru -S wordcraft-bin`.
#### Community packages
These packages are maintained by community members, not by the WordCraft team.
On Gentoo, the [::snakebyte overlay](https://github.com/switch87/snakebyte-overlay) packages the
Linux release as `app-office/wordcraft-bin` (prebuilt) and `app-office/wordcraft` (built from source):
```sh
eselect repository add snakebyte git https://github.com/switch87/snakebyte-overlay.git
emaint sync -r snakebyte
echo 'app-office/wordcraft-bin ~amd64' >> /etc/portage/package.accept_keywords/wordcraft
emerge --ask app-office/wordcraft-bin
```
### FreeBSD
| Build | File |
|---|---|
| x86_64 | `wordcraft-<ver>-freebsd-x86_64.tar.gz` |
### Web (WebAssembly)
| Build | File | Notes |
|---|---|---|
| Static site | `wordcraft-web-<ver>.zip` | Runs in a modern browser; host it on any static server |
## The Crafting Apps
WordCraft is one of the **Crafting Apps**: free, open-source creative tools from the
[ArtCraft](https://getartcraft.com/) team, each written from scratch in Rust and each able to
stand on its own.
| | App | What it's for | Code | Learn more |
|:-:|---|---|---|---|
| <img src="https://raw.githubusercontent.com/storytold/photocraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.photocraft.png" alt="" width="32" height="32"> | **PhotoCraft** | Image editing: layers, masks, type and real PSD files | [GitHub](https://github.com/storytold/photocraft) | [Website](https://getartcraft.com/apps/photocraft) |
| <img src="https://raw.githubusercontent.com/storytold/vectorcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.vectorcraft.png" alt="" width="32" height="32"> | **VectorCraft** | Vector illustration | [GitHub](https://github.com/storytold/vectorcraft) | [Website](https://getartcraft.com/apps/vectorcraft) |
| <img src="https://raw.githubusercontent.com/storytold/filmcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.filmcraft.png" alt="" width="32" height="32"> | **FilmCraft** | Video editing, color and sound | [GitHub](https://github.com/storytold/filmcraft) | [Website](https://getartcraft.com/apps/filmcraft) |
| <img src="https://raw.githubusercontent.com/storytold/lightcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.lightcraft.png" alt="" width="32" height="32"> | **LightCraft** | Photo library and raw development | [GitHub](https://github.com/storytold/lightcraft) | [Website](https://getartcraft.com/apps/lightcraft) |
| <img src="https://raw.githubusercontent.com/storytold/pdfcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.pdfcraft.png" alt="" width="32" height="32"> | **PdfCraft** | Reading, organizing and protecting PDFs | [GitHub](https://github.com/storytold/pdfcraft) | [Website](https://getartcraft.com/apps/pdfcraft) |
| <img src="https://raw.githubusercontent.com/storytold/effectcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.effectcraft.png" alt="" width="32" height="32"> | **EffectCraft** | Motion graphics and visual effects | [GitHub](https://github.com/storytold/effectcraft) | [Website](https://getartcraft.com/apps/effectcraft) |
| <img src="https://raw.githubusercontent.com/storytold/designcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.designcraft.png" alt="" width="32" height="32"> | **DesignCraft** | Page layout and publishing | [GitHub](https://github.com/storytold/designcraft) | [Website](https://getartcraft.com/apps/designcraft) |
| <img src="https://raw.githubusercontent.com/storytold/figcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.figcraft.png" alt="" width="32" height="32"> | **FigCraft** | Interface design and prototyping | [GitHub](https://github.com/storytold/figcraft) | [Website](https://getartcraft.com/apps/figcraft) |
| <img src="https://raw.githubusercontent.com/storytold/wordcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.wordcraft.png" alt="" width="32" height="32"> | **WordCraft** | Word processing and documents | [GitHub](https://github.com/storytold/wordcraft) | [Website](https://getartcraft.com/apps/wordcraft) |
| <img src="https://raw.githubusercontent.com/storytold/soundcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.soundcraft.png" alt="" width="32" height="32"> | **SoundCraft** | Audio recording and editing | [GitHub](https://github.com/storytold/soundcraft) | [Website](https://getartcraft.com/apps/soundcraft) |
| <img src="https://raw.githubusercontent.com/storytold/deckcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.deckcraft.png" alt="" width="32" height="32"> | **DeckCraft** | Presentations and slide decks | [GitHub](https://github.com/storytold/deckcraft) | [Website](https://getartcraft.com/apps/deckcraft) |
| <img src="https://raw.githubusercontent.com/storytold/cadcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.cadcraft.png" alt="" width="32" height="32"> | **CADCraft** | Computer-aided design | [GitHub](https://github.com/storytold/cadcraft) | [Website](https://getartcraft.com/apps/cadcraft) |
| <img src="https://raw.githubusercontent.com/storytold/gridcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.gridcraft.png" alt="" width="32" height="32"> | **GridCraft** | Spreadsheets and data | [GitHub](https://github.com/storytold/gridcraft) | [Website](https://getartcraft.com/apps/gridcraft) |
| <img src="https://raw.githubusercontent.com/storytold/texturecraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.texturecraft.png" alt="" width="32" height="32"> | **TextureCraft** | 3D texture painting | [GitHub](https://github.com/storytold/texturecraft) | [Website](https://getartcraft.com/apps/texturecraft) |
| <img src="https://raw.githubusercontent.com/storytold/craft-anything/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.craft-anything.png" alt="" width="32" height="32"> | **Craft Anything** | See how any software works, then build your own | [GitHub](https://github.com/storytold/craft-anything) | [Website](https://getartcraft.com/apps/craft-anything) |
| <img src="https://raw.githubusercontent.com/tangency-labs/solidcraft/main/assets/icons/app/linux/exports/hicolor/64x64/apps/io.tangencylabs.solidcraft.png" alt="" width="32" height="32"> | **SolidCraft** | Parametric 3D CAD by Tangency Labs (community app) | [GitHub](https://github.com/tangency-labs/solidcraft) | |
And [**ArtCraft**](https://getartcraft.com/) itself, our AI image and video studio for artists who want real control.
<br>
<p align="center">
<a href="https://discord.gg/artcraft"><img alt="Join the ArtCraft community on Discord" src="https://img.shields.io/badge/Join%20us%20on%20Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white" height="40"></a>
</p>
<h3 align="center">Come make things with us</h3>
<p align="center">
Our Discord is where artists of every kind hang out: people who paint, shoot, draw, cut film,
set type, and people still figuring out what they like to make. Share what you're working on,
ask for help, tell us what's broken, or tell us what you wish these tools could do.
Whatever your medium and however long you've been at it, you're welcome here.
</p>
<p align="center">
<a href="https://discord.gg/artcraft"><b>discord.gg/artcraft</b></a> ·
<a href="https://getartcraft.com/">getartcraft.com</a> ·
<a href="https://getartcraft.com/apps">The Crafting Apps</a> ·
<a href="https://getartcraft.com/apps/wordcraft">WordCraft</a>
</p>
## License and credits
WordCraft is dual-licensed under [MIT](LICENSE-MIT) or [Apache-2.0](LICENSE-APACHE), at your option.
Copyright (c) 2026 ArtCraft Team and the WordCraft contributors. Required notices are in [NOTICE](NOTICE).
Bundled fonts, icons, images and other assets keep their own open licenses; each one is listed
with its author, source and license in [ATTRIBUTION.md](ATTRIBUTION.md).
The English spelling dictionary and hyphenation come from Grady Ward's public-domain Moby
Hyphenator II word list. Polish spelling reads the Hunspell `pl_PL` dictionary installed on the system (not bundled), as
do Russian, Portuguese, Czech, Italian, Croatian and Turkish spelling (how to install them:
[docs/spelling-dictionaries.md](docs/spelling-dictionaries.md)), and
Polish hyphenation the TeX patterns by Hanna Kołodziejska, Bogusław Jackowski and Marek Ryćko (MIT
option). The sample documents and templates are original text written for WordCraft.
The ArtCraft name, wordmark and logos in [`docs/brand/`](docs/brand/) are trademarks of the
ArtCraft Team and are not covered by this license. They may be used only unmodified, and only as
part of this repository and WordCraft, under [`docs/brand/LICENSE-brand.txt`](docs/brand/LICENSE-brand.txt).
Forks and modified versions must remove them.
<p align="center">
<a href="https://getartcraft.com/"><img alt="ArtCraft" src="docs/brand/artcraft-mark.svg" width="28"></a><br>
<sub>Made by the <a href="https://getartcraft.com/">ArtCraft</a> team and community.</sub>
</p>