144 Commits
Author SHA1 Message Date
aiongg 2a7a9b7da9 docs: document story links, link source IDs, style mappings and placed-text import options 2026-10-12 18:43:58 +00:00
aiongg 96a84f0487 docs: document articles and the EPUB accessibility version boundary 2026-10-12 17:44:15 +00:00
aiongg 9f72881d5e docs: document movies and sounds 2026-10-12 15:55:32 +00:00
aiongg a5987d0b47 fix: leave out timing targets whose element is not written 2026-10-12 14:52:14 +00:00
aiongg 6c61f25235 docs: document button behaviours 2026-10-12 14:35:38 +00:00
aiongg a6bb0c02e7 docs: document timing lists, motion presets and animation settings 2026-10-12 14:10:43 +00:00
aiongg 1d4686bb33 feat: write the alternative text and tagging of object styles 2026-10-12 13:46:08 +00:00
aiongg 0bd2db2b96 fix: write a colon in a style group's name as \: in its Self and Name 2026-10-12 13:40:58 +00:00
aiongg 0a40d2188a feat: write the extended keyboard shortcut of styles with a character key 2026-10-12 11:23:28 +00:00
aiongg 02e4405a59 feat: write the script labels of frames, shapes, groups, buttons and multi-state objects, and label strings as stored 2026-10-12 11:20:58 +00:00
aiongg c4672ad579 feat: write the overprint flags of groups and page item defaults 2026-10-12 10:20:37 +00:00
aiongg 750c912e0f feat: write 79 text attributes placed by the order of the attribute list
IDML writes a style's text attributes in ascending attribute ID order.
The IDs between known ones, with their payload types, place 79 more
attributes: ruby, kenten, tatechuyoko and warichu settings, OpenType
features, gap tints and colours, overprint flags, paragraph border
options and others. Styles and text runs write them wherever they are
stored; the root style values come from the INDD instead of the
observed values.
2026-10-12 09:06:55 +00:00
aiongg d58d89fa87 feat: write the layer before grouping, table style caption position, generated alternative text and nested style group names
- BeforeGroupingLayerReference from the u32 at 0 of chunk 0x324, a
  spread layer resolved to its layer.
- TableStyle CaptionPosition from DOM 21.5: attribute 0x1047D = 1 gives
  BeforeTable, absent gives AfterTable.
- AIGeneratedAltText, AltTextGenerationError and AltTextCropSyncRect of
  page items from chunks 0x1E262, 0x1E260 and 0x1E261.
- The Name of a nested style group is its full path joined by ':'.
2026-10-12 08:12:50 +00:00
aiongg 6dda8c63bd feat: write the preview data of unlinked images that name no raw data object as Contents
An image without a link whose chunk 0x8C23 is 0 or absent keeps its
file in its preview (0x170D -> class 0x1708 -> 0x119 -> raw data
object). Images of InDesign 2.0 to 5.0 whose chunk 0x8C1B names a class
0x8C01 object keep the preview as a preview.
2026-10-12 07:22:26 +00:00
aiongg f174589ec5 fix: return the previews of graphics in table cells and form states, and leave out damaged previews
`read_previews` also collects the page items of graphic table cells and
the items of form field states, which the package holds as well. Over
the open corpus this adds previews for 657 graphics in cells and 385 in
states; every cell graphic without `Contents` has one. Items anchored in
cell text were already in the story anchors.

A preview chain that can't be read gives no preview instead of failing
the graphic, and with it the conversion.

The README and ARCHITECTURE.md say that every conversion looks up each
graphic's preview object; only `convert` reads the preview data.
2026-10-12 06:15:20 +00:00
Wiktor Wiesek 6d41202f17 feat: return the previews of graphics whose file is not in the document
`indd::convert` now returns `Conversion::previews`: InDesign's screen
preview (chunk 0x170D -> class 0x1708 -> chunk 0x119 -> raw data) of each
placed graphic without `Contents`, one entry per preview file with the
`Self` of every graphic that uses it. IDML has no place for a preview, so
the package is unchanged; an application can show the preview when it
cannot read a linked file. `convert_into` and `indd audit` do not read
previews.

