diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index af962f3b8..f60911143 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -41,6 +41,12 @@ Generated-in-code art is original and has no file to list: the UI icon set (`cra | `assets/fonts/SourceSerif4-It.ttf` | Paul D. Hunt / Frank Grießhammer, Adobe (released as open source) | https://github.com/adobe-fonts/source-sans · https://github.com/adobe-fonts/source-serif | OFL-1.1 (`assets/fonts/OFL-SourceSans3.txt`, `OFL-SourceSerif4.txt`) | Open-source typeface (Latin UI/document font, carried over from DesignCraft) | | `assets/fonts/SourceSerif4-Regular.ttf` | Paul D. Hunt / Frank Grießhammer, Adobe (released as open source) | https://github.com/adobe-fonts/source-sans · https://github.com/adobe-fonts/source-serif | OFL-1.1 (`assets/fonts/OFL-SourceSans3.txt`, `OFL-SourceSerif4.txt`) | Open-source typeface (Latin UI/document font, carried over from DesignCraft) | | `assets/fonts/SourceSerif4-Semibold.ttf` | Paul D. Hunt / Frank Grießhammer, Adobe (released as open source) | https://github.com/adobe-fonts/source-sans · https://github.com/adobe-fonts/source-serif | OFL-1.1 (`assets/fonts/OFL-SourceSans3.txt`, `OFL-SourceSerif4.txt`) | Open-source typeface (Latin UI/document font, carried over from DesignCraft) | +| `docs/images/review.png` | WordCraft contributors | screenshot of WordCraft itself (sample document written for WordCraft, rendered by `ui_shot`) | MIT OR Apache-2.0 | Original; no Microsoft UI or assets | +| `docs/images/references.png` | WordCraft contributors | screenshot of WordCraft itself (sample document written for WordCraft, rendered by `ui_shot`) | MIT OR Apache-2.0 | Original; no Microsoft UI or assets | +| `docs/images/hero.png` | WordCraft contributors | screenshot of WordCraft itself (sample document written for WordCraft, rendered by `ui_shot`) | MIT OR Apache-2.0 | Original; no Microsoft UI or assets | +| `docs/images/design.png` | WordCraft contributors | screenshot of WordCraft itself (sample document written for WordCraft, rendered by `ui_shot`) | MIT OR Apache-2.0 | Original; no Microsoft UI or assets | +| `docs/images/dark.png` | WordCraft contributors | screenshot of WordCraft itself (sample document written for WordCraft, rendered by `ui_shot`) | MIT OR Apache-2.0 | Original; no Microsoft UI or assets | +| `docs/images/backstage.png` | WordCraft contributors | screenshot of WordCraft itself (sample document written for WordCraft, rendered by `ui_shot`) | MIT OR Apache-2.0 | Original; no Microsoft UI or assets | | `docs/brand/LICENSE-brand.txt` | ArtCraft Team | craftrules `assets/brand/` | ArtCraft trademark, `docs/brand/LICENSE-brand.txt` | Not open source; usable unmodified only | | `docs/brand/artcraft-logo-white.png` | ArtCraft Team | craftrules `assets/brand/` | ArtCraft trademark, `docs/brand/LICENSE-brand.txt` | Not open source; usable unmodified only | | `docs/brand/artcraft-logo-white.svg` | ArtCraft Team | craftrules `assets/brand/` | ArtCraft trademark, `docs/brand/LICENSE-brand.txt` | Not open source; usable unmodified only | diff --git a/README.md b/README.md index c3ef4680d..9022bba7b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,244 @@ -WordCraft -========== +

+ + + + ArtCraft + + +

-By ArtCraft +

WordCraft

+ +

+ Writing and document design; an open-source, clean-room reimplementation of Microsoft Word, rebuilt in pure Rust. +

+ +

+ A fast, open-source word processor with the Word workflow you already know: 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.
+ By the ArtCraft team. +

+ +

+ Written in Rust + Runs on macOS, Windows, Linux, BSD and the web + License: MIT OR Apache-2.0 + Agent-drivable over MCP +

+ +

+ Join the ArtCraft community on Discord +

+ +

+ WordCraft on getartcraft.com · + ArtCraft · + All Crafting Apps +

+ +
+ +

+ 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. +
The Open Studio Handbook, WordCraft's built-in sample: the ribbon, live Styles gallery, rulers and the Navigation pane. +

+ +> [!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).** + +

+ A tour · + Why WordCraft · + What works today · + Quick start · + For agents · + Architecture · + Roadmap · + The Crafting Apps · + License and credits +

+ +## 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`). + + + + + + + + + + + + + +
The Review tab with Track Changes on: the inserted words Cheaper rent is one reason and forty are underlined in magenta, the replaced words are struck through, two commented phrases are shaded and the Comments pane on the right shows both comments with Go to, Resolve and Delete buttons

