Files
designcraft/docs/gaps.md
T
aiongg 18ae8e4761 Merge upstream main a184db6f8 with our 15 PRs (batch-0) into next
Conflicts resolved per file (both sides kept unless noted):
crates/engine/src/atomic.rs | 1 | main's: `write_file` removed (main routes command writes through `crate::io::write_file`); its one caller in file.rs now uses `crate::io::write_file`
crates/engine/src/cmd/datamerge/fill.rs | 1 | next's `Graphic` literal (has `clip` and `wrap`, which next's `Graphic` carries)
crates/engine/src/cmd/datamerge/mod.rs | 1 | main's `read_path_capped` (crate::io metadata/read_capped, roots checked); next's capped read is the same behaviour
crates/engine/src/cmd/datamerge/parse.rs | 1 | main's (`crate::io::metadata`, `crate::io::Metadata`)
crates/engine/src/cmd/edit.rs | 1 | next's `spread_param(p, "edit.paste")` (the second argument is the command id on both sides)
crates/engine/src/cmd/export.rs | 3 | main's: EPUB params doc, `toc_title` once (main's position; next's duplicate dropped)
crates/engine/src/cmd/file.rs | 7 | place doc: next's (lists page/rect/autoflow params #803 checks); next's recent-file functions + main's `foreign_document`; next's open (load_bytes, warnings, non-DesignCraft refusal) with main's checked `crate::io::read_file` for the bytes; main's `check_write` be
crates/engine/src/cmd/find.rs | 7 | main's Find scope (FindContext, scope/selection/story, continuation, UTF-8 repair) on next's `designcraft_compose::grep::Grep` (dialect GREP): find uses `find_all` capped at MAX_MATCHES, change uses `replacements`/`find_all` (literal change text not expanded), fin
crates/engine/src/cmd/fonts.rs | 1 | next's (`has_style`, resolved/replacement face); `has_style` already compares styles ignoring spacing and case, which is main's `same_style` fix; main's test kept
crates/engine/src/cmd/interchange.rs | 1 | next's `import_idml_report_with_previews` (previews for unreadable links)
crates/engine/src/cmd/layout.rs | 8 | pages.insert: main's overflow-safe `after` + next's checked `parent_ref`; main's duplicateSpread doc; layout.section: next's `SectionEdit` (already keeps unnamed settings, #717) with main's `d.repaginate()` moved into `SectionEdit::apply` (remove and set paths),
crates/engine/src/cmd/links.rs | 5 | next's links.list (no doc clone); main's `text_status` via crate::io; `use std::io::Read` dropped (unused after main's read_capped); test literals main's. `link_missing` (next) uses `crate::io::exists` for the file-guard scan
crates/engine/src/cmd/object.rs | 4 | object.fill/stroke tint-alone: main's (23e1680e7; out-of-range tint is an error, which main's test asserts); object.fit doc: next's (lists `axis`)
crates/engine/src/cmd/paths.rs | 1 | next's (shatai transform on outlines)
crates/engine/src/cmd/place_text.rs | 1 | next's `add_flow_frame` (used by autoflow)
crates/engine/src/cmd/preflight.rs | 2 | next's overset/unplacedStory issue (its `overset_location` already applies the parent transform main's #738 fix adds); next's two test modules kept with main's
crates/engine/src/cmd/scripts.rs | 1 | combined: next's `in_undo_step = false` (#406) + main's full rollback of a failed script (#709)
crates/engine/src/cmd/style.rs | 14 | param docs next's (gradient swatch.create, swatch stops, model colours); create_para next's; rename_style main's structure (rename entry, then `redirect_style_refs`), redirect has next's full reference set (cells, defaults, notes, TOC) + main's never-based-on-it
crates/engine/src/cmd/text.rs | 10 | main's selectSentence/Paragraph/Story + select_around; next's selectionAttrs (mixed) + main's openTypeFeatures/type.feature; main's comments; tracked typing: next's `reserve_command_text` + main's `insert_format_at`; empty-paragraph mark formatting main's (with `
crates/engine/src/cmd/thread.rs | 1 | next's `spread_param(p, "text.thread")`
crates/engine/src/dtd.rs | 1 | next's linear, depth-bounded `expand_parameter_entities` with main's budget (input + 1 MiB, `MAX_EXPANDED_BYTES`) and message ("expand the DTD beyond"); 16 MiB constant removed; both sides' tests pass on message
crates/engine/src/guard.rs | 2 | main's whole-transaction snapshot (docs, active, journal; #742) + next's `in_undo_step` restore; tests both
crates/engine/src/lib.rs | 5 | LoadedGraphic doc next's; next's `new_document_preview`; execute: main's `discard_stale_find_scope()` before next's nested-undo run; modules both (tests_autosize, tests_file_guard, tests_params, tests_roots)
crates/engine/src/recovery.rs | 1 | next's test (superset of main's assertion)
crates/engine/src/tests.rs | 4 | moved tests deduplicated (identical on both sides); next's preflight and direct-selection/kerning tests + main's style-delete, locked-frame and baseline-fit tests
crates/engine/src/tests_idml.rs | 3 | main's order (drop cap and margins tests identical on both sides, once each)
crates/ui-egui/src/canvas.rs | 3 | next's screen_options/DisplayKey block and tests kept; two tests that auto-merge had added twice (parent_guides_on_a_page_are_not_picked_there, baseline_grid_lines_are_the_ones_on_the_page) kept once; main's `typing`/`screen_at`/`click` helpers and its tests clicks
crates/ui-egui/src/control.rs | 3 | main's `count` check and pending budget (control queue + synthetic queue); exact-budget test runs both sides' cases (click 255 on 9,492 pending; drag 9492×255)
crates/ui-egui/src/cursors.rs | 1 | main's (same Pen cursor set)
crates/ui-egui/src/dialogs.rs | 14 | dialog body (newDocument … alert match) is next's text, with main's Find/Change scope reset (`set_field`, `reset_find_scope`, `find_change_params`) and main's Create Guides / Margins and Columns arms ported in; `Dialog::new` ruby section (next) + main's `set_fi
crates/ui-egui/src/i18n.rs | 7 | ka and pl modules, languages, statics and lookups both; `category_first` covers uk, ru, pl, ka and `count_label` keeps next's Czech plurals; shared TABLE union; next's duplicate rows for Auto, Number:, Gutter:, Top:, Bottom:, Inside:, Outside:, Left:, Right: dropped
crates/ui-egui/src/i18n/ar.rs | 2 | union of rows, no duplicate keys
crates/ui-egui/src/i18n/it.rs | 1 | union of rows, no duplicate keys
crates/ui-egui/src/i18n/ja.rs | 1 | union of rows, no duplicate keys
crates/ui-egui/src/i18n/pt_br.rs | 1 | union of rows, no duplicate keys
crates/ui-egui/src/i18n/uk.rs | 1 | union of rows, no duplicate keys
crates/ui-egui/src/icons.rs | 2 | both tests (main's typography icon, next's distribute icons)
crates/ui-egui/src/lib.rs | 11 | UiState: next's tabs_panel + main's last_color/last_gradient; `cursors` field once; next's SVG paste and paste-on-spread-in-view; next's extensionless document open; opens_as_document next's comment; tests both (next's control bar / key-name tests, main's rich black
crates/ui-egui/src/menus.rs | 15 | app.language doc next's text with pl and ka; UI_COMMANDS both (next's Tabs, Toggle Presentation, Apply None text; main's panel commands, Apply Color, Apply Gradient); Edit › Interface Language stays out (next moved it to Preferences); Type menu main's order with
crates/ui-egui/src/panels/glyphs.rs | 1 | next's (already has main's scroll-bar fix); the scroll-bar test module auto-merge had added twice kept once
crates/ui-egui/src/panels/layers.rs | 3 | next's drag-and-drop `object_rows`, with main's features ported into it: selection reveal (layer opens, row scrolls into view once), selected rows highlighted (also a group whose member is selected), double-click rename in place (`object.rename` queued like
crates/ui-egui/src/panels/mod.rs | 6 | tabs + typography modules and color_panel_tests; SelInfo has wrap_side/wrap_contour and wrap_offsets (offsets from the graphic's own wrap when it is selected); next's swatch_picker returning the chip response; next's content_selection_tests
crates/ui-egui/src/panels/pages.rs | 1 | next's (parents dragged by id)
crates/ui-egui/src/panels/properties.rs | 4 | next's swatch popup (Apply To, Tint); main's four wrap offsets then next's Wrap To / Contour Type; test fixtures main's (`..Default::default()`, no unused builder)
crates/ui-egui/src/panels/swatches.rs | 3 | main's Delete Swatch button + next's New Swatch comment; next's draggable rows; click: main's PICKED + fill/stroke in front, with next's no-apply on double-click
crates/ui-egui/src/toolbar.rs | 2 | main's Apply Color / Gradient / None wells and functions; next's apply_none doc line
crates/compose/src/lib.rs | 5 | next's line loop kept (mark_leading + last_line_mark, wrap segments/carry, grid gyoudori); main's mark-chars base_leading block (auto-merged) stays beside it. `fits`: next's #106 rule (baseline fit for horizontal frames, full descent for paths, vertical text, footnote
crates/compose/src/tests.rs | 5 | next's tests (tombstone set, sliver/one-sided/contour/clipping wrap tests, borders, lists, kenten, grid, anchored wrap, balance, shaped frames) plus main's an_empty_last_paragraph_isnt_overset; main's wrap_object_beside_one_narrow_column_leaves_the_other_alone re-ad
crates/doc/src/assets.rs | 1 | main's doc comment (same meaning)
crates/doc/src/build.rs | 3 | parent_page_for: next's parent_page_for_side (RTL-aware); single_sided_page_shows_first_parent_page test kept once, at main's position
crates/doc/src/item.rs | 1 | next's rotated_group_bounds_follow_the_children_outlines test kept
crates/doc/src/lib.rs | 1 | next's kerning_increment field kept; main's "Bulleted & Numbered" wording
crates/doc/src/page.rs | 1 | next's outer_page_indices + parent_page_for_side (integration of parent-margins with rtl-master-sides); main's parent_page_index dropped, its only caller (build.rs) uses parent_page_for_side
crates/doc/src/slice.rs | 5 | extract: next's `marked()` (get-based, fix_notes/fix_endnotes/fix_marks; main's version indexed slices and could panic); insert_story: main's take() limit on endnote/editorial payload copies with next's id comment, redundant `let ne`/`let nn` dropped; main's excess_note
crates/geom/src/corners.rs | 1 | next's box_outline_rounds_only_closed_corners test kept
crates/render/src/damage.rs | 1 | next's wrapping-anchored-object damage test kept
crates/render/src/fx.rs | 2 | feather: next's choke/corners sigma+join inside main's structure (body and clip at device resolution, with_filters(.., None)); inner glow centre: next's blend `mix` with main's clip argument (bp, xf)
crates/render/src/lib.rs | 3 | next's layer comment; next's front baseline grid draw after items; gradient match on g.kind (main's tuple scrutinee did not match the single-pattern arms)
crates/render/src/text.rs | 5 | paint_glyphs: main's paint_stroke closure structure with next's stroke overprint (overprinting helper, stroke `(TextPaint, bool)`); callers pass next's overprint_fill/overprint_stroke
crates/render/tests/placed_pdf.rs | 1 | main's `near` helper version
crates/tools/src/lib.rs | 1 | main's (PenConvert already declared below, avoids a duplicate variant)
crates/tools/src/pen.rs | 1 | main's module doc
crates/tools/src/select.rs | 1 | next's Drag::Corner variant (live corners) kept
crates/tools/src/tests.rs | 4 | next's tests (content drag, live corners, table border drag, eyedropper matchFrom, fitting handles, pen cursors once); eyedropper_ignores_inactive keeps next's samples_image check (main's exact-JSON compare lacks matchFrom) with main's `..Default::default()` Asset lit
crates/tools/src/text.rs | 2 | next's table border drag (BorderDrag, border_at) kept, then main's comment on locked text frames
crates/tools/src/xform.rs | 2 | main's explicit `Vec<&Item>` for shown children; next's eyedropper matchFrom (integration 796e9d713)
Cargo.toml | 2 | main's craft-pdf workspace dep added (craft-print stays once, in next's craft-libs block); [patch.crates-io] keeps next's winit (rust-windowing #4694 backport) and adds main's krilla patch; main's skylartaylor winit left out (see UNSURE 1)
Cargo.lock | 1 | union: next's craft-atomic and craft-cms entries plus main's craft-pdf entry; needs `cargo` normalisation
README.md | 1 | Open bullet combines INDD import via indd-utils (next) and editable PowerPoint export (main); main's paragraph break kept
contributors/people.toml | 1 | both people kept (switch87 from next, Nmarello from main)
apps/designcraft-cli/src/main.rs | 4 | next's `Export` enum dispatch kept; main's .pptx export added as `Export::Pptx` (run prints slides and warnings, script runs file.exportPptx); main's `--pdf-options` null-as-{} parse; usage lines list .pptx
apps/designcraft/src/main.rs | 3 | `startup.leave()` right after `app.ui` (main #380) and next's macOS `sync_movable` kept after the IME discard; next's Apple Events install kept; main's macOS Dock Quit `with_close_requested_on_terminate` block left out (needs the skylartaylor winit; UNSURE 1)
crates/fonts/src/fontdb.rs | 9 | FONT6 aliases (next) combined with #911 WWS names (main): ScannedFace and both CatalogEntry constructors carry `wws` and `aliases`; `canonical_family` falls back to WWS family names; `exact_style_traits` canonicalises then tries typographic, then WWS names (`named_st
crates/format/src/lib.rs | 1 | tests: both sides kept (next's r7a nullable-default tests; main's oversized ZIP entry/asset/entry-count tests)
crates/idml/src/import.rs | 11 | main's bounded `Package` reader under next's `import_idml_report_with_previews` (metadata read through `pkg.part`); next's `tab_list_repaired` kept; ruler origin: next's `settings.ruler_origin`, and main's guide import reads it (main's private `RulerOrigin` enum and
crates/idml/src/tests.rs | 6 | item-level union: all next tests plus main's new ones (ruler guides, package limits, CJK leading model, liquid page rules module, mojikumi); no test dropped
crates/mcp/src/backend.rs | 1 | test comment merged from both
crates/pdf/src/tests.rs | 1 | tests: both sides kept
crates/pdf/src/text.rs | 4 | next's (skew `tan`, cluster `start`, ruby overprint warning); main had no change here beyond base
crates/textimport/src/docx.rs | 5 | next's (ListCounter integration for list levels, page-break test position); main's side was the older form of the same code
crates/epub/src/lib.rs | 30 | non-test code is next's (StoryWriter holds img_src/images/no_alt/heading_ids; covers main's #787/#791/#782 fixes, plus #314 group transforms, anchored images in images_without_alt, endnote story skipped in the TOC); tests: next's set plus main's extra css_weight_style a
docs/control-protocol.md | 2 | next's rows (ui.paste, count 1–255, documentGrid) and wording
docs/file-format-parity.md | 1 | rows combined (next's ICC notes, main's TIFF indexed colour)
docs/gaps.md | 2 | status change notes unioned; Flex Layout removed from missing (main implemented it), next's Parent Options sentence kept
docs/localization-parity.md | 4 | Polish and Georgian rows; 5 languages beyond the twelve; file list includes cs and ka; both history rows
docs/roadmap.md | 1 | M1 next's (#186 fixed on next), M2 main's IME wording
docs/target-app-parity.md | 6 | next's status line; File formats row next's, UI/UX row main's (IME no longer failing); UI line next's plus main's Swatches detail; one Page tool line (main's fuller one); Load styles and main's fuller Pathfinder line both kept, main's duplicate short Pathfinder line r
docs/ui-parity.md | 1 | IME row main's, Font menu row next's