Output: `diff_outputs.py --exclude own/` over 23 files (the fixtures and
part of the open corpus): 0 differing outputs, 0 changed warnings or
failures.
2026-10-12 05:49:46 +00:00
aiongg 032ab0b15c feat: write the story, link, contour, object style and HTML5 export values of DOM 21.1 to 21.5, and the anchored settings of every complete element
Stories and XML stories get the Ai* attributes from DOM 21.5; links the
Ai* attributes from 21.5 and SourceObjectName from 21.4; every typed
ContourOption the four contour parameters from 21.4; object styles
EpubAriaLabel and EpubAriaLabelSourceType from 21.2; designmap.xml
Html5ExportPreference from 21.1. LockPosition and AnchorSpaceAbove go on
every AnchoredObjectSetting with all ten settings, polygons included,
in place of the per-tag WhenWritten blocks.
2026-10-12 04:59:47 +00:00
aiongg 3e8ea49d4a feat: write clipping path settings of every type, their geometry, and those of placed pages
Chunk 0x2C1A gives the clipping type (None, DetectEdges, AlphaChannel,
PhotoshopPath) and a flags byte (high-resolution image, invert and
restrict to frame). Graphics of types 1 to 3 write their chunk 0x162B
paths as ClippingPathGeometry; PhotoshopPath names come from key 0x7D
of the image properties when ASCII, AlphaChannel names from chunk
0x177C. Placed pages get the element with the values of graphics
without the chunk.
2026-10-12 04:08:34 +00:00
aiongg 2cab1c0d65 feat: read RulerOrigin and measure guide locations from it
Chunk 0x808 of the preferences is the ruler origin (0 spread, 1 page,
2 spine). With PageOrigin a page guide is measured from its own page,
with SpineOrigin a vertical guide on a two-page spread from the spine.
The difference is taken after adding the spread's translation, which
gives IDML's 0 for guides on the origin.
2026-10-12 01:02:06 +00:00
aiongg 92201b848a feat: write 13 Q as the optical margin size of stories without chunk 0x2EE in Q documents
A story without chunk 0x2EE has OpticalMarginSize 9.2125984251969 (13 Q)
when the text size unit is Q, and 12 otherwise: 33,351 of 33,351
stories of the trustworthy pairs. The preferences' size of new frames
does not give it (3 pairs differ).
2026-10-11 23:48:07 +00:00
aiongg 7fcdc80b61 feat: read IncludeSectionPrefix and name pages and sections by it
Section chunk 0x4C02 stores IncludeSectionPrefix as a u16 after a u16 0.
The section Name is its prefix; pages of a section that includes the
prefix are named with it. The first section starts at its stored start
even when it continues numbering, and the page descriptor writes a
return in the marker as U+2029.
2026-10-11 18:01:55 +00:00
aiongg 1149d01150 feat: write a paragraph range per paragraph-style record
IDML starts a ParagraphStyleRange at every paragraph-style run record,
also between neighbouring records with equal formatting. Document the
rule and the paragraph length list of the records in objects.md, and
the remaining splits inside one record in unknowns.md.
2026-10-11 17:24:08 +00:00
aiongg 60928833fe docs: update the InsetSpacing counts 2026-10-11 15:01:00 +00:00
aiongg 35f15b7556 feat: write InsetSpacing as the f64 at 0 of chunk 0x3723 for frames that are not 4-point rectangles
A plain rectangle has exactly four straight points along the axes. Other
frames take the one number from offset 0 of chunk 0x3723, whatever their
four insets, and before DOM 11 always have InsetSpacing.
2026-10-11 14:22:55 +00:00
aiongg f941f0fd0e docs: update the InsetSpacing counts 2026-10-11 14:06:50 +00:00