Commit Graph
3018 Commits
Author SHA1 Message Date
dotCooCoo 2c7bbaa79e File Info: OK keeps the fields the dialog does not hold, and the active document's Data Merge preview 2026-10-24 18:40:43 -07:00
dotCooCoo 0f037cb67e Merge main into feat/file-info 2026-10-24 18:14:03 -07:00
skylar taylor-barrick 0f1ff65e7a Merge pull request #1647 from andeecollard/codex/placed-graphic-layer-overrides
M6: preserve placed-graphic layer settings across IDML and native saves
2026-10-24 18:55:32 -06:00
aiongg befc2e0346 Styles: renaming a style keeps its Export Tagging (#1790)
* Styles: renaming a style keeps its Export Tagging

Renaming a paragraph or character style, or moving it into a style
group, moves its Export Tagging to the new name. Deleting a style drops
its tagging and leaves the replacement's own tagging unchanged.

* Styles: a paragraph style can't be renamed onto another style's name

* Styles: a refused rename says the name is taken and shows the General section

Renaming a paragraph or character style onto a name another style has
now says so ("a paragraph style named `Body` already exists"); empty
or bracketed names keep the generic message. The Paragraph Style Options
dialog switches to General, where the name field is, when the rename is
refused. Paragraph style names are trimmed like character style names,
and a renamed style never picks up an export tag left under its new name.

* Styles: the rename test's stale tagging takes the Split Document field

* ROADMAP: date the style rename line 2026-10-24
2026-10-24 20:37:21 -04:00
aiongg a59880394d Search: Delete Workspace is left out of Quick Apply and command search (#1791)
* Search: Delete Workspace is left out of Quick Apply and command search

It needs a saved workspace's name, which a search entry can't supply,
so choosing it there failed. The application bar's workspace menu lists
the saved workspaces to delete.

* Search: leave out the interface commands that fail or reset a setting there

Quick Apply and the application bar's search ran their entries without
parameters. Commands that need a workspace, a command and shortcut, a
menu item, a panel, a window edge, an app page, a recent file, or a
swatch or color group failed when chosen there. Interface Color Theme
and UI Scaling switched to the dark theme and 100%, Workspace switched
to Essentials, and Reset Shortcuts cleared every custom shortcut without
asking. Search leaves all of them out; each stays in the menu, panel or
dialog that gives it the value.

* Search: the flattener preset, Screen Mode, Zoom To and the Task Bar pin stay out of Quick Apply
2026-10-24 20:23:48 -04:00
skylar taylor-barrick a32ad396f3 PDF: give the test-only Graphic literals the layer_options field
Graphic gained an optional layer_options field, so the test-only literals in the PDF
crate and in the engine's optional-content support need it. No behaviour changes.
2026-10-24 17:39:46 -06:00
aiongg b595f1b7d3 EPUB: Split Document (export option and per-style Export Tagging) (#1787)
* EPUB: Split Document in a paragraph style's Export Tagging

* EPUB: Split Document as a document setting (off, one style, or export tags)

The document stores EPUB Export Options › Split Document (DocSettings.epub_split):
off (one content file, the default), a single paragraph style, or the
paragraph styles' Export Tagging › Split Document flags. document.epubSplit sets
it as one undo step; file.exportEpub takes a split that overrides it for one
export. A Style setting follows a renamed style and a deleted style's
replacement. IDML reads and writes EPubExportPreference BreakDocument and
ParagraphStyleName. A split before a list item or preformatted line closes the
open list or block first, so each content file is balanced.

* EPUB Export Options dialog with Split Document before Export EPUB

File › Export EPUB… opens EPUB Export Options, seeded from the document's
Split Document setting: a Split Document checkbox with Single Paragraph Style
(and its style) or Based on Paragraph Style Export Tags. OK stores a changed
setting through document.epubSplit, then continues to the save dialog; Cancel
does nothing. app.exportEpub with a path skips the dialog. Docs and the
progress log describe the setting.

* EPUB: the navigation test exports one content file with Split Document off

* EPUB export from the menu passes its options (cover, split) to the engine

* EPUB: Split Document on a style's EPUB tag map counts when the style says false; a caller's cover: false stays
2026-10-24 17:56:49 -04:00
skylar taylor-barrick 9fc02f8f7b Merge contributor branch codex/placed-graphic-layer-overrides (PR #1647) into main
Conflict resolutions:
- crates/pdf/src/export.rs: keep main's `graphic(.., hidden)` signature from
  #1241 and report retained graphic-layer overrides that drawing cannot apply.
- docs/gaps.md: keep main's change list and add the graphic-layer entry.
2026-10-24 15:30:03 -06:00
skylar taylor-barrick 21a3f8bbb1 PDF: preserve placed optional-content visibility in vector exports (#1241)
Preserve contributor commits and integrate current main. Plain/PDF-X4 exports retain placed PDF optional-content defaults and hidden-name choices; prepared variants are cached, trailer history is parsed structurally, null OCProperties is treated as absent, and unreadable non-null Prev refuses safely. Preserve the recent form/table exporter refactors.

Verified exact integration tree with all nine cargo xtask ci gates (3,209 tests passed, 6 skipped; 16 WASM-safe crates), 118 original-head PDF tests, independent flat/null and Prev export matrices, and 12 qpdf checks. GitHub CI passed; fresh CodeRabbit review covers the exact head with no new actionable comments. Sonar workflow succeeded but its scan was skipped because the fork lacks SONAR_TOKEN.

This landing does not include or release the format-v4 pair #1647/#1671, held separately pending parent-placement IDML layer-choice preservation.
2026-10-24 14:59:07 -06:00
skylar taylor-barrick 0e0ed78125 M6: integrate placed-PDF vector layer export with current main (#1241)
Preserve contributor commits and adapt optional-content registration and table-cell graphic calls to the current PDF exporter refactors. Keep current-main roadmap corrections.

All nine cargo xtask ci gates passed on tree d0c21f347e: 3209 tests passed, 6 skipped, 16 WASM-safe crates. The exact PR head also passed 118 PDF unit/integration tests. Independent production-export controls: 8 flat/null cases succeeded; 7 unreadable Prev values refused, 4 compatibility controls succeeded; all 12 emitted PDFs pass qpdf.

This PR is independent of the format-v4 pair (#1647/#1671), which remains held for a reproduced parent-placement IDML issue.
2026-10-24 14:38:11 -06:00
aiongg a16f29a669 Optical margin alignment: lines with a tab hang their edge glyphs, as both line breakers measure them (#1760)
layout_line set a line with a tab or a right indent tab without the optical
margin or CJK edge hangs, while the greedy breaker and the paragraph composer
counted them. A line that fit only because its period hangs was then squeezed
into the measure or set past it.

layout_line now hangs the edge glyphs of every line. Tabs are measured from the
hung start, so tab stops stay where they are, and a right indent tab fills to
the hung end. A tab at a line edge hangs nothing. Lines without tabs lay out as
before.
2026-10-24 14:45:04 -04:00
dotCooCoo 6bc5ac36fb Merge main into feat/file-info 2026-10-24 11:30:55 -07:00
dotCooCoo bfc36622e0 File Info: keywords with a comma keep their place, and the dialog stores into its own document
Editing one keyword in File Info re-split the whole field, so a stored
keyword holding a comma or semicolon became two. A stored keyword that is
still in the field whole now stays one keyword.

An Export PDF title equal to the document's name was dropped, so the PDF
took File Info's title. The dialog's title now starts empty, and a title
given there is always the PDF's title; without one the file is named
after the document.

file.info refuses parameters that are not an object; null reads the
fields like {}.

File Info's OK stores the fields in the document the dialog was opened
for, even when another document became active meanwhile, and stores
nothing once that document has closed.
2026-10-24 11:25:22 -07:00
Brandon Thomas 45ed6cfce0 Merge pull request #1678 from marcoarnulfo/feat/multi-automation-roots
MCP: --automation-read-root and --automation-write-root may each be given more than once (#1552)
2026-10-24 10:24:24 -04:00
Brandon Thomas 610792ed34 Merge storytold/main into feat/multi-automation-roots 2026-10-24 10:24:14 -04:00
Brandon Thomas ee8a3397a3 Merge pull request #1639 from marcoarnulfo/feat/convert-variable-to-text
Type › Text Variables › Convert Variable to Text: the selected instances, or every instance of one variable, become the text they show on their page
2026-10-24 10:24:10 -04:00
Brandon Thomas 4b9b0a96f1 Merge storytold/main into feat/convert-variable-to-text
# Conflicts:
#	docs/gaps.md
2026-10-24 10:24:00 -04:00
Brandon Thomas 057d76be3c Merge pull request #1638 from marcoarnulfo/feat/layout-go-back-forward
Layout: Go Back and Go Forward through the pages viewed, with InDesign's shortcuts
2026-10-24 10:23:55 -04:00
Brandon Thomas 3ea6459651 Merge storytold/main into feat/layout-go-back-forward 2026-10-24 10:23:44 -04:00
Brandon Thomas 3f637ae093 Merge pull request #1762 from dotCooCoo/feat/previous-next-note
Type › Notes › Previous Note and Next Note: the insertion point moves from note to note, as in InDesign
2026-10-24 10:23:40 -04:00
Brandon Thomas 0f3ce4dca6 Merge storytold/main into feat/previous-next-note 2026-10-24 10:23:30 -04:00
Brandon Thomas 2b93db2cff Merge pull request #1756 from dotCooCoo/feat/convert-to-note
Type › Notes › Convert to Note: the selected text becomes a note, as in InDesign
2026-10-24 10:23:26 -04:00
Brandon Thomas 073287500f Merge storytold/main into feat/convert-to-note 2026-10-24 10:23:16 -04:00
Brandon Thomas 12c6c721e7 Merge pull request #1753 from Hamza0101/fix/grep-scan-bounds
GREP styles: a scan and the pattern cache are bounded (#1598)
2026-10-24 10:23:12 -04:00
Brandon Thomas c0e2c608cd Merge pull request #1751 from Hamza0101/fix/linked-file-read-cap
links: a linked file is read under a cap, not whole (#1596)
2026-10-24 10:23:09 -04:00
Brandon Thomas a57d4cea1b Merge pull request #1752 from Hamza0101/fix/import-value-ranges
import: a value a file gives is one the engine can mean (#1593)
2026-10-24 10:23:05 -04:00
Brandon Thomas 6649125539 Merge pull request #1744 from PiMinusMax/effects-dialog-global-light-angle
Effects dialog: the Angle with Use Global Light stays editable and sets the global light
2026-10-24 10:23:02 -04:00
Brandon Thomas a67cf73d83 Merge storytold/main into effects-dialog-global-light-angle 2026-10-24 10:22:52 -04:00
Brandon Thomas 520a810640 Merge pull request #1742 from dotCooCoo/fix/package-redirect-test-junction
Package: the Windows redirect test falls back to a directory junction
2026-10-24 10:22:47 -04:00
Brandon Thomas 8d6989c508 Merge pull request #1740 from Silvertree2010/fix/h1918-footnote-numbering-overflows-u32
Saturate footnote and endnote numbering at u32::MAX
2026-10-24 10:22:43 -04:00
Brandon Thomas 178efcccd9 Merge pull request #1732 from dotCooCoo/fix/rooted-link-tests-on-windows
Preflight: the missing-link test uses a path that is absolute on Windows too
2026-10-24 10:22:38 -04:00
Brandon Thomas 5dddce5eb6 Merge pull request #1707 from Silvertree2010/fix/h1903-table-style-altrows-counts-are-t
Saturate table style altRows counts instead of truncating to 32 bits
2026-10-24 10:22:35 -04:00
Brandon Thomas 280436dbdc Merge pull request #1700 from Silvertree2010/fix/h1882-html-epub-style-css-drops-the-un
Join underline and strikethrough into one text-decoration in EPUB CSS
2026-10-24 10:22:31 -04:00
Brandon Thomas 6cf71e33e3 Merge pull request #1699 from Silvertree2010/fix/h1863-from-bezpath-loses-smooth-anchor
Detect smooth anchors on all open subpaths in from_bezpath
2026-10-24 10:22:28 -04:00
aiongg 5def4a8c01 Story Optical Margin Alignment with a size, and Ignore Optical Margin (Story panel, engine and IDML) (#1705)
* Type: story Optical Margin Alignment with a size, and Ignore Optical Margin (engine, IDML)

A story's Optical Margin Alignment applies to every paragraph except those
with Ignore Optical Margin; hang amounts scale with the story's size.
story.options sets it, type.para and paragraph styles take
ignoreOpticalMargin. IDML imports and exports StoryPreference
OpticalMarginAlignment/OpticalMarginSize and IgnoreEdgeAlignment. The
per-paragraph opticalMargin switch keeps hanging at the text's own size.

Part of #947.

* Type: the Story panel, and Ignore Optical Margin in the Paragraph panel menu and Paragraph Style Options

Window > Type & Tables > Story sets Optical Margin Alignment and its size
for the stories of the text selection or the selected text frames through
story.options, and is disabled without either. type.selectionAttrs
reports the stories' values as storyOptions, null where they differ.
The Paragraph panel menu toggles ignoreOpticalMargin, and Paragraph Style
Options > Indents and Spacing has an Ignore Optical Margin checkbox.

Part of #947.

* ROADMAP: the story Optical Margin Alignment entry names its default and scope
2026-10-24 10:08:40 -04:00
Brandon ThomasandClaude Opus 5.5 b8070d814c links: the capped-read test is native-only, like reload_capped
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:05:55 -04:00
Brandon ThomasandClaude Opus 5.5 637c32506a GREP styles: empty matches don't count toward the per-paragraph cap
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:05:52 -04:00
Brandon Thomas b724698d98 Merge remote-tracking branch 'origin/main' into pr1678
# Conflicts:
#	apps/designcraft-cli/src/main.rs
2026-10-24 10:03:25 -04:00
Brandon Thomas b33224d692 Merge remote-tracking branch 'origin/main' into pr1639
# Conflicts:
#	docs/gaps.md
#	docs/target-app-parity.md
2026-10-24 10:02:54 -04:00
Brandon ThomasandClaude Opus 5.5 5fca302ff6 Endnotes: saturate the remaining numbering sites at u32::MAX
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:01:04 -04:00
aiongg d767fcf41e Text frames: a custom baseline grid's Relative To (page, margin, frame or inset) (#1758) 2026-10-24 09:55:47 -04:00
aiongg 7848c21220 Paragraph Style Options: Align to Grid (None, All Lines, First Line Only) in Indents and Spacing (#1759) 2026-10-24 09:38:37 -04:00
dotCooCoo 42d2857fcc Type › Notes › Previous Note and Next Note: the insertion point moves from note to note, as in InDesign
The new commands note.previous and note.next move the insertion point
to the previous or next editorial note in its story and put the caret
after the note's anchor. Previous Note skips the note whose anchor the
caret directly follows, so repeated use reaches every note. Each item
is unavailable when no note lies in its direction in the story, or when
the insertion point is in a table cell or a footnote. The items follow
the Notes panel item in Type › Notes, with translations in the catalogs
that already translate Next Document and Previous Document.
2026-10-24 06:17:31 -07:00
aiongg 4be45a713a Anchored text frames compose against the grid and page where they are placed (#1710)
* Anchored text frames compose against the grid and page where they are placed

An anchored text frame is not a spread item, so frame_specs composed it at
its stored transform: no page, no page side, no page rect, and a baseline
grid phase taken from that transform. A note set to Only Align First Line
to Grid snapped to the wrong line, and page-number markers and
spine-relative alignment inside it saw no page.

The composer now looks up the host story's composition first, finds where
it placed the frame (in its frames' anchored objects, footnotes or table
cells) and composes the frame's story against that placement
(ComposeOptions::placed). The cache does the same and adds the placement
to the entry's signature, so a note recomposes when its host moves it.
Host lookups stop after eight levels, which bounds stories anchored in
each other.

* Anchored text frames: the cache keys on the placed spread's pages
2026-10-24 08:30:03 -04:00
Andee CollardandClaude Opus 5.5 2633fe8b5d Format: choose the native version in one place; share v4 with #1671
skylartaylor's review: #1647 and #1671 each introduced native format 4 for a
different capability, so a reader that understood only one could accept a
file carrying the other and silently drop its settings. No release has shipped
v4 (main and v0.12.0 still write at most 3), so v4 is defined as one
capability covering both retained placed-graphic layer options and explicit
all-on PDF layer choices; #1671 is stacked on this branch.

Move the version choice into required_version so every new capability is
decided in one place, document the shared v4 contract on VERSION, and test
that plain, EPS-only and layer-option documents keep 2, 3 and 4 respectively.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 13:22:08 +01:00
andeecollard b7e36bf616 M6: retain layer order when native parents reopen closed subtrees 2026-10-24 13:22:08 +01:00
andeecollard 3d362d0bdf M6: preserve nested graphic layers and retain export diagnostics 2026-10-24 13:22:08 +01:00
andeecollard 7074dc8a85 M6: preserve per-placement graphic layer options 2026-10-24 13:22:08 +01:00
aiongg d4c1322d97 Merge pull request #1709 from aiongg/w65-batch
Integration batch: book-chapter IDML baseline grids, hyphenation, and the Paragraph panel stack
2026-10-24 08:14:29 -04:00
Hamza d5a6a7ddd5 GREP styles: a scan and the pattern cache are bounded (#1598)
Two unbounded things in the GREP-style path.

`BACKTRACK_LIMIT` bounds one search, not a scan: `find_all` was called with
`usize::MAX` and pays the limit again for every match, so a pattern tuned just
under it cost `200_000 x matches` per paragraph on every relayout. A scan now
stops at `MAX_MATCHES_PER_PARAGRAPH` (4096) -- more styled runs than a
paragraph can usefully carry -- and says which pattern reached it.

The `PATTERNS` thread-local never evicted, so it grew across every pattern a
session ever composed. It now holds at most 64, least recently used dropped
first: a tick counter marks each use, so the entry evicted is the one longest
unused rather than the one inserted earliest. The test checks that the pattern
just used is still there after the cache overflows, which insertion-order
eviction would not give.

Left for a separate change: DC-17 also asks for a per-compose step budget, so
the cost cannot add up across paragraphs. That means threading a budget from
`compose_story` through `shape` into `overlays`, a compose-internal signature
change that wants its own review rather than riding along here.
2026-10-24 16:26:39 +05:00