Repository navigation
Extend Design typography and structured text interchange - #195
Merged
Merged
Conversation
Page items inside IDML stories are typed from their retained XML (AnchoredObjectSetting position and Y offset plus the item itself) and inline ones in horizontal text are composed as engine inline boxes: an object replacement character with its own width and line metrics that draws nothing and wraps whole. Items sit on the baseline raised by their Y offset and are drawn through the frame's affine in output and on the canvas. Extents, Auto leading and bounding-box wrap offsets follow InDesign's PDF of the public paged-media anchored sample. Boxes scale with their specs in the preview and at every output resolution. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Every AnchoredObjectSetting attribute is typed with its IDML default. Items above the line are zero-width engine boxes whose new room-above lowers their line; custom items are zero-width boxes placed by anchor point against the anchor, its line's metrics, the column, frame, page margins or page, with offsets, spine mirroring and pinning. Composed items whose wrap is not applied raise the existing Preflight warning. The rules follow InDesign's PDF of the public paged-media anchored sample, which a new layout test reproduces. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Anchored TextFrames are typed with the story their ParentStory names and compose it in their own box as a one-frame thread, nested anchors included. Output paints them, Preflight reports their overset text, and the canvas draws their lines as generated text of the holding frame. Frames whose story leads back to their host are reported and never set. Anchored Groups are flattened into members that move together, with an extent spanning them and the group's name and wrap on a container. Placed copies take a reserved object id no document object has. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
An anchored item at a custom position with a text wrap now wraps the lines of its own story after its anchor's line, as Adobe's public help describes, never that line or the lines before it. Wrap obstacles gained a first band, and a projected story composes again with its items where the previous pass put them until they settle. Preflight warns on other stories' frames that an item's wrap reaches, since only the item's own story is wrapped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Next and previous page numbers render where the marker's frame is known: in a one-frame pass they show the page of the next or previous frame in the thread of the story their frame touches, or their own page, following public jump-line guidance. The Text Variables window inserts both kinds. Object styles' Text Wrap & Other category is read, written and applied: items without their own wrap take their style's, and editing a styled item's wrap stores only what differs. Each Layers panel row gains a compact IgnoreWrap toggle. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
MatchParagraphStyleType and MatchCharacterStyleType definitions are typed and saved with InDesign's spellings. An instance shows the first or last matching paragraph or run on its page, carries the previous page's value forward, and applies change case and end punctuation as InDesign's PDF of the public paged-media variables sample shows; a layout test reproduces all eight of its headers on all five pages. Next and previous page numbers inside a multi-frame thread now follow their own thread from the frame they land in, recomposing until stable. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Creation, modification and output date variables and file-name variables are typed and saved with InDesign's spellings, so every public template's default definitions now type. Documents carry their dates and file path: creation and modification dates travel in the package's XMP, and the editor stamps them at open, save and output. A new dates module parses XMP dates and formats InDesign's date codes; the public variables sample's formats print as in InDesign's PDF. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Tables inside stories are typed from their retained XML: row sizing, column widths, and cells with spans, fills, edge strokes, insets and vertical justification, each cell's text a document story. A table is set in its line as one block: growing rows take their tallest cell's last baseline plus insets, fills and edges draw as InDesign's PDFs of the public paged-media tables samples show, and cell text composes and draws with the holding frame in output and on the canvas. Tables breaking across frames, repeated header rows and table and cell styles remain for the next phases. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A table that does not fit the room left now breaks between whole rows into parts, each set on a line of its own and continued at the top of the next column of the thread. Header and footer rows repeat in every column, once per frame or once per page, and the first header and last footer can be skipped; rows kept with the next stay together unless nothing else would fill a column, a break never splits a cell spanning rows, and a row no column holds leaves the rest of the table overset. These reproduce InDesign's PDFs of the public paged-media tables-rows and tables-overset samples. Where parts fall depends on where they land, so a story holding tables composes again until its parts settle. A table never shares a line with text, never overlaps the text above under fixed leading, and overhangs a column narrower than itself. Keep options no longer hold a table's parts. StartRow and undefined repeat values are reported; one key is added to all 150 catalogs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Tables now resolve their settings through their table style and cell styles, with BasedOn chains: a cell's own attributes, then its applied cell style, then the cell style its table region gives it, then their bases. Insets, vertical justification, fills and edge strokes come through that cascade. Fills alternate by row or column as the table or its style asks, row patterns skipping header and footer rows, and ColumnFillsPriority picks which axis shows, as InDesign's PDF of the public paged-media tables sample draws them. Styles link only through the Properties/BasedOn element, as the styles-cascade sample's PDF shows InDesign does. Table and cell style groups are retained and saved unchanged, where saving used to drop them. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Importing a real template listed InDesign's defaults as unread: each section's layout name as an alternate layout, default object styles' text-frame and effects categories enabled at their default values, retained text-variable definitions and already typed story structures as retained content, and a group's own wrap and export settings as unsupported frames, which were read as page items. The report now names only what Schist does not set: a second layout or a pagination master, a category whose settings differ from InDesign's defaults, structures still unset after reading, and a group wrap that is on. One key is added to all 150 catalogs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Gradient swatches are typed from Graphic.xml, linear or radial with colour or tint stops, and fill items whose FillColor names them, running where the item's GradientFillStart, Length and Angle say; saving writes them back. With no start stated a gradient begins at the path's left and bottom edges and runs its width, as InDesign's own exports write and as its PDF of the public paged-media gradients sample draws. Plates, the composite and the canvas mix each pixel's two stops. A radial highlight is reported and not drawn; one key is added to all 150 catalogs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Items now stroke with their EndCap, EndJoin, MiterLimit and StrokeAlignment, locally or from an object style's Stroke and Corner Options category, in output and on the canvas, and save them. Strokes mitre by default as InDesign's do; shape strokes had joined round. Inside and outside alignment move the path half the weight for fill and stroke alike, as InDesign's PDF of the public paged-media strokes-fills sample draws them. Importing every sample of that corpus found three misreadings, now fixed: Lab colours in the specification's LAB spelling, guides on a spread, and bullets remembered with their font. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A text frame's stroke now moves its text in by its reach into the frame: half a centred weight, an inside weight, nothing outside or uncoloured, as InDesign's PDF of the public paged-media stroke-inset sample measures. Shaped frames offset their outline exactly, matching that sample's chamfered frames where they had been about 4 pt further in. Rectangles, text frames and image frames take rounded, inverse rounded, bevel and inset corners per corner, locally or from an object style; the item keeps its rectangle and draws, clips and sets its text in the cornered outline, and saving writes the rectangle with its corner attributes. Decorative corners and corners on other outlines are kept, drawn square and reported. Contour wrap around a shaped image frame no longer shrinks to its corner. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Body text now fits a frame's last line by its baseline, its descent hanging below the frame, as InDesign's PDF of the public paged-media stroke-inset sample sets a fifth line in frames 0.3 pt deeper than its baseline. Schist used to need room for the descent, so frames InDesign filled exactly overset their last line. Columns, wrapped bands and blank lines follow the same rule, and a footnote that cannot fit moves its reference line on by that line's baseline. Footnote bodies and vertical text still fit whole line cells, for want of native evidence. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Items stroke with gradient swatches as they fill with them: a StrokeColor naming a Gradient runs where the item's GradientStrokeStart, Length and Angle say, or with no start from the path's left and bottom edges over its width, in plates, the composite and on the canvas, aligned centre, inside or outside as a solid stroke is; saving writes it back, and a stroke's highlight is reported as a fill's is. Text fills and strokes with them too, from paragraph and character styles and local ranges, running over the frame the text is set in, and an underline or strikethrough in the text's colour follows. The first stop stands in as the ink for readers of solid colour. No public sample strokes or sets text in a gradient: of the paged-media corpus PDFs only the gradients sample has shadings, all rectangle fills. So both read the specification as the fill evidence reads it. InDesign's text defaults, a start of 0 0 beside a length of -1, state no vector; a start text does state is saved but reported and not drawn. One key is added to all 150 catalogs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A table's border and its alternating row and column strokes now resolve into its cells' edges when it is read. Each attribute of an edge comes from the cell or its cell styles; else, on the table's outside, from the border (TopBorderStrokeWeight and its kin) on the table, its style chain and [No table style]; else from the group of alternating strokes its body row or column falls in; else InDesign's 1 pt black. Absent settings are those InDesign's own exports write for [No table style]. Each row or column in a group strokes both its edges, a Schist reading of the specification, as no public sample sets a pattern. Strokes are drawn by grid line and column or row. A grid line two cells share draws the edge from the stronger source (the cell or its styles, then the table, then nothing), the lower or right cell's on a tie, except that a header row's bottom edge is drawn above the body and a footer row's top edge below it. Row strokes run half their weight past a crossing where the line changes stroke and column strokes stop at them; ColumnOnTop swaps the two. InDesign's PDF of the public paged-media tables sample fixes these rules: page 5's 3 pt magenta middle cell drawn over its neighbours on all four sides, page 6's spanned cells, page 12's header bottom edge winning over a body cell's stated top edge. Before, a shared line always drew the lower cell's top edge, so page 5's magenta cell lost its bottom and right edges. SpaceBefore and SpaceAfter (4 and -4 pt when nothing states them) keep room above a table's first part and below its last; a column's first line drops the space before, as the tables and tables-rows PDFs set tables at the top of frames, cells and continuing frames. StartRow on a body row ends the part before it and starts its part in the next column, frame, page or odd or even page, through a row event composition passes like a paragraph start; on the first row it moves the table on from the text before it. Stroke types other than solid, overprinted strokes, undefined StrokeOrder values and StartRow on rows with no place to start are reported. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Items now stroke with their StrokeType, locally or from an object style's Stroke and Corner Options category, in output and on the canvas, and save it: custom dashed, dotted and striped stroke styles, the resources underlines already use, and the built-in Dashed style with the item's own StrokeDashAndGap, cap and StrokeCornerAdjustment. GapColor, GapTint and OverprintGap fill the rest of the stroke's band with their own ink, as decoration gaps do. The path stays as it is: dashes start at its first point and run on round its corners, a corner adjustment fits each stretch between corners with a dash at both ends, and stripes run across from the stroke's left edge. A StrokeType the package does not declare strokes solid, as InDesign's PDF of the public paged-media strokes-fills sample draws four such types; saving declares the built-in styles items name. Other built-in styles, which the specification only names, are kept, drawn solid and reported, as are arrowheads. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The canvas paints a dashed, dotted or striped stroke's marks with the stroke's own fill, so a gradient stroke dashes with its gradient, and lays an aligned pattern's fill without a stroke band. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The format notes describe item stroke types, gradient strokes and gradient text, and table borders, alternating strokes, spacing and row starts, with their public evidence and the readings no sample settles. The roadmap records the merged batch, its shared sweep with baseline fitting, and its native review. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Text frames read and save their auto-size settings and fit their text when they are opened and after every edit, the fit folding into the edit's undo step. A height fit ends the frame at its last baseline plus its bottom inset and stroke reach, as InDesign's PDF of the public paged-media text-autosize sample grows a 40 pt frame to 156.856 pt, about the frame's reference point and never below its minimum. Width-only and height-and-width frames take their longest line's width. Threaded frames keep their size, as the public PSU template's own export shows; proportional fits and multi-column or shaped auto-size frames are kept and reported, with one key added to all 150 catalogs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Items blend with what lies beneath them as their BlendMode says, plate by plate on each ink's complement as PDF blends subtractive colour, and cast drop shadows: everything the item paints, paper included, moved by the shadow's offsets, blurred to its size and laid beneath in its colour at its opacity and blend. InDesign's PDF of the public paged-media effects sample masks its shadows with one edge curve scaled by the size, a Gaussian of deviation half the size, which three box blurs follow to within 0.03. The canvas casts shadows from shapes and frame fills and strokes. Effects Schist does not draw, which imports used to drop silently, are reported; one key is added to all 150 catalogs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
InDesign's PDF of the public paged-media layout sample shows how it fits the auto-size cases the text-autosize sample left open. Height-and-width frames now take the narrowest width their widest unbreakable fragment allows and then the height of their lines, as InDesign narrows two 200 pt frames of short paragraphs to 30 pt about their reference points; Schist had taken their longest unbroken line. Multi-column frames, reported until now, take the shortest height that leaves no text over, holding ten of twenty lines in each of two columns as InDesign's does, to within the point InDesign leaves below them. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A toolbar toggle beside guides and snapping draws each page on the canvas as it separates, bleed included, a pixel to the canvas unit, instead of item by item. Blend modes, shadows cast by text and images and overprinting, which the canvas cannot draw because it paints items one by one, show there as they print. The preview is the separation's composite through the separations preview's CMYK to RGB conversion, cached until the document, zoom or fonts change; frame edges, ports, notes and the story being typed are drawn over it. One key is added to all 150 catalogs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Phase 0 is decided: the INDD database is mapped from the public specimens' bytes alone. Two master pages select an A/B page map; objects are indexed by UID in a class tree and a location tree and held in data pages or slotted records with continuations, uncompressed. Every IDML Self id is the UID of the same object, so each field was identified against InDesign's own export of the same document. That justifies a reader; half of each page checksum is still unknown, so not a writer. schist-codec-indd reads pages, margins, sections, bleed, spreads, parent pages, layers, swatches, paths, groups, text frames, threads and story text, writes them as IDML parts and reads those with the IDML importer, behind the design-mode flag. The specimen tests hold every recovered object to the IDML importer's reading of each twin; everything else is reported, and an INDD document saves as IDML. docs/indd-format.md has the layout, the evidence and the go/no-go. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Brings in the photo development workspace, Camera Raw masks, viewer overlays, the JPEG XL, AVIF, OpenRaster, Krita and OpenEXR codecs, GPX geotagging and duplicates, and the Remove tool. The two conflicts were additive: the keymap tests import both branches' actions, and the panels module declares both paragraph_keeps and photo. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
IAmJSD
marked this pull request as ready for review
October 8, 2026 12:36
The Ubuntu job ran out of disk during `cargo test --workspace`: every integration test file links its own binary, and the layout, IDML, separation, text-engine and INDD suites took the workspace from 171 to 294 of them, each with full debug info. Free the hosted image's unused toolchains (keeping the Android SDK the cross-check needs) and build the tests with line tables only, which keeps backtraces readable. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Design Mode now composes more imported typography and text-only footnotes while preserving editable source text. Generated references and list markers no longer change the source paragraph's formatting, direction, initial count or nested-style boundaries. The feature remains disabled by default.
[No character style]and always define both IDML root styles, so every style reference resolves inside the package; on reading, the root character style is the absence of a style.anchoredsample, measured from its content stream. Boxes scale with their text in the preview and at every output resolution. One key is added to all 150 catalogs.variablessample shows (all eight headers on all five pages reproduced). Next/previous page numbers inside a multi-frame thread follow their own thread from the frame they land in, matching the same PDF. One key is added to all 150 catalogs.tablesandtables-rowssamples. The PSU academic template's table now types. One key is added to all 150 catalogs.tables-rows(three frame-break pages) andtables-overset(five frame heights) samples. A table never shares a line with text, never overlaps the text above under fixed leading, and overhangs a column narrower than itself. StartRow and undefined repeat values are reported; one key is added to all 150 catalogs.tablessample draws them, and styles link only throughProperties/BasedOn, as itsstyles-cascadePDF shows. Table and cell style groups are now retained on save.gradientssample draws. Plates, composite and canvas mix each pixel's two stops (separation tests reproduce the sample's linear, three-stop and radial pages). A radial highlight is reported; one key is added to all 150 catalogs.strokes-fillssample draws them. Importing all 59 public corpus samples found three misreadings, now fixed: Lab colours spelledLAB, guides on a spread, and bullets remembered with their font.stroke-insetsample measures; shaped frames offset their outline exactly, matching its chamfered frames where they had been about 4 pt further in. Rectangles, text frames and image frames take rounded, inverse rounded, bevel and inset corners per corner, locally or from an object style, drawn, clipped and composed from the settings while the item keeps and saves its rectangle. Decorative corners and corners on other outlines are kept, drawn square and reported; contour wrap around a shaped image frame no longer shrinks to its corner.stroke-insetsample sets a fifth line in frames 0.3 pt deeper than its baseline; frames InDesign filled exactly used to overset their last line. Columns, wrapped bands and blank lines follow, and a footnote that cannot fit moves its reference line on by that line's baseline; footnote bodies and vertical text keep fitting whole line cells.strokes-fillsPDF draws four; no public PDF draws a dash, so the dash geometry is the specification's reading. Other built-in styles and arrowheads are kept, drawn solid and reported.tablesPDF draws them; tables after text now keep[No table style]'s 4 pt before and −4 pt after.text-autosizesample grows a 40 pt frame to 156.856 pt, about the frame's reference point and never below its minimum; width-only and height-and-width frames take their longest line's width. Threaded frames keep their size, as the PSU template's own export shows; proportional fits and multi-column or shaped auto-size frames are kept and reported (one key in all 150 catalogs).effectssample masks its shadows with one edge curve scaled by the size, a Gaussian of deviation half the size, which three box blurs follow to within 0.03. The canvas casts shadows from shapes and frame fills and strokes; other effects, which imports used to drop silently, are reported (one key in all 150 catalogs).layoutsample does: height-and-width frames take the narrowest width their widest unbreakable fragment allows and then the height of their lines (InDesign narrows two 200 pt frames of short paragraphs to 30 pt about their reference points), and multi-column frames, reported until now, take the shortest height that leaves no text over, ten of twenty lines in each of two columns, within the point InDesign leaves below them..indd) documents for the subset the Phase 0 research recovered, behind the same feature flag. The database is mapped from the public specimens' bytes alone (no Adobe headers or binaries): two master pages select an A/B page map; objects are indexed by UID in a class tree and a location tree, held in data pages or slotted records with continuations, and uncompressed; every IDMLSelfid is the UID of the same object. Pages, margins, sections, bleed, spreads, parent pages, layers, swatches, rectangles, polygons, lines, groups, text frames, their threads and their stories' text are written as IDML parts and read by the IDML importer, and the specimen tests hold every recovered object to the IDML importer's reading of InDesign's own export of the same document. Everything else is reported; an INDD document saves as IDML. Phase 0's go/no-go (a reader, not a writer) and the evidence are indocs/indd-format.md. Twenty-two keys are added to all 150 catalogs.Validation for the custom-variable authoring commit (
aaad6dc0) was completed on Windows from an isolated worktree before any new code compiled:check-design-output, editable-interchange checks/lint, headless library WASM, shared UI, formatting and the commit's whitespace check pass, and the debug app builds. That checkpoint has 2,095 distinct passing Rust tests, and all 43 proof PDFs are byte-identical to ab0cdef3cbaseline regenerated on the same machine. Native review of its window in the actual development app (Design enabled, isolated configuration) passed creation, insertion, shared edits, one-step undo/redo, recapture, stale-cursor and closed-document refusal, coincident removal, delete refusal, the Stories entry point and IDML save/reopen. It also found the orphaned-window defect fixed here.Current checkpoint (
5325d604, INDD reader): all 18 roadmap targets (now includingcheck-inddandlint-indd), headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,362 distinct passing Rust tests (18 new) and no corrections; all 43 proof PDFs are byte-identical. The specimen tests read all three redistributable INDD specimens (InDesign CC 2014 Macintosh, 20.2 Windows) and agree with the IDML importer on every page, object, parent page, layer and placed story, and 504 damaged variants return errors without panicking. Native review opened each INDD in the debug app beside its IDML twin: the same pages, frames, layers and parent items, with text unstyled as reported.Output preview checkpoint (
05289f5b, output preview): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,344 distinct passing Rust tests (1 new) and no corrections; the strict i18n audit first caught the toggle's key duplicating the output window's, renamed. All 43 proof PDFs are byte-identical. Native review with one guarded click on the new toggle shows five 50 % magenta rectangles over cyan drawn Normal on the canvas, and in preview Multiply and Darken blue, Screen and Lighten cleared to paper, with both shadows rendered as they separate.Layout-sample auto-size checkpoint (
aa9de080, auto-size from thelayoutsample): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,343 distinct passing Rust tests (2 new) and no corrections; all 43 proof PDFs are byte-identical. Native review shows the previous build widening a height-and-width frame to its longest line and leaving a two-column frame overset, and the new one narrowing the first about its centre and growing the second to ten lines a column.Effects checkpoint (
9bfc16c4, blend modes and drop shadows): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,341 distinct passing Rust tests (10 new) and no corrections; all 43 proof PDFs are byte-identical. Native review shows a paper rectangle casting the sample's soft black shadow and a pale frame casting a magenta one on the canvas, with nothing reported unread; the plates' blends are checked by the separation tests.Auto-size checkpoint (
a91a49a8, text frame auto-size): all 16 roadmap targets, headless library WASM, shared UI, formatting and the debug app build pass on Windows with 2,331 distinct passing Rust tests (10 new), and all 43 proof PDFs are byte-identical; the whitespace check first failed on CRLF line endings left by a checkout, converted back to LF with nothing else changed. Native review of the publictext-autosizesample's own package shows the previous build leaving its filled 40 pt frame overset and the new one growing it to fit, the neighbouring frame's text wrapping beside the grown box and returning below it, as InDesign's PDF draws them.Merged-batch checkpoint (
356d5a26, baseline fitting with item stroke types, gradient strokes and text, and table borders): the last three were built in parallel by subagents in separate worktrees and merged here, resolving seven conflicting hunks and one canvas call. All 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,321 distinct passing Rust tests (43 new) and no corrections. The named-initial proof's footnoted horizontal case now sets its last row beneath the initial, in reading order, matching its reference; the other 42 proofs are byte-identical. Native review shows a frame setting a fourth line by its baseline where the previous build overset it, and one package with table borders, gradient text, and dashed (with a gap colour), long-dash, dotted, striped and gradient strokes, each as specified.Corner checkpoint (
38db8f9f, frame strokes and corner options): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,278 distinct passing Rust tests (16 new) and no corrections; beforehand the frame-paint separation test's reference gained the text inset its stroke now implies. The object-style proof's four text-frame pages move their text 5 pt in for the 10 pt stroke and still match their references; the other 42 proofs are byte-identical. Native review shows a stroked text frame rounded 30 pt with its first line 30 pt in and the rest inside the stroke, and rectangles with rounded, inverse rounded, bevel, inset and mixed corners, the decorative one square and reported.Stroke-option checkpoint (
27a3710c, stroke options): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,262 distinct passing Rust tests (9 new) and no corrections. The object-style proof's four rectangular frame pages now mitre their stroke corners (17 pixels at 60 dpi differ, all at corners); the other 42 proofs are byte-identical. Native review shows inside-, centre- and outside-aligned 12 pt strokes, round and bevel joins, a projecting cap, aLABspot colour and a spread guide, with nothing reported unread.Gradient checkpoint (
431e72b5, gradient fills): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,253 distinct passing Rust tests (10 new) and no corrections; all 43 proof PDFs are byte-identical. Native review shows the sample's three gradients (black to paper, cyan through magenta to yellow, radial from the bottom-left corner) and a frame filled at 90° on the canvas, with nothing reported unread.Import-report checkpoint (
76ed2026, accurate import reports): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,243 distinct passing Rust tests (4 new); one existing test now injects a category without a default exemption. All 43 proof PDFs are byte-identical. Opening the PSU academic template in the development app shows 7 unread items instead of 22.Table-style checkpoint (
805697d5, table and cell styles): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,239 distinct passing Rust tests (3 new) and no corrections; all 43 proof PDFs are byte-identical. Native review shows a style-striped table with a centred 60 % header from its region cell style, a cell opting out of the stripe, and the style's column fills hidden as ColumnFillsPriority asks.Table-break checkpoint (
a50ca7ec, tables breaking across frames): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,236 distinct passing Rust tests (11 new) and no corrections; all 43 proof PDFs are byte-identical. Native review found a broken table placing no part at all (the default body style's keep-lines rule counted table parts as lines), fixed with tests; the final capture shows a header, rows 1-7 and footer in the first frame and the repeated header, rows 8-14 (three kept rows moved on together) and footer in the second, with its overset marker.Table checkpoint (
095ce680, tables in their lines): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,225 distinct passing Rust tests (11 new); the i18n audit flagged the new message as long untranslated English, so it was shortened in all 150 catalogs and that check re-passed. All 43 proof PDFs are byte-identical. Native review found cell lines dropped where a row is as tall as its last baseline (no room for the descent); cell frames now extend by that descent, with a test that every cell line draws. The final capture shows a tinted header, multi-line cells and a bottom-justified cell as specified.File-name/date checkpoint (
90f6ce88, file-name and date variables): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,214 distinct passing Rust tests (9 new) and no corrections; all 43 proof PDFs are byte-identical. Native review shows creation and modification dates from a file's XMP, the session's output date and the file name rendering in a frame.Running-header checkpoint (
c29ff40b, running headers and in-thread jump numbers): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,205 distinct passing Rust tests (4 new); the sweep's two lint findings and two fixture expectations (public fixtures' default Running Header is now typed) were corrected and the layout, IDML and lint targets re-passed. All 43 proof PDFs are byte-identical. Native review shows header frames on three pages with a first-on-page heading as is and in upper case without end punctuation, carried forward over a page without a heading.Jump-line checkpoint (
b5615e0c, jump-line page numbers, object-style wrap, layer IgnoreWrap): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,201 distinct passing Rust tests (3 new); two outdated IDML test expectations found by the sweep were corrected and that target re-passed. All 43 proof PDFs are byte-identical. Native review shows a jump line reading "Next page 2 previous page 1", text wrapping around a box whose wrap comes from its object style, the new Layers toggle unwrapping its frame, and the Text Variables window inserting a next-page marker at a captured cursor.Anchored-wrap checkpoint (
dff813d6, wrap around anchored items): the source-frozen sweep of all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build passes on Windows with 2,198 distinct passing Rust tests (3 new) and no corrections; all 43 proof PDFs are byte-identical. Passive native review shows a box anchored at a sentence's end leaving its anchor line whole, the six lines beside it starting after its offset, and the lines below returning to full width.Anchored-frame checkpoint (
29e24efa, anchored text frames and groups): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,195 distinct passing Rust tests (9 new); the first sweep found one IDML round-trip failure (fresh ids on import changed a public fixture's stories after a save), corrected with a reserved placed-item id before a second full sweep. All 43 proof PDFs are byte-identical. Passive native review shows an anchored text frame setting its own story inline and a group of a box and circle in the margin beside its anchor.Anchored-position checkpoint (
9c757f22, above-line and custom anchored positions): the source-frozen sweep of all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build passes on Windows with 2,186 distinct passing Rust tests (10 new) and no corrections; all 43 proof PDFs are byte-identical to the inline-item checkpoint. Passive native review of the development app shows a centered banner above its paragraph's first line with the line lowered to make room, an oval in the frame's right margin at its anchor line and a box offset from its anchor, each where specified.Inline-item checkpoint (
1a8853b3, inline anchored items): all 16 roadmap targets, headless library WASM, shared UI, whitespace and the debug app build pass on Windows with 2,176 distinct passing Rust tests (19 new); a rustfmt-only correction to a new test file during the sweep re-passed the format check, the layout target and its lint on the final source, and all 43 proof PDFs are byte-identical to the shaped-frame checkpoint. Native review (passive captures of the development app with Design enabled and isolated configuration) found two composition bugs, both fixed with tests: boxes were not scaled with their text at preview zoom or other output resolutions, and Auto leading never reached a tall item, so it overlapped the lines above. On the final build a tall raised item makes room for itself under Auto leading and overlaps upward under fixed leading, as InDesign does.Shaped-frame checkpoint (
9c516fb9, shaped frames and root styles): all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build pass on Windows with 2,157 distinct passing Rust tests (13 new). Two test-side mistakes found by the sweep (a missing test import; the object-style proof's rectangular reference for curved text) were corrected and their targets re-run on the final source. The object-style proof's two curved-text pages now match their independent reference with the text inside the ellipse; the other 42 proofs are byte-identical to the text-wrap checkpoint. Native review in the development app (Design enabled, isolated configuration) shows text following an elliptical frame and flowing around a hole, the compact Text on path / Text in shape row, and, after the typing fixes it prompted, spaced text typed straight into a new shaped frame and saved to IDML.Text-wrap checkpoint (
7dc6b99c): the final source-frozen sweep of all 16 roadmap targets, headless library WASM, shared UI, formatting, whitespace and the debug app build passes on Windows with 2,144 distinct passing Rust tests (22 new properties); all 43 proof PDFs are byte-identical across the batch's sweeps. Native review found two problems, both fixed and re-swept: a hyphenated paragraph whose first word did not fit an interval narrowed by an item was rejected whole (a plain word would instead have overflowed into the wrap), and multi-second pauses in the debug build after wrap edits (a debug composition of the review page fell from 1.08 s to 0.15 s). In the actual development app with Design enabled and isolated configuration, contour wrap flows text around both sides of an ellipse, offsets and the side dropdown work, and documents carrying each native wrap preset (contour, inside-outline, right-side box, jump object, next column, ignoring frame) render as specified. The review desktop was shared with another application being driven concurrently, so interactive input on the final build was stopped and its renders were captured passively from Schist's window.Previous checkpoint (
550ba45f): the source-frozen sweep of all 16 roadmap targets, shared UI, formatting and whitespace passes on Windows with 2,120 distinct passing Rust tests, four browser checks and eight Python audit tests; one existing shared UI documentation example remains ignored. Two fixes from native review (run-end insertion style, unsaved-close prompt) re-passed layout, IDML and Design tests and lints, workspace clippy, app/web checks, formatting, whitespace and the app build on the final source (2,122 tests). The variable proof now has 36 pages: the previous 24 are pixel-identical, the 12 parent-page page-number/section-marker cases match literal controls in every plate and in Poppler and pass visual review, and the other 42 proofs are byte-identical. Native review shows typed fixture Chapter/Last Page definitions, the chapter kind's Format-only draft, marker insertion with removable rows, page numbers following section edits through one-step undos, native ACE 18 output and preserved chapter numbering after save, and the unsaved-close prompt (Cancel keeps both windows; Don't Save quits; Save writes first).Earlier checkpoints on Windows:
021e3bbd(last page numbers, 2,105 tests) and the completedaaad6dc0validation (2,095 tests; 43 proofs byte-identical tob0cdef3c).Independent source/control proofs compare every process/spot plate at 72/144/216 dpi, then extracted PDF samples and Poppler renders. The new 12-page custom-variable proof matches independently authored ordinary text across horizontal/vertical writing, affine placement and process/spot paints; every page was visually reviewed. The 16-page end-style proof covers horizontal/vertical text, authored overrides, affine placement, repeated sequences and generated references in whole and actual split notes. All eight pairs are pixel-identical and every page passes visual review. Earlier repeat, word, delimiter, initial/reference, direction, list-marker, hyphenation and footnote proofs are included in the output sweep. Properties cover every continuation slice, source preservation, repeated IDML saves and exact undo/redo.
Native development-app reviews cover the compact dock, Story Editor, footnotes, PDF/package output, reopening and both Text Variables checkpoints. Some intermediate controls were reviewed in exact-commit CI browser artifacts with Design enabled while native capture was unavailable. These reviews cover collapsed defaults, reachable menus, inheritance, property edits and one-step undo/redo. The isolated development bundle uses its own configuration; the installed application is untouched.
Remaining limits: gradient highlights and stated text gradient starts; arrowheads, built-in stroke styles beyond Dashed and decorative corners; proportional auto-size and auto-size or effects from object styles; non-separable blend modes, shadow spread and noise, other effects (glows, inner shadow, feathers, bevel, satin) and blend modes on the canvas outside output preview; overprinted and non-solid table strokes, diagonal lines, cell rotation and table editing; anchored items in vertical text and threaded anchored frames; text wrap for vertical text, initials, list markers and of other stories around anchored objects; Story Editor/note-body variable cursor integration; date variables before a document has dates; page-dependent values in threads spanning pages or sections; note-body variables; active initial/nested-style interactions and control-containing values; indent markers; end-style controls with active initials, note-body controls and explicit end-delimiter counts above one; other structured-story composition; explicit breaks/start constraints inside notes; unknown spanning defaults and layout-dependent note numbering; sentence rules, unverified Repeat forms, structural delimiters and native drop-cap flags; advanced object styles. Unsupported settings remain retained and diagnosed. Public XML and native screenshots support the documented subsets; complete native Unicode segmentation, repeat-record representation and external placement/composer agreement remain unverified. INDD is read for the recovered subset; styles, strokes, text formatting, frame options, tables, footnotes, guides, placed images and curves are reported, and writing INDD is out of scope. Translation debt and detailed evidence are recorded in the roadmap and IDML format documentation.
🤖 Generated with Claude Code