An edit that moves lines into other frames composes on until a paragraph
starts in the same frame and place as before, or to the story's end, as
an_edit_that_moves_lines_composes_up_to_the_next_frame_the_text_starts_in
shows. The ROADMAP line no longer cites an issue about selection lag.
data.placeholder.add with role qr and the insertion point in text bound
the QR code to the first selected frame, which the caret was not in. It
now returns "qr placeholders bind to a frame", as a QR field there does.
A field inserted at the insertion point left the caret before its
marker, so a second field went in front of the first. The caret now
moves past the marker, as after typing.
Docs: docs/agents.md.
* Automation roots: refuse COM¹ to LPT³ and a device name before a colon
is_device_name missed COM¹, COM², COM³ and LPT¹, LPT², LPT³, which Windows reserves as it does COM1.
It also cut the name only at a period, so COM1: and NUL:x were not seen as device names.
* Credit my name in the About window
* Automation roots: document the device-name tests
CodeRabbit's docstring check counts the touched tests. same_component stays without a doc comment, because #2205 deletes that function and a doc line above it conflicts.
* Automation roots: record the device-name refusal
The MCP roots description and the roadmap now name COM¹ to LPT³ and a device name before a colon.
docs/gaps.md now lists the same cases as docs/architecture.md and
reuse::plain. A doc comment on rejoin says that a run style an edit uses
for the first time stops the reuse until the old composition reaches the
same style at the same index.
Every edit of a story composed it from its first paragraph, so a typed
character in a long threaded story cost as much as laying out the whole
story: 456 ms in a story threaded over 300 pages.
A composition that lays every paragraph once keeps its state before each
paragraph. After an edit, composing starts one paragraph above the first
changed one, in the kept state and with the lines above copied. It stops
at the first unchanged paragraph it reaches in the state kept for that
paragraph, and copies the lines from there on with their story offsets
moved by the length of the edit.
- The cache does this when only the story differs from its entry.
- Composed whole as before: stories with footnotes, endnotes, tables,
anchored objects, named lists, tracked deletions, balanced columns,
vertical justification other than Top, column rules, type on a path,
spanning or split paragraphs, paragraph borders or shading, and a
layout that goes back over a paragraph (keep options).
- An edit that moves lines into other frames is composed to the end of
the story.
In a 240-paragraph story a typed character composes 3 paragraphs
(240 before).
Docs: docs/architecture.md, docs/gaps.md (gap 20), ROADMAP.
Refs #2298
With the insertion point in a table cell or a note, data.placeholder.add
with an image field returned "a hyperlink field can't go in a table cell
or a note". It now returns a message about image fields that names the
two ways on: bind the field to a frame, or pass role text to merge its
path. Nothing is inserted on the error, and role text still puts the
marker in the cell.
Docs: docs/agents.md and the command's params text.
A clipped contour now looks only at the edges of the outline and its clips
that reach a line band, and charges its work budget for those alone. An
outline with thousands of points elsewhere no longer exhausts the budget
and falls back to the projections' common part. The Text wrap row of
docs/typography-parity.md notes that an image over 40 megapixels, or one
that can't be decoded, follows the frame's path.
- each traced Alpha Channel outline has a serial number, and the composition signatures include the outlines in use, so a relink or link update that changes only the image data no longer leaves text laid out around the old image
- a wrap with the default alpha threshold is saved without it, as before thresholds were stored
- docs/typography-parity.md says Alpha Channel contours follow the image's visible pixels
Paste ignored a bitmap on the system clipboard: a screenshot or an image
copied in a browser had to be saved and placed. Paste now places it.
- edit.pasteImage {base64, name?, spread?, at?} embeds the image in the
selected empty frame, or in a new frame centered on `at` at its stored
resolution (72 ppi when none) and at most 60% of the page width, as
File > Place sizes it. Save and reopen and IDML export keep the pixels.
Images over 64 million pixels and names without an image extension are
refused.
- Ctrl/Cmd+V pastes the image egui delivers with no text, and Edit >
Paste reads the clipboard's bitmap, or the first image file of a copied
file list, when there is no text or the text is only an address.
- The menu read waits at most 1.5 s on its own thread, with one read in
flight at a time.
- With a native menu, objects copied here still paste as objects until
the pasteboard's change count shows a newer copy.
- ui.paste takes {image} for the control channel.
A call with an `ids` or `id` that is not an object id used to fall back
to the selected frame or the caret's frame. It now fails and leaves the
document unchanged.
The Properties panel's Text Frame section shows the frame Text Frame
Options change: with the Type tool, the frame the caret is drawn in.
Type > Justification and Paragraph Style Options > Justification now show
Auto Leading (0% to 500% of the type size) and Single Word Justification
(Align Left, Align Center, Align Right, Full Justify). Both fields show the
selected paragraphs' values, or blank where they differ, and OK writes
autoLeading and singleWordJustify only when they were edited. An Auto
Leading outside 0% to 500% keeps the dialog open with the reason.
With the insertion point in footnote text or a table cell and no stored
frame on the caret, Text Frame Options changed the last frame of the
thread. They now change the frame the caret is drawn in: the frame that
holds the placed footnote, or the cell's own occurrence (not a repeated
header or footer), else the frame that shows the footnote reference or
the table's anchor.
object.textFrameOptions refuses a gutter outside 0 to 15552 pt, a column
count outside 1 to 40 (it was clamped) and an on/off option that is not
true or false (it was skipped). The Control bar's Columns field stops at
40, as the other column fields do. The params text gives the ranges and
lists flexibleWidth.
type.para and paragraph style create and edit refuse left and right
indents outside 0 to 15552 pt and first and last line indents outside
-15552 to 15552 pt. A style made from the selection is checked with the
values it takes from the selection.
style.paragraph.apply and style.paragraph.redefine check that Minimum,
Desired and Maximum stay in order in each justification row they change,
over the overrides paragraphs keep, and refuse the change otherwise.
Object > Text Frame Options and Cmd+B are enabled with a text caret or a
text selection. Without ids or selected objects, object.textFrameOptions
changes the frame that shows the insertion point, or every frame that
holds part of the selected text, instead of every frame of the story.
The dialog shows that frame's options and keeps the frames it opened
with while the preview reflows the text.
An empty ids list and an id that is not in the document are refused.
Options a frame already has leave the document unchanged and add no
undo step.
Fixes#2396
Insert Field with a QR column and the text cursor in a frame added a text placeholder, so a merge wrote the QR payload as plain text. It now returns "qr placeholders bind to a frame" and leaves the story unchanged.
type.para, style.paragraph.create and style.paragraph.edit accepted any
number for paragraph spacing and justification. They now refuse Space
Before, Space After and same-style spacing outside 0 to 15552 pt, word
spacing outside 0% to 1000%, letter spacing outside -100% to 500%, glyph
scaling outside 50% to 200%, Auto Leading outside 0% to 500%, and a
Single Word Justification other than left, center, right or
fullyJustified. Each justification row needs Minimum <= Desired <=
Maximum over the values the paragraph or style resolves to after the
change, including the styles based on an edited style and the
paragraphs, table cells and notes that use them.
object.textFrameOptions refuses an inset outside 0 to 15552 pt or a list
that is not four sides, and a verticalJustification, firstBaseline,
autoSize or columnsKind that is not one of its names. These were applied
or skipped without an error before. IDML import reads these values as
before.
An image field inserted at a text insertion point, or typed there as
<<name>>, merged as text, so each record showed the image's path.
It now merges as an inline image at its natural size, scaled down to
fit the smallest text column of the story's frames. A missing file is
listed in missingImages and its marker is removed. An explicit image
role at a text insertion point places an inline image too.
An image path that starts with one separator (\Photos\a.jpg) is tried
from the drive's root first, then beside the data file and the
document.
For an oval, a polygon or a frame with corner options, Inset Spacing dims
Top, Left, Bottom, Right and the link and shows one Inset field. OK sends
it as `object.textFrameOptions {inset: <number>}`, which sets all four
sides; compose keeps that inset from the frame's outline. Rectangular
frames keep the four fields.
* Tables: commands given a table id run with nothing in a table selected
Table commands whose params list `story?` and `table?` (table.insertRow,
table.deleteColumn, table.options, the Convert Rows commands and the
others) were refused with "place the insertion point in a table" when the
call named the table but the selection was not in one. A call that passes
`table` now acts on that table whatever is selected. A table that is not
in the document, or not in the given `story`, is refused, and a `story`
that is not a non-negative integer is an error.
The menus are unchanged: with nothing in a table selected, the table
items stay disabled, and calls that name no table are still refused.
* Tables: a bad story is refused whether or not a table is selected
A call that names a table with a story that is not a non-negative integer (a string, a negative number, a fraction or null) was refused only when nothing in a table was selected. With a table selected, the command ignored the story and acted on the named table. Both paths now read story with one helper and refuse it the same way.
* Tables: an edit to a named table keeps a caret in footnote text
With the caret in footnote text, a table command that names a table
runs, and the edit cleared the caret's footnote address, so the next
typing went into the story. clamp_selection now leaves footnote
addresses alone, as in_cell does.
* pt-BR: translate the 634 interface strings added since the catalog was completed
Covers the strings the catalog lacked after #495: tool names, menu
paths (Edit > Menus), Japanese typesetting dialogs (ruby, kinsoku,
mojikumi, warichu, kenten), special characters, Load Styles, Text
Frame auto-size, Data Merge, preflight, font replacement and About.
Tools are "Ferramenta X", parent pages "página principal", stories
"artigo"; menu paths reuse the existing menu names. IT, VA and Y:
stay as they are, as in every other language.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* pt-BR: one term per feature, the unit names, a catalog test and the docs
Review fixes for the new rows: Gradient Feather, stroke styles and type
on a path use the catalog's existing terms; warichu's Line Spacing no
longer reads as Leading; em/en dash, hair space, nonbreaking space and
hyphen and paragraph return take their Brazilian typographic names; the
file and word counts read correctly for one. File > New's unit names,
which reach tr at run time, are translated too.
The new test checks every pt-BR row's placeholders, padding and
ellipsis, and that each menu path is made of the menu names.
Docs: pt-BR re-measured at 2,416 of 2,419 strings (61% before) in
localization-parity.md, gaps.md (gap 21), target-app-parity.md and the
ROADMAP languages table and progress log. Readiness is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Docs: trace each localization count to its commit; list Russian
The 1,724 baseline was counted at a127c6d5 (#355); recounting that
commit by the same rule gives 1,723, with pt-BR at the same 1,057. The
2,419 strings are main at 438d7b6d. The 2,021 figure is gone: it was
the same rule at the last commit of 2026-10-10, not another scale.
Russian (ru, 1,705 of 2,419) joins the other shipped languages, which
makes six beyond the twelve; ROADMAP's two "Also shipped" lines become
one that includes it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* pt-BR: the 12 strings main added since; docs re-measured at 2e36dcf9
Merging main brought window and guide commands, the InDesign shortcut-set
import and the credits' PRs column, which pt-BR didn't translate yet. Its
button label and result message reach tr as literals no other catalog
has, so they join the shared test's list of UI strings.
Re-measured at main 2e36dcf9: pt-BR translates 2,431 of 2,434 strings
(the Control panel's IT, VA and Y: stay English) and the unit names;
Russian 1,709 of 2,434. The PR adds 645 strings and 7 unit names.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Docs: pt-BR at 2,574 of 2,941 strings by i18n-report; Russian listed
Re-measured on main f3bcc886 with `cargo xtask i18n-report`: pt-BR
translates 2,574 of 2,941 interface strings (1,933 before); the 367 it
lacks are mostly strings main added since 2026-10-23. pt-BR to full is
4-6 h. localization-parity.md, gaps.md (gap 21), target-app-parity.md
and the ROADMAP languages table and progress log say so, each with its
revision row; the ROADMAP entry is dated today, as the review asked.
Russian (1,855 of 2,941) joins the other shipped languages, eight beyond
the twelve, and ROADMAP's two "Also shipped" lines become one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* pt-BR: drop two rows main removed; the test lists eight live labels
`cargo xtask i18n-report` flagged ten pt-BR rows whose keys its
interface list lacks. "/1000 em" and "Import InDesign Set…" are gone
from the code, so their rows go. The other eight still reach tr
(Auto-Sizing, Color Theme, Minimum Height/Width, No Line Breaks,
Reference Point, the shortcut-import result and the unavailable-fonts
message) and join the test's list of UI strings.
The report now counts 2,939 strings; pt-BR translates 2,572 of them
(88%), Russian 1,853. The docs say so; the PR adds 632 strings and the
7 unit names.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* pt-BR: the 364 strings main added since 2026-10-23
Keyboard Shortcuts sets (craft-keymap's dialog, import messages and
counts), panel docking, OpenType features, page presets, the Package
summary and the command dialog's parameter names. "Atalho", "conjunto"
and "escopo" for shortcut, set and scope; tab groups stay "grupo de
guias" and inks "de escala"/"especial", as in the catalog. Key names
stay as printed on keyboards.
`cargo xtask i18n-report` now lists only the Control panel's IT, VA and
Y: for pt-BR: 2,936 of 2,939 strings. The docs say so; pt-BR to full is
1-2 h (an in-app check and the older parent-page and story terms).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* pt-BR review fixes: Affix in, Dir, End, Pathfinder and three clashes; doc scales
- "Affix in" (where footnote prefix and suffix appear) is "Afixos em".
- "Dir" is a folder in file.save, recovery save and links.copyTo and a
direction in text.move: "Pasta/direção".
- The End key is "Fim", as Home is "Início".
- Pathfinder keeps its name ("Objeto/Pathfinder"), as "Pathfinder:"
already did, instead of "Localizador de caminhos" beside "demarcador".
- Pattern (stroke dashes) is "Padrão de traço", apart from Default
("Padrão"); Skipped is "Pulados", apart from "ignoradas"; Heading is
"Intertítulo", apart from Title and Section headings.
ROADMAP's "Also shipped" line now uses one scale (today's i18n-report of
2,939 strings); the pt-BR note names main ef6c3686, and Russian reads
1,855 of 2,939.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>