Review. Track changes, comments, accept and reject, spelling and grammar as you type.

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

References. Tables of contents, footnotes, citations in APA, MLA, Chicago or IEEE, index and captions.

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

Design. Themes, style sets, paragraph spacing, watermarks, page colour and borders.

WordCraft in dark mode with the Insert tab open and formatting marks shown: pilcrows at paragraph ends and dots for spaces

Dark mode with formatting marks, and the Insert tab: tables, pictures, shapes, links, headers, footers, fields and symbols.

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

File. Start from a template, open recent documents, edit properties, export to PDF and other formats.

+ +## Why WordCraft + +- **Familiar.** Word's 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, .txt; 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 389 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, sort, formulas, text ↔ table | +| **Pages** | Margins, orientation, size, columns, page/column/section breaks, headers and footers (first page, odd/even), page numbers, watermark | +| **Objects** | Pictures (resize, crop, recolour, brightness/contrast, transparency, background removal, picture styles, rotate), shapes, text boxes, floating position | +| **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, thesaurus, word count, comments, 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 | +| **Files** | .docx read/write (opens in Word), PDF export, .odt, .rtf, .html, .md, .txt import/export, page images | + +The honest picture, area by area, is in [ROADMAP.md](ROADMAP.md) and the generated +[feature parity report](docs/parity.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 +``` + +Command line: + +```sh +wordcraft-cli convert report.docx report.pdf # docx, pdf, odt, rtf, html, md, 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 +``` + +Web: `cd apps/wordcraft-web && trunk serve`, then open . + +## 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 +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`). + +## Architecture + +| Layer | Crate | Job | +|---|---|---| +| L0 | `wordcraft-geom` | units and measurements | +| L1 | `wordcraft-doc`, `wordcraft-fonts`, `wordcraft-proof` | document model and editing; fonts and shaping; spelling, grammar, hyphenation | +| 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 (krilla) | +| L4 | `wordcraft-engine` | session, undo, 389 commands, Word feature catalog | +| L5 | `wordcraft-mcp` | MCP server | +| L6 | `wordcraft-ui-egui` | the Word-style front end (swappable) | +| apps | `wordcraft`, `wordcraft-cli`, `wordcraft-web` | desktop, command line, browser | + +`cargo xtask ci` runs formatting, clippy, ~250 tests, the asset-attribution check, the layering +check and the wasm build. Contributor and agent instructions: [AGENTS.md](AGENTS.md). + +## Roadmap + +WordCraft covers 87% of Word's ribbon features with commands today; we estimate about 58% of +real feature parity once depth is counted. Next: text wrap around floating pictures, margin +comment balloons, column balancing, charts, an equation editor and signed releases for every +platform. Details and estimates: [ROADMAP.md](ROADMAP.md). + +## 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 | +|:-:|---|---|---|---| +| | **PhotoCraft** | Image editing: layers, masks, type and real PSD files | [GitHub](https://github.com/storytold/photocraft) | [Website](https://getartcraft.com/apps/photocraft) | +| | **VectorCraft** | Vector illustration | [GitHub](https://github.com/storytold/vectorcraft) | [Website](https://getartcraft.com/apps/vectorcraft) | +| | **FilmCraft** | Video editing, color and sound | [GitHub](https://github.com/storytold/filmcraft) | [Website](https://getartcraft.com/apps/filmcraft) | +| | **LightCraft** | Photo library and raw development | [GitHub](https://github.com/storytold/lightcraft) | [Website](https://getartcraft.com/apps/lightcraft) | +| | **PrintCraft** | Reading, organizing and protecting PDFs | [GitHub](https://github.com/storytold/printcraft) | [Website](https://getartcraft.com/apps/printcraft) | +| | **EffectCraft** | Motion graphics and visual effects | [GitHub](https://github.com/storytold/effectcraft) | [Website](https://getartcraft.com/apps/effectcraft) | +| | **DesignCraft** | Page layout and publishing | [GitHub](https://github.com/storytold/designcraft) | [Website](https://getartcraft.com/apps/designcraft) | +| | **WordCraft** | **Writing and document design · you are here** | [GitHub](https://github.com/storytold/wordcraft) | [Website](https://getartcraft.com/apps/wordcraft) | + +And [**ArtCraft**](https://getartcraft.com/) itself, our AI image and video studio for artists who want real control. + +
+ +

