Commit Graph
1660 Commits
Author SHA1 Message Date
Dylan M. TaylorandClaude Sonnet 5.5 9770002c5c chore: method paths for remaining trivial closures (Sonar S1612)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 08:32:21 +00:00
Dylan M. TaylorandClaude Sonnet 5.5 8dc6717ff2 chore: replace glob imports in test modules with explicit names (Sonar S2208)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 08:32:10 +00:00
Dylan M. TaylorandClaude Sonnet 5.5 8299d26400 chore: replace trivial closures with method paths (Sonar S1612) (#1714)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:30:43 -04:00
dotCooCoo f5e1bda7cc Preflight: the missing-link test uses a path that is absolute on Windows too
a_missing_link_shown_by_its_preview_is_still_reported stored the link
/definitely/missing dir/photo.jpg in a document without a path. On
Windows that path names no drive, so document_path refuses it as not
absolute and the preflight message ends with "(the path is not
valid)", and the test failed. The test now stores a link under
std::env::temp_dir(), an absolute path with the default
temporary-folder settings on Windows, macOS and Linux, and expects the
message for that path. The preflight code is unchanged.
2026-10-24 01:21:55 -07:00
KnottyDyesandClaude Opus 5.5 a84faee829 PDF: a hidden layer missing from the placed file aborts vector export
Main now aborts an export when a stored hidden layer can no longer be
applied (#876). Vector export follows it: a layer hidden in Object Layer
Options that the placed PDF doesn't have, because the file has no layers
or was relinked, fails with an error naming the file instead of exporting
everything visible. The image-path tests for oversized images and
undecodable content export as PDF/A-2b, which still rasterizes placed
PDFs with hidden layers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 01:54:58 -06:00
KnottyDyes 38d692089f PDF: preserve placed optional-content visibility in vector exports
Keep source defaults and per-frame hidden layers in plain and PDF/X-4 vector exports, including independent repeated placements, booklet output and book merging. Accept usage-application arrays and resource-only groups without a catalog configuration.

Use file-named warnings and all-ON defaults for recoverable default-configuration problems and unsupported base states. Add readable groups omitted from OCGs without discarding their visibility, combine concurrent recovery warnings, and generate missing names only when no frame override needs name matching. Retain errors for contradictory states, unresolved references and ambiguous name overrides.

Cache prepared variants per asset and hidden-name set while replaying recovery warnings through the existing deduplicating channel. Keep original source bytes when every group is visible and named, so reader-repaired cross-reference tables remain usable without an incremental layer update. When hidden groups or generated names require writing, reject an unusable cross-reference table with a file-named damage error and retain the first placement failure.

Cover visibility, recovery, names, independent placements, repaired cross-reference tables and vector output with 46 optional-content integration tests, plus preparation-cache and shared-buffer unit tests.
2026-10-24 01:54:58 -06:00
Dylan M. TaylorandDylan Taylor f90d286721 chore: resolve SonarCloud maintainability issues (#1698)
* chore: resolve SonarCloud maintainability issues

- Replace lambda closures with method references (S1612)
- Replace wildcard imports with explicit imports (S2208)
- Refactor complex functions with extracted helpers (S3776)
- Replace OR pattern with range pattern in math parser (S9047)

* style: apply rustfmt to warichu helper

* fix(compose): revert slice conversion in tests and remove unused var in warichu

* Group warichu row layout scalars to satisfy S107 parameter limit

* style: satisfy rustfmt in warichu.rs

---------

Co-authored-by: Dylan Taylor <dylan@craftmaker.dev>
2026-10-24 03:54:24 -04:00
dotCooCoo a525894355 File Info: PDF export writes the document's title, author, description and keywords
File › File Info… opens a dialog with Document Title, Author,
Description, Keywords, Copyright Notice and Copyright Info URL, and the
document saves them. The new file.info command reads them with {} and
sets the fields it is given; "" or null clears a field, and keywords
are a list or one line split at semicolons and commas. file.info.get
returns the fields without editing the document, so opening the dialog
does not end a Data Merge preview.

Export PDF, PDF/X-4 and Print Booklet write the title, author,
description and keywords into the PDF's document information and XMP.
EPUB export takes the title and author from File Info, and HTML export
takes the title. A title or author given to the export replaces File
Info's, and an empty Document Title leaves the document's name as the
title. Export PDF's dialog no longer sends the document's name as the
PDF title, so the PDF takes its title from File Info; the file name
still comes from the document's name.
2026-10-24 00:20:21 -07:00
skylar taylor-barrick 00d5fa5cdd M6: reject unreadable PDF trailer history links (#1670)
Reject a non-null Prev entry that cannot be read as an offset instead of silently treating it as the end of the guarded trailer chain. Keep absent/null end markers and readable numeric offsets unchanged.

Reproduced CodeRabbit discussion_r4366245854 with an independent probe and a failing native regression before the fix. The synthetic regression covers seven unreadable value types plus absent/null and integer/real history controls.

Validation: all 9 cargo xtask ci gates passed (3063 tests passed, 6 skipped; 16 WASM-safe crates). One unrelated GPU test was labelled leaky by nextest in that run and passed cleanly in an isolated rerun. Independent checks: 17 original supported PDF variants still pass qpdf, logical preservation and Poppler pixels; 6 original refusal cases remain refused. All 11 additional Prev controls pass (7 refused, 4 accepted).
2026-10-24 00:40:33 -06:00
skylar taylor-barrick 7427a15863 M6: harden placed PDF layer variants (#1670)
Integrate current main (d8d78851) without rewriting the contributor's commits, retaining craft-libs 9f75d3dc.

Accept literal null trailer entries while rejecting actual or ambiguous encryption/hybrid markers. Structurally inspect bounded xref/trailer history instead of adopting trailer-looking comments. Preflight all selected source variants before editing/undo; preserve reset-to-defaults. Suppress stale unrewritable canvas overrides rather than revealing source content. Keep conservative all-content crop fallback without overcropping layerless/null stubs.

Validation: cargo xtask ci, all 9 gates passed; 3062 tests passed, 6 skipped; all 16 WASM-safe crates checked. 17 supported variants passed independent qpdf, logical preservation and Poppler pixel checks; 6 unsupported/repair-only cases refused. Direct-harness Claude Opus 5 reviewed the exact main-relative delta with no blocking findings.

No native-format changes or unrelated layer features. Synthetic regression fixtures are generated in test code.
2026-10-24 00:18:22 -06:00
NetterSilverandClaude Haiku 5.5 4867a3f41b Saturate table style altRows counts instead of truncating to 32 bits
Found while testing crates/engine/src/cmd/table.rs:1742

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 08:08:22 +02:00
aiongg c428083d74 Merge #1483: Bulleted and Numbered List buttons give InDesign's default hanging indent
# Conflicts:
#	crates/ui-egui/src/i18n/ar.rs
#	crates/ui-egui/src/i18n/cs.rs
#	crates/ui-egui/src/i18n/de.rs
#	crates/ui-egui/src/i18n/it.rs
#	crates/ui-egui/src/i18n/ja.rs
#	crates/ui-egui/src/i18n/ka.rs
#	crates/ui-egui/src/i18n/pl.rs
#	crates/ui-egui/src/i18n/pt_br.rs
#	crates/ui-egui/src/i18n/ru.rs
#	crates/ui-egui/src/i18n/uk.rs
#	docs/target-app-parity.md
2026-10-24 06:00:59 +00:00
aiongg 87be33e969 Hyphenation: new documents start with Capitalized Words, Last Word and Across Column off 2026-10-24 05:56:36 +00:00
aiongg d8d7885172 Anchored objects: Relative to Spine mirrors custom positions on right-hand pages (#1702)
* Anchored objects: Relative to Spine mirrors custom positions on right-hand pages

* Anchored objects: page side from the frame's spread position; footnote cache keyed by page side
2026-10-24 01:34:05 -04:00
aiongg 3b71900097 Links: resolve stored paths with craft-docpath's resolve_absolute (#1399)
* Links: use resolve_absolute for stored paths

* Links: check for a missing linked file with is_ok_and

* CI: release only with git dependencies from storytold

The winit patch from skylartaylor/winit at its pinned rev is the one other source allowed.

* Links: Relink to Folder only uses a name that stays a file name in the folder

* CI: the git-sources check reads Cargo.lock as TOML, needs it current and refuses config patches

* CI: the git-sources check parses .cargo/config and .cargo/config.toml for source replacement, patches and paths

* Links: rustfmt

* Links: Relink to Folder only takes a file directly in the chosen folder

* Links: Relink to Folder compares folders as the file system resolves them
2026-10-23 21:19:50 -04:00
moppeeer 5217392d50 Merge remote-tracking branch 'origin/main' into table-cell-keys 2026-10-24 00:24:55 +02:00
moppeeer 74ed763507 Merge remote-tracking branch 'origin/main' into codex/toc-right-indent-separator
# Conflicts:
#	crates/idml/src/tests.rs
2026-10-24 00:21:11 +02:00
moppeeer 245fb99a8d Merge remote-tracking branch 'origin/main' into direct-select-delete-image
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-23 23:42:19 +02:00
Brandon Thomas aaa18ad1c2 Merge pull request #1550 from Silvertree2010/fix/h1233-text-frame-column-count-is-trunc
Clamp text frame column count before narrowing to u32
2026-10-23 17:29:35 -04:00
Brandon Thomas 8eb4f5590a Merge storytold/main into feat/cell-rotation-reported
# Conflicts:
#	crates/idml/src/tests.rs
2026-10-23 17:29:22 -04:00
Brandon Thomas 17d197dbef Merge pull request #1567 from Hamza0101/fix/insert-pages-count
A page count Insert Pages cannot mean is refused
2026-10-23 17:29:02 -04:00
Brandon Thomas 3e783b2671 Merge pull request #1562 from Hamza0101/fix/duplicate-page-in-export-list
A page named twice in an export list is exported once
2026-10-23 17:28:54 -04:00
Brandon Thomas 515796aa1c Merge pull request #1571 from Hamza0101/fix/unique-anchor-name
A text anchor's name is the document's, so it is not reused
2026-10-23 17:28:50 -04:00
Brandon Thomas 132a0816e1 Merge pull request #1376 from Silvertree2010/fix/h869-table-alternating-fill-counts-ar
Saturate table alternating-fill and index paragraph counts
2026-10-23 17:28:43 -04:00
Brandon Thomas dd9ab4b6d9 Merge pull request #1369 from Silvertree2010/fix/h850-polygon-side-count-is-truncated
Clamp polygon side count before narrowing to u32
2026-10-23 17:28:24 -04:00
Brandon Thomas abda81d473 Merge pull request #1661 from marcoarnulfo/fix/align-key-object
Align: a click on one of several selected objects makes it the key object
2026-10-23 17:28:06 -04:00
Brandon Thomas f0907d3831 Merge pull request #1665 from MarekSpodBiedry/issue-1624
find: search and change text inside table cells in document scope (#1624)
2026-10-23 17:27:58 -04:00
Brandon Thomas 597fc5c900 Merge pull request #1574 from Hamza0101/fix/character-size-bounds
A type size outside 0.1 to 1296 pt is refused
2026-10-23 17:27:18 -04:00
Brandon Thomas dc968ecdff Merge pull request #1629 from marcoarnulfo/feat/autoflow-existing-pages
Autoflow: fill the pages that follow before adding pages at the end
2026-10-23 17:26:42 -04:00
Brandon ThomasandClaude Opus 5.5 1e86a669ca table: the rotation comment names only the IDML import warning
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 17:18:56 -04:00
Brandon ThomasandClaude Opus 5.5 253be57a85 layout.pages.insert: range-check the count before narrowing to usize
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 17:18:46 -04:00
Brandon ThomasandClaude Opus 5.5 50161d0d42 Index: next-paragraph ranges saturate and read the paragraph list with get
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 17:15:22 -04:00
Brandon ThomasandClaude Opus 5.5 2aa2ef4b7c find: move the table id into the cell iterator (E0373)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 17:02:49 -04:00
moppeeer 812310ff6a Merge branch 'direct-select-anchor-points' into properties-anchor-points
# Conflicts:
#	crates/engine/src/cmd/object.rs
2026-10-23 22:28:43 +02:00
moppeeer 6a775f5986 Merge branch 'direct-select-anchor-points' into direct-select-handles 2026-10-23 22:26:50 +02:00
moppeeerandClaude Opus 5.5 3d652b3e3e Move Anchors: a points value that is not a list is an error
path.moveAnchors treated a non-list points as absent and fell back to the
id/anchors form, so a request with a malformed points and an id moved that
path. Found by CodeRabbit on #1657.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 22:26:47 +02:00
moppeeer 66b4d1cc34 Merge remote-tracking branch 'origin/main' into direct-select-anchor-points 2026-10-23 22:22:46 +02:00
moppeeer 7762cdafb6 Merge remote-tracking branch 'origin/main' into global-units-preferences
# Conflicts:
#	ROADMAP.md
2026-10-23 22:21:41 +02:00
moppeeer 2fc7800677 Merge remote-tracking branch 'origin/main' into direct-select-handles
# Conflicts:
#	ROADMAP.md
2026-10-23 22:16:31 +02:00
moppeeerandClaude Opus 5.5 eaef6e94f5 Format the conversion test
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 22:11:30 +02:00
moppeeer bc7e4bb0c6 Merge branch 'table-menu-insert' into table-convert-dialogs
# Conflicts:
#	ROADMAP.md
#	crates/ui-egui/src/dialogs.rs
2026-10-23 22:05:28 +02:00
moppeeer e963fa3f4d Merge remote-tracking branch 'origin/main' into table-convert-dialogs
# Conflicts:
#	ROADMAP.md
2026-10-23 22:05:07 +02:00
moppeeerandClaude Opus 5.5 dd2d7e6949 Insert Table: the style in the same step, and the engine's limits in the dialog
- table.insert takes tableStyle and applies it in its own edit, so one Insert
  Table is one undo, and a style that is gone (or not a name) changes nothing.
  The dialog passes it instead of running style.table.apply afterwards.
- The dialog's fields stop at table.insert's limits (500 body rows, 200
  columns, 100 header or footer rows; now public constants), so the table made
  is the one shown.

Found by CodeRabbit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 22:04:42 +02:00
moppeeer bbe29dfecc Merge remote-tracking branch 'origin/main' into table-menu-insert
# Conflicts:
#	ROADMAP.md
2026-10-23 21:59:50 +02:00
moppeeerandClaude Opus 5.5 f5a67336ad Esc on a cell selection starting in a merged cell selects that cell's text
selection.cells may start at a covered grid position; the toggle now goes to
the merged cell (its owner at the top left), whose story holds the text.
Found by CodeRabbit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 21:59:37 +02:00
moppeeer 7a0c350114 Merge remote-tracking branch 'origin/main' into table-cell-keys
# Conflicts:
#	ROADMAP.md
2026-10-23 21:57:04 +02:00
aiongg 2c32ee389b Engine: Export PDF and Print take a creation date, so the print test's two exports match (#1680) 2026-10-23 15:38:43 -04:00
moppeeerandClaude Opus 5.5 cbb2a974d1 Tables: InDesign's Convert Text to Table and Convert Table to Text dialogs
Table › Convert Text to Table… and Convert Table to Text… open dialogs laid
out as InDesign's instead of converting at once with tabs and paragraphs:
- Column and Row Separator: Tab, Comma, Paragraph from the field's menu, or
  any characters typed.
- Number of Columns (Convert Text to Table), available when both separators
  are the same: the cells fill rows of that many.
- Table Style (Convert Text to Table), applied to the new table in the same
  undo step.

table.convertFromText takes rowSeparator, columns and tableStyle, and any
characters as separators; table.convertToText takes both separators
(Table::text_with). Convert Text to Table is available only with text
selected outside a table, as in InDesign. New strings are translated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 21:21:32 +02:00
moppeeerandClaude Opus 5.5 10cd0cac3c Table menu in InDesign's order; Insert Table dialog laid out as InDesign's
- Table menu: Insert Table… (Cmd+Alt+Shift+T), Convert Text to Table,
  Convert Table to Text | Cell Options | Insert, Delete, Select | Merge,
  Unmerge, Split Horizontally/Vertically, Convert Cell Type, Convert Rows |
  Distribute Rows Evenly, Distribute Columns Evenly. The Table panel item left
  the menu (it is in Window › Type & Tables, Shift+F9).
- Cmd+Alt+Shift+T opens the Insert Table dialog, as InDesign's; it ran
  table.insert with its defaults, so the shortcut and the menu did different
  things.
- The Insert Table dialog: InDesign's title, a narrow window, Body Rows and
  Columns then Header and Footer Rows as numbers with spinners and
  right-aligned labels, and a Table Style applied to the new table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 20:57:03 +02:00
moppeeerandClaude Opus 5.5 3886ad2fd1 Tables: Shift+Tab goes back a cell and Esc toggles text and cell selection
As in InDesign (Learn Skills Daily / Adobe "How to make a table" lesson):
- With the Type tool in a table cell, Shift+Tab goes to the previous cell.
  It went on to the next one: the tool sent a plain Tab whatever the
  modifiers.
- Esc in a cell toggles between the text and the cell: the insertion point
  or text in a cell selects that cell, and selected cells select the text of
  the first one. Esc left the table and selected the frame.

New engine command table.toggleSelection does the toggle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 20:33:44 +02:00