i18n/fr.rs: five rows dropped that main's shared table now has (Row, Open Path, Flex Layout, Current Page Number, Rulers).
2026-10-16 03:09:22 +00:00

16 KiB
Raw Blame History

Where DesignCraft falls short of InDesign

Last reviewed: 2026-10-10 · Last updated: 2026-10-13 · Change: minor (.indd and .indt open through indd-utils; gap 0 shrunk: text threads by hand; threading gaps added; Optical kerning from outlines (#181); gap 6: macOS lists fonts that font services and managers activate; shared print spooler; image clipping paths from IDML; Tabs panel listed as present (#343); book chapter update safety; gap 16: Based on Parent leftovers; bounded control click/drag input) · Target: Adobe InDesign 2026 (21.6)

Every known shortfall against InDesign 2026, one entry each, ranked by how much it stops an InDesign professional from doing real work. This is the work list: agents pick from the top. Numbers and weights are in target-app-parity.md; the plan is in roadmap.md. Estimates are Opus 5.5 agent-hours, calibrated in target-app-parity.md. When you close a gap, delete its entry (or shrink it), add a line to the ROADMAP progress log and update the timestamps.

Kind: F feature · U UI/UX · T typography · FF file format · H hardware · L localization · P performance · S stability · E ecosystem · A AI.

Alpha blocker (the core-workflow gate in roadmap.md)

0. Primary Text Frame autoflow adds pages users can't delete (F) · ALPHA BLOCKER

  • Missing: fixes to Smart Text Reflow on the Primary Text Frame, which users report adding pages they can't delete (#165). Threading by hand works (ports, loaded text cursor, text.thread / text.unthread / text.removeFromThread).
  • Evidence: #165.
  • Impact: a long story in a Primary Text Frame document can leave pages the designer can't remove.
  • Estimate: 5–7 h.
  • Doc: ui-parity.md

Blocking (beta can't be declared while these are open)

1. Basic editing fails for many users (U, S)

  • Missing: object copy/paste on Windows and Linux (#351, #348, #312, #185, #164, #201, text RTF paste #212); Paste in Place onto the selected page (#348); right-click context menus that don't open (#238, #187, #160, #312); double-click word selection in fields (#189); character formatting set at a caret is discarded (#289).
  • Evidence: 16 issues from 2026-10-05 to 2026-10-10, mostly against the 0.4/0.5 release builds.
  • Impact: a layout artist can't finish the simplest job. This dominates the ready-for-real-work number.
  • Estimate: 30–50 h (reproduce per platform through the control channel, regression tests).
  • Doc: ui-parity.md

2. INDD opening isn't measured on real files (FF)

  • Missing: a real-file corpus test of opening .indd and .indt. They open through storytold/indd-utils, which converts them to IDML in memory for the IDML importer, but DesignCraft's own tests use synthetic bytes only. INDB and INDL are still not read.
  • Evidence: #21, #114 (PR #98 proposed another converter). indd-utils reports 96.9% of InDesign's IDML values reproduced on ~650 INDD/IDML pairs and 0 failures on ~4,300 files; what DesignCraft draws from those files is unmeasured, and it inherits the IDML importer's open bugs (gap 3).
  • Impact: a client's .indd opens, but nobody knows how close it comes to the original.
  • Estimate: 10–30 h (corpus pinned in a sibling of storytold/photocraft-corpus, metric, fixes in indd-utils or the IDML importer).
  • Doc: file-format-parity.md

3. IDML round-trip isn't proven on real files (FF)

  • Missing: a corpus test of real InDesign-authored IDML (via storytold/photocraft-corpus or a sibling) measuring what survives import → export → reopen in InDesign. Open bugs: frames not rendered without a warning (#193), $ID/ font names reported missing (#338), no PDFAttribute on export (#339), Package writes build-machine absolute paths (#340), drag-drop open of IDML on the app icon (#211).
  • Evidence: importer coverage is broad (styles, tables, footnotes, xrefs, index, CJK, Arabic, verified in InDesign 2026 with synthetic files), but nothing is measured on real documents.
  • Impact: IDML is the main interchange format until INDD lands, and the only one that goes back to InDesign.
  • Estimate: 60–100 h (corpus, metric, fixes).
  • Doc: file-format-parity.md

4. Composition isn't compared with InDesign (T)

  • Missing: an oracle harness: the same synthetic stories set by InDesign 2026 (observed black-box, results kept under plan/) and by DesignCraft, comparing line breaks, overset and frame fit. Known differences: optical kerning is an outline-based approximation, not Adobe's algorithm (#181); a frame goes overset when descenders don't fit, InDesign needs only the baseline (#180); setting the text language was missing (#130; Language is now in Properties, #145, the issue is still open); "hyphenation doesn't work" (#87).
  • Impact: an opened IDML reflows: different line breaks, different page count, overset text. Professionals notice on the first page.
  • Estimate: 70–125 h (harness 20–30, optical kerning tuning 5–10, then fixes by cluster).
  • Doc: typography-parity.md

5. Startup crashes on some graphics hardware (S, H)

  • Missing: a start that survives every GPU/driver: Metal device lost on Intel Macs (#334), AMD OpenGL driver crash on Windows (#167), launch failures (#273, #220, #192, #166), blank or frozen canvas after graphics loss (#90).
  • Evidence: a backend fallback landed 2026-10-10 (#297: DirectX 12 on Windows, gpu.json skip list); then VectorCraft's adapter choice (the GPU that drives the display), restart on the next adapter or backend when one fails or hangs at start-up, the indirect-call check off (the first Metal error of #334) and a logged reason when the app stops (#273). Not yet confirmed by the reporters. Still open for #334: wgpu asks an old macOS's Metal compiler for a language version it doesn't have (-std=metal3.2).
  • Estimate: 15–30 h.
  • Doc: hardware-parity.md

6. Installed fonts not always found (F)

  • Missing: fonts in user font folders used for text (#161, #110, #107), fonts that font services and managers activate on Windows, reload when fonts change on disk (#328).
  • Evidence: on macOS the scan reads the font files CoreText has available, so fonts that Adobe Fonts and font managers activate are listed (#261, #327, 2026-10-11); not yet confirmed by the reporters.
  • Impact: documents set in the client's fonts render in Source Sans 3: wrong everywhere.
  • Estimate: 10–20 h (VectorCraft has a port, #261).
  • Doc: typography-parity.md

7. No CI runs the tests on pull requests (S)

  • Missing: a PR workflow running cargo xtask ci (fmt, clippy, tests, layers, wasm). Today only FreeBSD and Windows ARM build checks run, and only when manifests change; main has no branch protection. 65 PRs are open, some integrated in bulk (#259).
  • Impact: regressions land unseen; the 1,122 tests protect nothing they aren't run on.
  • Estimate: 4–8 h (plus runner minutes; owner decision on required checks).

High

8. Canvas IME not checked with real input methods (U, L)

  • Have: IME composition in the Type tool on macOS, Windows, Linux and the web (#322).
  • Missing: a check by hand with a system IME on each platform, and the fixes it finds.
  • Estimate: 10–20 h. Doc: localization-parity.md

9. PDF output presets and standards (FF)

  • Missing: PDF/X-1a and PDF/X-3 (no flattener to PDF 1.3/1.4), Adobe PDF Presets and .joboptions load/save, output-intent choice beyond the built-in profile, PDF/UA validation; #159, #32.
  • Have: PDF/X-4 with output intent and a validator (#200), PDF/A-2b, tagged PDF, CMYK and spot, marks and bleed, the options dialog with remembered settings (#196).
  • Estimate: 40–70 h. Doc: file-format-parity.md

10. Printing (H, F)

  • Missing: PostScript, a printer-driver options UI, separations to device, print presets, or trapping.
  • Have: file.print exports selected pages/spreads with marks and bleed, then submits through craft-print: CUPS on macOS/Linux and the Windows PDF raster spooler. Physical printer fidelity remains a hardware check.
  • Estimate: 25–45 h. Doc: hardware-parity.md

11. Paragraph and character style editing reliability (F)

  • Missing: saving edits and deleting a paragraph style reported failing (#169).
  • Have: the Tabs panel (Type › Tabs: a ruler over the text column, alignment, leader and Align On) and a Tabs section in Paragraph Style Options (#343).
  • Estimate: 10–20 h. Doc: ui-parity.md

12. Tables in depth (F)

  • Missing: anchored objects in cells not drawn (#163); Table ▸ Table Options and Cell Options submenus as InDesign lays them out, Diagonal Lines, Convert Rows to Header/Body/Footer, Edit Header/Footer, Go to Row; general reliability (#20).
  • Estimate: 25–40 h.

13. Hyphenation and spelling languages (T, L)

  • Missing: hyphenation patterns for every language but English, Spanish, Portuguese and Norwegian; spelling for every language but English. InDesign ships dictionaries for ~40 languages.
  • Estimate: 30–60 h (permissively licensed patterns exist for most; spelling word lists need licence review). Doc: typography-parity.md

14. Windows and Linux are thinly tested (S)

  • Missing: runtime testing on Windows and Linux: installer confusion (#64), pull-down panels can't scroll on Linux Mint (#267), tab bar overlaps menus in some workspaces (#182), CJK UI font missing on Linux (#332).
  • Estimate: 30–60 h (smoke tests in CI, fixes).

Medium

15. Long documents in depth (F)

  • Missing: book-wide TOC and index; Table of Contents Styles and deeper production workflows.
  • Present: basic style synchronization, continuous book numbering and merged PDF export. Chapter updates prepare the full batch and write only closed native chapters; IDML is a read-only source. Each file is atomic, but a later I/O failure can leave completed chapters; the error lists them. Cross-file transactional saving remains unavailable.
  • Estimate: 30–50 h.

16. Menu items still missing (U)

  • Missing: 151 of 482 in-scope items of InDesign 21.6's menu dump have no match (measured 2026-10-10; some exist under other labels): Type ▸ Notes and Track Changes submenus (the panels and commands exist), hyperlink and cross-reference update commands, Convert Bullets/Numbering to Text, Convert Variable to Text, Object ▸ Clear Effects / Clear All Transparency / Rotate 180° / Reverse Path, Layout ▸ Go Back/Forward, Window ▸ Arrange (2-up … 6-up), Trap Presets, Overlays, Edit ▸ Assign Profiles / Convert to Profile / Edit Original, File ▸ File Info / Open PDF / Document and Print Presets / User Settings, Type ▸ Size presets, Table ▸ Table Options / Cell Options submenus, Paste Before/After, Convert Rows/Columns, Object ▸ Interactive ▸ Convert to (form fields), View ▸ Extras badges and Story Editor options. Pages panel ▸ Parent Options (Based on Parent is the layout.parents.options command only); overriding a base parent's items on a parent spread itself (overrides work on document pages only).
  • Estimate: 40–70 h (most are thin wrappers over existing engine features).
  • Doc: ui-parity.md

17. HTML and fixed-layout EPUB (FF)

  • Missing: HTML export is one basic page (#314); fixed-layout EPUB writes page images, not live text and CSS; no animation or timing for EPUB/HTML.
  • Estimate: 30–50 h.

18. Colour management depth (F)

  • Missing: Assign Profiles / Convert to Profile, per-image rendering intents in output, hex entry and colour picker issues (#323, #190), keep kerning on colour change (#29).
  • Estimate: 20–35 h.

19. Placed graphics depth (FF)

  • Missing: EPS is shown through its preview only (no PostScript interpreter); PSD layer comps beyond visibility; the Clipping Path Options dialog (tracing into a clip that keeps the frame, Threshold/Tolerance/Inset Frame preview, picking an alpha channel or a path saved in a TIFF/PSD); Text Wrap › Same As Clipping following an imported clipping path; Edit Original / Edit With; PDF placed as editable vectors (#227, #24); QuarkXPress import (#73).
  • Estimate: 30–60 h (PostScript interpreter is a large separate project: +80–150 h).

20. Performance on large documents (P)

  • Missing: incremental composition (recompose from the edited paragraph; 8 ms keystroke budget), benchmarks against InDesign on long books and image-heavy catalogues.
  • Have: compose 300k characters ~38 ms warm, damage-region repaint (< 1 ms while typing), parallel story composition.
  • Estimate: 40–80 h.

26. Autoflow fills the following pages before it adds pages (F)

  • Missing: Shift-click autoflow (and autoflow on Place) always adds new pages after the story's last frame, one margin-sized frame each. InDesign first threads a frame per column on the existing pages that follow, then adds pages at the end of the document.
  • Impact: autoflowing into a document that already has pages inserts new pages in the middle of it instead of using the empty pages.
  • Estimate: 4–8 h.

27. Loaded text cursor can't thread into a frame inside a group (F, U)

  • Missing: a click with the loaded text cursor on a text frame inside a group hits the group, so the cursor shows it can't thread there.
  • Estimate: 2–4 h.

Lower

21. Localization breadth (L)

  • Missing: Hindi, Indonesian, Korean, Vietnamese interfaces; ~17% of strings in the 83–85% languages; 39% of pt-BR; native-speaker review for all. Estimate: 120–180 h. Doc: localization-parity.md

22. InDesign scripting compatibility (E)

  • Missing: an ExtendScript / UXP-compatible DOM so existing InDesign scripts run. Our own command API, scripts panel, CLI and MCP are strong and agent-friendly, but not compatible.
  • Estimate: 150–250 h for a useful DOM subset; owner decision.

23. Plug-ins (E)

  • Missing: any plug-in model. InDesign's third-party ecosystem (imposition, preflight, data publishing) doesn't carry over and can't. Owner decision; not estimated.

24. AI features (A)

  • Missing: InDesign 2026's Generative Expand, Text to Image and Auto Style equivalents; local generative vector requested (#232). Owner decision on openly licensed models.
  • Estimate: 60–120 h.

25. Accessibility of the app itself (U)

  • Missing: screen-reader exposure of panels and dialogs (egui AccessKit coverage unverified); PDF/UA validation of exports. Estimate: 15–25 h.

Out of scope (by design)

Adobe cloud services (CC Libraries, Stock, Adobe Fonts activation, Publish Online, Share for Review, Creative Cloud sign-in), InCopy assignment workflows, Bridge, Exchange extensions, Version Cue. These are excluded from every percentage.

Revision history

Date Change Summary
2026-10-13 minor Gap 16: Parent Options dialog and overrides of base items on a parent spread
2026-10-12 minor Gap 0 shrunk to the Primary Text Frame page fixes (#165): text threads by hand; gaps added for autoflow onto existing pages and threading into grouped frames
2026-10-10 minor Gap 0 added and marked alpha blocker: manual text threading is missing (stage re-normalized to pre-alpha)
2026-10-10 major Created: 25 ranked gaps from the full re-measure against InDesign 2026 21.6 and issues #1–#352