+ Join the ArtCraft community on Discord +

+ +

Come make things with us

+ +

+ 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. +

+ +

+ discord.gg/artcraft · + getartcraft.com · + The Crafting Apps · + WordCraft +

+ +## 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 spelling dictionary and hyphenation come from Grady Ward's public-domain Moby Hyphenator II +word list. 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. + +Microsoft and Microsoft Word are trademarks of the Microsoft group of companies. Adobe, Photoshop, Illustrator, Premiere Pro, Lightroom, Acrobat, After Effects and InDesign are trademarks or registered trademarks of Adobe Inc. in the United States and/or other countries. WordCraft is an independent, open-source project and is not affiliated with, sponsored by or endorsed by Microsoft Corporation or Adobe Inc.; these names are used only to describe the workflows it is compatible with. + +

+ ArtCraft
+ Made by the ArtCraft team and community. +

diff --git a/crates/engine/src/cmd/review.rs b/crates/engine/src/cmd/review.rs index c9541c5fa..dd98baf06 100644 --- a/crates/engine/src/cmd/review.rs +++ b/crates/engine/src/cmd/review.rs @@ -373,7 +373,7 @@ fn word_count(s: &mut Session, _: &Value) -> CmdResult { /// Issues (spelling + grammar) in one paragraph as positions. fn para_issues(s: &Session, story: StoryRef, path: &wordcraft_doc::Path) -> Vec<(Pos, Pos, wordcraft_proof::Issue)> { let Some(p) = s.doc.para(story, path) else { return Vec::new() }; - let text: String = p.text.chars().map(|c| if c == wordcraft_doc::para::OBJ { ' ' } else { c }).collect(); + let text = wordcraft_layout::para::proof_text(p); let mut v: Vec = wordcraft_proof::check_spelling(&text); v.extend(wordcraft_proof::check_grammar(&text)); v.sort_by_key(|i| i.start); diff --git a/crates/fonts/src/word.rs b/crates/fonts/src/word.rs index 729d1ec5d..1b259be72 100644 --- a/crates/fonts/src/word.rs +++ b/crates/fonts/src/word.rs @@ -98,14 +98,18 @@ pub fn line_metrics(face: &crate::FontFace) -> (f64, f64) { } let mut v = (face.ascent.max(1.0), face.descent.abs()); if let Some(f) = face.skrifa() { - if let Ok(os2) = f.os2() { - let (a, d) = (os2.us_win_ascent() as f64, os2.us_win_descent() as f64); - if a > 0.0 && a + d < face.upem * 4.0 { - v = (a, d); - } - } else if let Ok(hhea) = f.hhea() { - let gap = hhea.line_gap().to_i16().max(0) as f64; - v = (hhea.ascender().to_i16() as f64 + gap, (hhea.descender().to_i16() as f64).abs()); + // hhea ascender + descender + line gap (Word on macOS); OS/2 win metrics only when the + // hhea values are missing, and never more than twice the em. + let hhea = f.hhea().ok().map(|h| { + let gap = h.line_gap().to_i16().max(0) as f64; + (h.ascender().to_i16() as f64 + gap / 2.0, (h.descender().to_i16() as f64).abs() + gap / 2.0) + }); + let win = f.os2().ok().map(|o| (o.us_win_ascent() as f64, o.us_win_descent() as f64)); + let ok = |m: &(f64, f64)| m.0 > 0.0 && m.0 + m.1 <= face.upem * 2.0; + if let Some(m) = hhea.filter(ok) { + v = m; + } else if let Some(m) = win.filter(ok) { + v = m; } } cache.lock().unwrap_or_else(|e| e.into_inner()).insert(face.id(), v); diff --git a/crates/layout/src/display.rs b/crates/layout/src/display.rs index 4efb17612..f66d071d3 100644 --- a/crates/layout/src/display.rs +++ b/crates/layout/src/display.rs @@ -173,6 +173,35 @@ fn lines( let top = y + (line.top - first.top); let base = top + (line.baseline - line.top); let bottom = top + line.height; + // Commented text gets a soft shade (comment anchors are object markers). + if opts.markup + && let Some(p) = para + { + let mut open: Option = None; + let mut ranges = Vec::new(); + for off in p.object_offsets() { + match p.object_at(off) { + Some(InlineObject::CommentStart { .. }) => open = open.or(Some(off)), + Some(InlineObject::CommentEnd { .. }) => { + ranges.push((open.take().unwrap_or(0), off)); + } + _ => {} + } + } + if let Some(o) = open { + ranges.push((o, p.len())); + } + for (a, b) in ranges { + if b <= line.start || a >= line.stop { + continue; + } + if let (Some(x0), Some(x1)) = (pl.x_of(li, a.max(line.start)), pl.x_of(li, b.min(line.stop))) + && x1 > x0 + { + out.push(Draw::Fill { rect: Rect::new(x + x0, top, x1 - x0, line.height), color: Rgb(0xEF, 0xE3, 0xF7), alpha }); + } + } + } // Backgrounds first: highlight and character shading. for k in line.c0..line.c1 { let (Some(c), Some(cx), Some(nx)) = (pl.clusters.get(k), line.xs.get(k - line.c0), line.xs.get(k + 1 - line.c0)) else { continue }; diff --git a/crates/layout/src/para.rs b/crates/layout/src/para.rs index 30acb0770..1d2b963cc 100644 --- a/crates/layout/src/para.rs +++ b/crates/layout/src/para.rs @@ -932,7 +932,7 @@ fn proof_issues(p: &Paragraph) -> Vec<(usize, usize, bool)> { if p.text.trim().is_empty() || p.text.len() > 100_000 { return Vec::new(); } - let text: String = p.text.chars().map(|c| if c == OBJ { ' ' } else { c }).collect(); + let text = proof_text(p); let skip = |a: usize, b: usize| { p.run_ranges().any(|(r, c)| r.start < b && a < r.end && (c.no_proof == Some(true) || c.hidden == Some(true) || c.link.is_some())) }; @@ -941,3 +941,20 @@ fn proof_issues(p: &Paragraph) -> Vec<(usize, usize, bool)> { v.extend(wordcraft_proof::check_grammar(&text).into_iter().filter(|i| !skip(i.start, i.end)).map(|i| (i.start, i.end, true))); v } + +/// Text for proofing with the same byte offsets: inline objects and tracked deletions become +/// U+0001 bytes (neither words nor spaces). +pub fn proof_text(p: &wordcraft_doc::Paragraph) -> String { + let mut out = String::with_capacity(p.text.len()); + for (i, c) in p.text.char_indices() { + let deleted = c == wordcraft_doc::para::OBJ || p.props_of_char(i).del.is_some(); + if deleted { + for _ in 0..c.len_utf8() { + out.push('\u{1}'); + } + } else { + out.push(c); + } + } + out +} diff --git a/crates/render/src/lib.rs b/crates/render/src/lib.rs index 5938cb1de..262e1a4b4 100644 --- a/crates/render/src/lib.rs +++ b/crates/render/src/lib.rs @@ -192,13 +192,13 @@ fn draw_watermark(ctx: &mut RenderContext, view: Affine, page: &Page, wm: &wordc return; } let diag = if wm.diagonal { ((page.w as f64).powi(2) + (page.h.min(2000.0) as f64).powi(2)).sqrt() } else { page.w as f64 }; - let size = (diag * 0.7 / raw_w).min(300.0); + let size = (diag * 0.5 / raw_w).min(200.0); let k = size / upem; let angle = if wm.diagonal { -((page.h.min(2000.0) as f64) / page.w.max(1.0) as f64).atan() } else { 0.0 }; let base = Affine::translate((page.w as f64 / 2.0, page.h.min(2000.0) as f64 / 2.0)) * Affine::rotate(angle) * Affine::translate((-raw_w * size / 2.0, size * 0.35)); - ctx.set_paint(color(wm.color, if wm.semitransparent { 0.5 } else { 1.0 })); + ctx.set_paint(color(wm.color, if wm.semitransparent { 0.35 } else { 0.8 })); let db = FontDb::global(); let mut x = 0.0; for g in &glyphs { diff --git a/crates/ui-egui/src/backstage.rs b/crates/ui-egui/src/backstage.rs index e1f54aced..fa883a0fc 100644 --- a/crates/ui-egui/src/backstage.rs +++ b/crates/ui-egui/src/backstage.rs @@ -115,7 +115,7 @@ fn template_tile(ui: &mut Ui, app: &mut WordApp, label: &str, template: &str) { let tex = ui.ctx().data(|d| d.get_temp::(egui::Id::new(&key))).or_else(|| { let mut s = wordcraft_engine::Session::new(wordcraft_doc::Document::new()); let _ = s.run("file.new", &json!({"template": template})); - let l = s.layout(); + let l = s.export_layout(); let page = l.pages.first()?; let img = wordcraft_render::render_page(&s.doc, page, 150.0 / page.w * ppp, &Default::default()); let px = img.to_straight(); diff --git a/docs/images/backstage.png b/docs/images/backstage.png new file mode 100644 index 000000000..155971349 Binary files /dev/null and b/docs/images/backstage.png differ diff --git a/docs/images/dark.png b/docs/images/dark.png new file mode 100644 index 000000000..a38806f5f Binary files /dev/null and b/docs/images/dark.png differ diff --git a/docs/images/design.png b/docs/images/design.png new file mode 100644 index 000000000..4c692cb22 Binary files /dev/null and b/docs/images/design.png differ diff --git a/docs/images/hero.png b/docs/images/hero.png new file mode 100644 index 000000000..66de40f7e Binary files /dev/null and b/docs/images/hero.png differ diff --git a/docs/images/references.png b/docs/images/references.png new file mode 100644 index 000000000..aa99757f8 Binary files /dev/null and b/docs/images/references.png differ diff --git a/docs/images/review.png b/docs/images/review.png new file mode 100644 index 000000000..f33f46f43 Binary files /dev/null and b/docs/images/review.png differ diff --git a/docs/parity.md b/docs/parity.md index 9eba661e9..bd74e9c09 100644 --- a/docs/parity.md +++ b/docs/parity.md @@ -2,48 +2,31 @@ Generated by `cargo xtask parity` (`wordcraft-cli parity --markdown`): the word-processor feature catalog (`crates/engine/src/catalog.rs`) compared with the live command registry. -**250 of 405 catalog features have commands (61.7%).** +**354 of 405 catalog features have commands (87.4%).** | Tab | Live | Total | |---|---|---| -| File | 11 | 20 | -| Quick Access | 2 | 4 | -| Home | 82 | 100 | -| Insert | 34 | 53 | +| File | 20 | 20 | +| Quick Access | 4 | 4 | +| Home | 89 | 100 | +| Insert | 42 | 53 | | Draw | 0 | 11 | -| Design | 9 | 10 | -| Layout | 11 | 19 | -| References | 10 | 24 | -| Mailings | 0 | 17 | -| Review | 17 | 29 | -| View | 20 | 29 | -| Table Design | 4 | 5 | -| Table Layout | 26 | 30 | -| Picture Format | 0 | 13 | -| Shape Format | 0 | 6 | -| Header & Footer | 2 | 5 | -| Editing | 22 | 24 | -| Tools | 0 | 6 | +| Design | 10 | 10 | +| Layout | 18 | 19 | +| References | 24 | 24 | +| Mailings | 17 | 17 | +| Review | 26 | 29 | +| View | 25 | 29 | +| Table Design | 5 | 5 | +| Table Layout | 28 | 30 | +| Picture Format | 13 | 13 | +| Shape Format | 2 | 6 | +| Header & Footer | 5 | 5 | +| Editing | 23 | 24 | +| Tools | 3 | 6 | ## Missing -### File - -- Backstage › Share (`file.share`) -- Backstage › Protect Document (`file.protect`) -- Backstage › Inspect Document (`file.inspect`) -- Backstage › Check Accessibility (`file.accessibility`) -- Backstage › Check Compatibility (`file.compatibility`) -- Backstage › Version History (`file.versions`) -- Backstage › Recover Unsaved (`file.recover`) -- Backstage › New from Template (`file.newFromTemplate`) -- Backstage › Save as Template (`file.saveTemplate`) - -### Quick Access - -- Toolbar › Repeat (`edit.repeat`) -- Toolbar › AutoSave (`file.autosave`) - ### Home - Clipboard › Paste Special (`edit.pasteSpecial`) @@ -51,24 +34,16 @@ Generated by `cargo xtask parity` (`wordcraft-cli parity --markdown`): the word- - Font › Character Border (`format.border`) - Font › Phonetic Guide (`format.phonetic`) - Font › Enclose Characters (`format.enclose`) -- Paragraph › Define New Bullet (`para.defineBullet`) -- Paragraph › Define New Number Format (`para.defineNumber`) -- Paragraph › Set Numbering Value (`para.setNumberingValue`) -- Paragraph › Text Direction RTL (`para.rtl`) - Paragraph › Asian Typography (`para.asianTypography`) - Styles › Style Inspector (`styles.inspector`) - Styles › Manage Styles (`styles.manage`) - Styles › Apply Styles (`styles.apply`) - Editing › Advanced Find (`edit.advancedFind`) -- Editing › Select Objects (`select.objects`) -- Editing › Select Similar Formatting (`select.similar`) - Voice › Dictate (`tools.dictate`) -- Editor › Editor (`review.editor`) ### Insert - Tables › Draw Table (`table.draw`) -- Tables › Excel Spreadsheet (`insert.spreadsheet`) - Illustrations › Online Pictures (`insert.onlinePicture`) - Illustrations › Icons (`insert.icon`) - Illustrations › 3D Models (`insert.model3d`) @@ -78,13 +53,6 @@ Generated by `cargo xtask parity` (`wordcraft-cli parity --markdown`): the word- - Illustrations › Drawing Canvas (`insert.canvas`) - Add-ins › Get Add-ins (`addins.get`) - Media › Online Video (`insert.video`) -- Links › Cross-reference (`insert.crossReference`) -- Header & Footer › Link to Previous (`layout.linkToPrevious`) -- Text › Quick Parts (`insert.quickParts`) -- Text › AutoText (`insert.autoText`) -- Text › Document Property (`insert.docProperty`) -- Text › Signature Line (`insert.signatureLine`) -- Text › Object (`insert.object`) - Symbols › Ink Equation (`insert.inkEquation`) ### Draw @@ -101,138 +69,42 @@ Generated by `cargo xtask parity` (`wordcraft-cli parity --markdown`): the word- - Insert › Drawing Canvas (`insert.canvas`) - Replay › Ink Replay (`draw.replay`) -### Design - -- Document Formatting › Effects (`design.effects`) - ### Layout -- Arrange › Position (`arrange.position`) -- Arrange › Wrap Text (`arrange.wrap`) -- Arrange › Bring Forward (`arrange.bringForward`) -- Arrange › Send Backward (`arrange.sendBackward`) -- Arrange › Selection Pane (`arrange.selectionPane`) -- Arrange › Align (`arrange.align`) - Arrange › Group (`arrange.group`) -- Arrange › Rotate (`arrange.rotate`) - -### References - -- Footnotes › Footnote Options (`references.noteOptions`) -- Research › Researcher (`references.researcher`) -- Citations › Insert Citation (`references.citation`) -- Citations › Manage Sources (`references.sources`) -- Citations › Style (`references.citationStyle`) -- Citations › Bibliography (`references.bibliography`) -- Captions › Insert Table of Figures (`references.tableOfFigures`) -- Captions › Update Table of Figures (`references.updateFigures`) -- Captions › Cross-reference (`insert.crossReference`) -- Index › Mark Entry (`references.markEntry`) -- Index › Insert Index (`references.index`) -- Index › Update Index (`references.updateIndex`) -- Table of Authorities › Mark Citation (`references.markCitation`) -- Table of Authorities › Insert Table of Authorities (`references.tableOfAuthorities`) - -### Mailings - -- Create › Envelopes (`mailings.envelopes`) -- Create › Labels (`mailings.labels`) -- Start Mail Merge › Start Mail Merge (`mailings.start`) -- Start Mail Merge › Select Recipients (`mailings.recipients`) -- Start Mail Merge › Edit Recipient List (`mailings.editRecipients`) -- Write & Insert Fields › Highlight Merge Fields (`mailings.highlightFields`) -- Write & Insert Fields › Address Block (`mailings.addressBlock`) -- Write & Insert Fields › Greeting Line (`mailings.greetingLine`) -- Write & Insert Fields › Insert Merge Field (`mailings.insertField`) -- Write & Insert Fields › Rules (`mailings.rules`) -- Write & Insert Fields › Match Fields (`mailings.matchFields`) -- Preview Results › Preview Results (`mailings.preview`) -- Preview Results › Next Record (`mailings.next`) -- Preview Results › Previous Record (`mailings.previous`) -- Preview Results › Find Recipient (`mailings.findRecipient`) -- Preview Results › Check for Errors (`mailings.checkErrors`) -- Finish › Finish & Merge (`mailings.finish`) ### Review -- Proofing › Spelling & Grammar (`review.spelling`) -- Proofing › Thesaurus (`review.thesaurus`) -- Speech › Read Aloud (`review.readAloud`) -- Accessibility › Check Accessibility (`file.accessibility`) - Language › Translate (`review.translate`) -- Language › Language (`review.language`) -- Tracking › Show Markup (`review.showMarkup`) -- Compare › Compare (`review.compare`) -- Compare › Combine (`review.combine`) - Protect › Block Authors (`review.blockAuthors`) -- Protect › Restrict Editing (`review.restrict`) - Ink › Hide Ink (`review.hideInk`) ### View -- Immersive › Immersive Reader (`view.immersive`) -- Page Movement › Vertical (`view.vertical`) -- Page Movement › Side to Side (`view.sideToSide`) - Window › Arrange All (`view.arrangeAll`) - Window › View Side by Side (`view.sideBySide`) - Window › Synchronous Scrolling (`view.syncScroll`) - Window › Switch Windows (`view.switchWindows`) -- Macros › Macros (`tools.macros`) -- Macros › Record Macro (`tools.recordMacro`) - -### Table Design - -- Borders › Border Painter (`table.borderPainter`) ### Table Layout - Draw › Draw Table (`table.draw`) - Draw › Eraser (`table.eraser`) -- Alignment › Text Direction (`table.textDirection`) -- Alignment › Cell Margins (`table.cellMargins`) - -### Picture Format - -- Adjust › Remove Background (`picture.removeBackground`) -- Adjust › Corrections (`picture.corrections`) -- Adjust › Color (`picture.color`) -- Adjust › Artistic Effects (`picture.effects`) -- Adjust › Transparency (`picture.transparency`) -- Adjust › Compress Pictures (`picture.compress`) -- Adjust › Change Picture (`picture.change`) -- Adjust › Reset Picture (`picture.reset`) -- Picture Styles › Picture Styles (`picture.style`) -- Picture Styles › Picture Border (`picture.border`) -- Accessibility › Alt Text (`picture.altText`) -- Size › Crop (`picture.crop`) -- Size › Size (`picture.size`) ### Shape Format -- Shape Styles › Shape Fill (`shape.fill`) -- Shape Styles › Shape Outline (`shape.outline`) - Shape Styles › Shape Effects (`shape.effects`) - Text › Text Direction (`shape.textDirection`) - Text › Align Text (`shape.alignText`) - Text › Create Link (`shape.link`) -### Header & Footer - -- Navigation › Previous Section (`hf.previous`) -- Navigation › Next Section (`hf.next`) -- Position › Header from Top (`hf.position`) - ### Editing -- Selection › Extend Selection (F8) (`select.extend`) - Selection › Column Selection (`select.column`) ### Tools -- Proofing › AutoCorrect Options (`tools.autocorrect`) -- Proofing › Set Proofing Language (`review.language`) - Customize › Customize Ribbon (`tools.customizeRibbon`) - Customize › Customize Keyboard (`tools.customizeKeyboard`) -- Protection › Encrypt with Password (`file.encrypt`) - Templates › Templates and Add-ins (`tools.templates`)