epub-codec 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -132,10 +132,10 @@ Every construct this package's XHTML mapping cannot represent losslessly is a do
132
132
  - **`epub/style-residue`** — a document's own `<head>` style declarations (`<link rel="stylesheet">`, `<style>`) are quarantined verbatim as `SourceResidue` on the owning `ContentSection`, never interpreted: CSS is residue, not content. `writeEpubContent` re-emits it into the written `<head>` on a same-format write (this family's standard restorable-fidelity re-emission contract).
133
133
  - **An empty or whitespace-only paragraph (`<p></p>`, `<p> </p>`, or bare whitespace text between two block-level siblings — the common case in any pretty-printed real EPUB) is dropped entirely on read**, matching the same "anonymous block box" rule a browser's own HTML block-formatting context already applies to inter-block whitespace, rather than becoming a bogus empty `ContentParagraph`.
134
134
  - **List marker type (bullet vs. ordered, and an `<ol>`'s own non-default `start`) is packed into the opaque `numId`** (`epub{N}:{bullet|ordered}[@{start}]`, `src/xhtml/list-id.ts`), since `ContentListMembership` carries no field of its own for it — the identical mechanism `markdown-codec`'s own `src/shared/list-id.ts` uses for its GFM bullet/ordered distinction, hand-mirrored rather than shared. A numId outside this grammar (odf.js's bare `"list1"`, markdown-codec's own `"md1:bullet"`) is read back as an ordinary bullet list with no declared start.
135
- - **A `<p>` containing a direct `<img>`** (some producers/editors wrap every floating image in a paragraph tag rather than a `<figure>`) is split at the image: the phrasing content before and after becomes its own paragraph (dropped entirely when empty), the image its own block, in source order — an image nested deeper than a direct child (inside a `<span>`, say) is not detected by this split.
135
+ - **A container's own direct-child `<img>`** (some producers/editors wrap every floating image in a paragraph tag rather than a `<figure>`) is split at the image by `readContainerChildren`: the phrasing content before and after becomes its own paragraph (dropped entirely when empty), the image its own block, in source order. That split fires for every container this package reads transparently through `readContainerChildren` `<body>` itself, `<p>`, `<li>`, `<blockquote>`, `<figure>`, `<div>`, `<section>`, `<article>`, `<aside>`, and `<nav>` — never only a named handful of them; an `<img>` reached anywhere else — nested inside a `<span>`/`<a>` at any depth, or a _direct_ child of a heading, a `<figcaption>`, a `<dt>`/`<dd>`, or a table cell, none of which route through `readContainerChildren` at all — is instead reached by `src/xhtml/inline.ts`'s own run-building recursion, which by that point has committed to producing a flat run sequence with no block list left to insert a sibling image block into, and degrades to its alt text (or nothing, when it carries none) with an `epub/image-inline-unsupported` diagnostic rather than silently vanishing. That guarantee covers those inline-recursion paths specifically, not every remaining case: an `<img>` inside a `<pre>`/`<code>` block is lost outright, since `readPre` extracts only text content and never reaches `inline.ts` at all; one inside a `<table>`'s own `<caption>` is lost the same way, since `readTable` only descends into `tr`/`thead`/`tbody`/`tfoot` and drops any other child; a `<dl>` wrapping its `<dt>`/`<dd>` pairs in a `<div>` (legal HTML5, used by producers that want a per-entry styling hook) loses the whole wrapped group, since `readDefinitionList` only recognises a `dt`/`dd` that is a direct child of the `<dl>`; and a `<ul>`/`<ol>` nested directly inside another list rather than inside an `<li>` (not valid HTML5, but a shape real-world converters do emit) loses the entire nested list and its content, since `readList` only recognises an `<li>` child — four genuinely silent gaps, tracked as [ExaDev/documents.js#994](https://github.com/ExaDev/documents.js/issues/994) rather than fixed here.
136
136
  - **A blockquote containing a heading cannot carry its `division` construct** — a marker extent may not open or close a heading scope, and the last heading inside an extent always leaves one standing (`document-schema.js`'s own constraint) — so it degrades to indent-only structure (still `indentLeftPt`/`styleId: "Quote"`) while the heading keeps its own heading fidelity.
137
137
  - **Image dimensions are derived from pixel size via the CSS reference-pixel ratio (1px = 1/96in)**, not read from any `<img width>`/`<img height>` attribute or CSS: an EPUB's own XHTML/CSS carries no reliable point-based sizing of its own, so the image's natural pixel size is the one dimension every manifest image reliably has.
138
- - **A GIF or SVG manifest image has no representation at all** — `ContentImageBlockSchema`'s own `format` field admits only `"png"`/`"jpeg"`, a family-wide schema constraint, not something this package works around; it degrades to alt text with an `epub/image-format-unsupported` diagnostic.
138
+ - **A GIF or SVG manifest image is not yet decoded** — `document-schema.js`'s `ContentImageBlockSchema` widened its `format` field to admit `"svg"`/`"gif"` alongside `"png"`/`"jpeg"` specifically for this package's own manifest image kinds, but this package's reader does not yet decode either one; it degrades to alt text with an `epub/image-format-unsupported` diagnostic until that decode work lands.
139
139
  - **A table cell's own construct-boundary marker (if a foreign producer's `ContentDocument` carries one) has no XHTML representation on write** and is dropped with a diagnostic — `document-schema.js`'s own `decompose` never descends into a table cell, so a cell's blocks are never grouped the way a section's are, and this package's own reader never emits one there either.
140
140
  - **`dc:publisher`/`dc:contributor`/`dc:rights` have no `LayoutMetadata` field to land in** and are reported as `epub/metadata-field-unmapped` rather than silently dropped.
141
141
 
package/dist/codec.d.cts CHANGED
@@ -595,7 +595,7 @@ declare const epubCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Ar
595
595
  kind: z.ZodLiteral<"drawing">;
596
596
  }, z.core.$strip>, z.ZodObject<{
597
597
  children: z.ZodArray<z.ZodObject<{
598
- mathml: z.ZodArray<z.ZodCustom<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>;
598
+ mathml: z.ZodArray<z.ZodType<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode, z.core.$ZodTypeInternals<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>>;
599
599
  starMath: z.ZodOptional<z.ZodString>;
600
600
  presentation: z.ZodOptional<z.ZodObject<{
601
601
  latex: z.ZodString;
@@ -1113,11 +1113,80 @@ declare const epubContentCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>,
1113
1113
  }, z.core.$strip>>>;
1114
1114
  colSpan: z.ZodOptional<z.ZodNumber>;
1115
1115
  rowSpan: z.ZodOptional<z.ZodNumber>;
1116
- background: z.ZodOptional<z.ZodObject<{
1117
- r: z.ZodNumber;
1118
- g: z.ZodNumber;
1119
- b: z.ZodNumber;
1120
- }, z.core.$strip>>;
1116
+ background: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
1117
+ kind: z.ZodLiteral<"solid">;
1118
+ color: z.ZodObject<{
1119
+ r: z.ZodNumber;
1120
+ g: z.ZodNumber;
1121
+ b: z.ZodNumber;
1122
+ }, z.core.$strip>;
1123
+ }, z.core.$strip>, z.ZodObject<{
1124
+ kind: z.ZodLiteral<"pattern">;
1125
+ patternType: z.ZodEnum<{
1126
+ percent5: "percent5";
1127
+ percent10: "percent10";
1128
+ percent12: "percent12";
1129
+ percent15: "percent15";
1130
+ percent20: "percent20";
1131
+ percent25: "percent25";
1132
+ percent30: "percent30";
1133
+ percent35: "percent35";
1134
+ percent37: "percent37";
1135
+ percent40: "percent40";
1136
+ percent45: "percent45";
1137
+ percent50: "percent50";
1138
+ percent55: "percent55";
1139
+ percent60: "percent60";
1140
+ percent62: "percent62";
1141
+ percent65: "percent65";
1142
+ percent70: "percent70";
1143
+ percent75: "percent75";
1144
+ percent80: "percent80";
1145
+ percent85: "percent85";
1146
+ percent87: "percent87";
1147
+ percent90: "percent90";
1148
+ percent95: "percent95";
1149
+ horizontalStripe: "horizontalStripe";
1150
+ verticalStripe: "verticalStripe";
1151
+ diagonalStripe: "diagonalStripe";
1152
+ reverseDiagonalStripe: "reverseDiagonalStripe";
1153
+ horizontalCross: "horizontalCross";
1154
+ diagonalCross: "diagonalCross";
1155
+ thinHorizontalStripe: "thinHorizontalStripe";
1156
+ thinVerticalStripe: "thinVerticalStripe";
1157
+ thinDiagonalStripe: "thinDiagonalStripe";
1158
+ thinReverseDiagonalStripe: "thinReverseDiagonalStripe";
1159
+ thinHorizontalCross: "thinHorizontalCross";
1160
+ thinDiagonalCross: "thinDiagonalCross";
1161
+ mediumGray: "mediumGray";
1162
+ darkGray: "darkGray";
1163
+ lightGray: "lightGray";
1164
+ darkHorizontal: "darkHorizontal";
1165
+ darkVertical: "darkVertical";
1166
+ darkDown: "darkDown";
1167
+ darkUp: "darkUp";
1168
+ darkGrid: "darkGrid";
1169
+ darkTrellis: "darkTrellis";
1170
+ lightHorizontal: "lightHorizontal";
1171
+ lightVertical: "lightVertical";
1172
+ lightDown: "lightDown";
1173
+ lightUp: "lightUp";
1174
+ lightGrid: "lightGrid";
1175
+ lightTrellis: "lightTrellis";
1176
+ gray125: "gray125";
1177
+ gray0625: "gray0625";
1178
+ }>;
1179
+ foregroundColor: z.ZodOptional<z.ZodObject<{
1180
+ r: z.ZodNumber;
1181
+ g: z.ZodNumber;
1182
+ b: z.ZodNumber;
1183
+ }, z.core.$strip>>;
1184
+ backgroundColor: z.ZodOptional<z.ZodObject<{
1185
+ r: z.ZodNumber;
1186
+ g: z.ZodNumber;
1187
+ b: z.ZodNumber;
1188
+ }, z.core.$strip>>;
1189
+ }, z.core.$strip>], "kind">>;
1121
1190
  borders: z.ZodOptional<z.ZodObject<{
1122
1191
  left: z.ZodOptional<z.ZodObject<{
1123
1192
  color: z.ZodObject<{
@@ -1356,10 +1425,10 @@ declare const epubContentCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>,
1356
1425
  endColumn: z.ZodNumber;
1357
1426
  }, z.core.$strip>>;
1358
1427
  type: z.ZodEnum<{
1359
- decimal: "decimal";
1360
- list: "list";
1361
1428
  date: "date";
1362
1429
  custom: "custom";
1430
+ decimal: "decimal";
1431
+ list: "list";
1363
1432
  time: "time";
1364
1433
  whole: "whole";
1365
1434
  textLength: "textLength";
@@ -2439,7 +2508,7 @@ declare const epubContentCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>,
2439
2508
  }, z.core.$strip>;
2440
2509
  }, z.core.$strip>, z.ZodObject<{
2441
2510
  formula: z.ZodObject<{
2442
- mathml: z.ZodArray<z.ZodCustom<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>;
2511
+ mathml: z.ZodArray<z.ZodType<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode, z.core.$ZodTypeInternals<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>>;
2443
2512
  starMath: z.ZodOptional<z.ZodString>;
2444
2513
  presentation: z.ZodOptional<z.ZodObject<{
2445
2514
  latex: z.ZodString;
package/dist/codec.d.ts CHANGED
@@ -595,7 +595,7 @@ declare const epubCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Ar
595
595
  kind: z.ZodLiteral<"drawing">;
596
596
  }, z.core.$strip>, z.ZodObject<{
597
597
  children: z.ZodArray<z.ZodObject<{
598
- mathml: z.ZodArray<z.ZodCustom<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>;
598
+ mathml: z.ZodArray<z.ZodType<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode, z.core.$ZodTypeInternals<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>>;
599
599
  starMath: z.ZodOptional<z.ZodString>;
600
600
  presentation: z.ZodOptional<z.ZodObject<{
601
601
  latex: z.ZodString;
@@ -1113,11 +1113,80 @@ declare const epubContentCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>,
1113
1113
  }, z.core.$strip>>>;
1114
1114
  colSpan: z.ZodOptional<z.ZodNumber>;
1115
1115
  rowSpan: z.ZodOptional<z.ZodNumber>;
1116
- background: z.ZodOptional<z.ZodObject<{
1117
- r: z.ZodNumber;
1118
- g: z.ZodNumber;
1119
- b: z.ZodNumber;
1120
- }, z.core.$strip>>;
1116
+ background: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
1117
+ kind: z.ZodLiteral<"solid">;
1118
+ color: z.ZodObject<{
1119
+ r: z.ZodNumber;
1120
+ g: z.ZodNumber;
1121
+ b: z.ZodNumber;
1122
+ }, z.core.$strip>;
1123
+ }, z.core.$strip>, z.ZodObject<{
1124
+ kind: z.ZodLiteral<"pattern">;
1125
+ patternType: z.ZodEnum<{
1126
+ percent5: "percent5";
1127
+ percent10: "percent10";
1128
+ percent12: "percent12";
1129
+ percent15: "percent15";
1130
+ percent20: "percent20";
1131
+ percent25: "percent25";
1132
+ percent30: "percent30";
1133
+ percent35: "percent35";
1134
+ percent37: "percent37";
1135
+ percent40: "percent40";
1136
+ percent45: "percent45";
1137
+ percent50: "percent50";
1138
+ percent55: "percent55";
1139
+ percent60: "percent60";
1140
+ percent62: "percent62";
1141
+ percent65: "percent65";
1142
+ percent70: "percent70";
1143
+ percent75: "percent75";
1144
+ percent80: "percent80";
1145
+ percent85: "percent85";
1146
+ percent87: "percent87";
1147
+ percent90: "percent90";
1148
+ percent95: "percent95";
1149
+ horizontalStripe: "horizontalStripe";
1150
+ verticalStripe: "verticalStripe";
1151
+ diagonalStripe: "diagonalStripe";
1152
+ reverseDiagonalStripe: "reverseDiagonalStripe";
1153
+ horizontalCross: "horizontalCross";
1154
+ diagonalCross: "diagonalCross";
1155
+ thinHorizontalStripe: "thinHorizontalStripe";
1156
+ thinVerticalStripe: "thinVerticalStripe";
1157
+ thinDiagonalStripe: "thinDiagonalStripe";
1158
+ thinReverseDiagonalStripe: "thinReverseDiagonalStripe";
1159
+ thinHorizontalCross: "thinHorizontalCross";
1160
+ thinDiagonalCross: "thinDiagonalCross";
1161
+ mediumGray: "mediumGray";
1162
+ darkGray: "darkGray";
1163
+ lightGray: "lightGray";
1164
+ darkHorizontal: "darkHorizontal";
1165
+ darkVertical: "darkVertical";
1166
+ darkDown: "darkDown";
1167
+ darkUp: "darkUp";
1168
+ darkGrid: "darkGrid";
1169
+ darkTrellis: "darkTrellis";
1170
+ lightHorizontal: "lightHorizontal";
1171
+ lightVertical: "lightVertical";
1172
+ lightDown: "lightDown";
1173
+ lightUp: "lightUp";
1174
+ lightGrid: "lightGrid";
1175
+ lightTrellis: "lightTrellis";
1176
+ gray125: "gray125";
1177
+ gray0625: "gray0625";
1178
+ }>;
1179
+ foregroundColor: z.ZodOptional<z.ZodObject<{
1180
+ r: z.ZodNumber;
1181
+ g: z.ZodNumber;
1182
+ b: z.ZodNumber;
1183
+ }, z.core.$strip>>;
1184
+ backgroundColor: z.ZodOptional<z.ZodObject<{
1185
+ r: z.ZodNumber;
1186
+ g: z.ZodNumber;
1187
+ b: z.ZodNumber;
1188
+ }, z.core.$strip>>;
1189
+ }, z.core.$strip>], "kind">>;
1121
1190
  borders: z.ZodOptional<z.ZodObject<{
1122
1191
  left: z.ZodOptional<z.ZodObject<{
1123
1192
  color: z.ZodObject<{
@@ -1356,10 +1425,10 @@ declare const epubContentCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>,
1356
1425
  endColumn: z.ZodNumber;
1357
1426
  }, z.core.$strip>>;
1358
1427
  type: z.ZodEnum<{
1359
- decimal: "decimal";
1360
- list: "list";
1361
1428
  date: "date";
1362
1429
  custom: "custom";
1430
+ decimal: "decimal";
1431
+ list: "list";
1363
1432
  time: "time";
1364
1433
  whole: "whole";
1365
1434
  textLength: "textLength";
@@ -2439,7 +2508,7 @@ declare const epubContentCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>,
2439
2508
  }, z.core.$strip>;
2440
2509
  }, z.core.$strip>, z.ZodObject<{
2441
2510
  formula: z.ZodObject<{
2442
- mathml: z.ZodArray<z.ZodCustom<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>;
2511
+ mathml: z.ZodArray<z.ZodType<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode, z.core.$ZodTypeInternals<import("document-schema.js").MathMlNode, import("document-schema.js").MathMlNode>>>;
2443
2512
  starMath: z.ZodOptional<z.ZodString>;
2444
2513
  presentation: z.ZodOptional<z.ZodObject<{
2445
2514
  latex: z.ZodString;
@@ -17,6 +17,7 @@ declare const EpubDiagnosticCodes: {
17
17
  readonly METADATA_FIELD_UNMAPPED: "epub/metadata-field-unmapped";
18
18
  readonly IMAGE_FORMAT_UNSUPPORTED: "epub/image-format-unsupported";
19
19
  readonly IMAGE_UNRESOLVED: "epub/image-unresolved";
20
+ readonly IMAGE_INLINE_UNSUPPORTED: "epub/image-inline-unsupported";
20
21
  readonly ELEMENT_UNMAPPED: "epub/element-unmapped";
21
22
  readonly STYLE_RESIDUE: "epub/style-residue";
22
23
  readonly FOOTNOTE_TARGET_UNRESOLVED: "epub/footnote-target-unresolved";
@@ -17,6 +17,7 @@ declare const EpubDiagnosticCodes: {
17
17
  readonly METADATA_FIELD_UNMAPPED: "epub/metadata-field-unmapped";
18
18
  readonly IMAGE_FORMAT_UNSUPPORTED: "epub/image-format-unsupported";
19
19
  readonly IMAGE_UNRESOLVED: "epub/image-unresolved";
20
+ readonly IMAGE_INLINE_UNSUPPORTED: "epub/image-inline-unsupported";
20
21
  readonly ELEMENT_UNMAPPED: "epub/element-unmapped";
21
22
  readonly STYLE_RESIDUE: "epub/style-residue";
22
23
  readonly FOOTNOTE_TARGET_UNRESOLVED: "epub/footnote-target-unresolved";
@@ -10,6 +10,7 @@ const EpubDiagnosticCodes = {
10
10
  METADATA_FIELD_UNMAPPED: "epub/metadata-field-unmapped",
11
11
  IMAGE_FORMAT_UNSUPPORTED: "epub/image-format-unsupported",
12
12
  IMAGE_UNRESOLVED: "epub/image-unresolved",
13
+ IMAGE_INLINE_UNSUPPORTED: "epub/image-inline-unsupported",
13
14
  ELEMENT_UNMAPPED: "epub/element-unmapped",
14
15
  STYLE_RESIDUE: "epub/style-residue",
15
16
  FOOTNOTE_TARGET_UNRESOLVED: "epub/footnote-target-unresolved",
@@ -1,2 +1,2 @@
1
- import { a as EpubEmptySpineError, c as EpubInvalidOpfError, d as EpubUnbalancedConstructMarkersError, f as EpubUnsupportedDocumentKindError, i as EpubDiagnosticSink, l as EpubPackageFlattenError, m as NOOP_EPUB_DIAGNOSTIC_SINK, n as EpubDiagnosticCodes, o as EpubInvalidContainerError, p as EpubWriteError, r as EpubDiagnosticSeverity, s as EpubInvalidMimetypeError, t as EpubDiagnostic, u as EpubParseError } from "./diagnostics-Ee4kG7mw.cjs";
1
+ import { a as EpubEmptySpineError, c as EpubInvalidOpfError, d as EpubUnbalancedConstructMarkersError, f as EpubUnsupportedDocumentKindError, i as EpubDiagnosticSink, l as EpubPackageFlattenError, m as NOOP_EPUB_DIAGNOSTIC_SINK, n as EpubDiagnosticCodes, o as EpubInvalidContainerError, p as EpubWriteError, r as EpubDiagnosticSeverity, s as EpubInvalidMimetypeError, t as EpubDiagnostic, u as EpubParseError } from "./diagnostics-tvGwPH46.cjs";
2
2
  export { EpubDiagnostic, EpubDiagnosticCodes, EpubDiagnosticSeverity, EpubDiagnosticSink, EpubEmptySpineError, EpubInvalidContainerError, EpubInvalidMimetypeError, EpubInvalidOpfError, EpubPackageFlattenError, EpubParseError, EpubUnbalancedConstructMarkersError, EpubUnsupportedDocumentKindError, EpubWriteError, NOOP_EPUB_DIAGNOSTIC_SINK };
@@ -1,2 +1,2 @@
1
- import { a as EpubEmptySpineError, c as EpubInvalidOpfError, d as EpubUnbalancedConstructMarkersError, f as EpubUnsupportedDocumentKindError, i as EpubDiagnosticSink, l as EpubPackageFlattenError, m as NOOP_EPUB_DIAGNOSTIC_SINK, n as EpubDiagnosticCodes, o as EpubInvalidContainerError, p as EpubWriteError, r as EpubDiagnosticSeverity, s as EpubInvalidMimetypeError, t as EpubDiagnostic, u as EpubParseError } from "./diagnostics-Ee4kG7mw.js";
1
+ import { a as EpubEmptySpineError, c as EpubInvalidOpfError, d as EpubUnbalancedConstructMarkersError, f as EpubUnsupportedDocumentKindError, i as EpubDiagnosticSink, l as EpubPackageFlattenError, m as NOOP_EPUB_DIAGNOSTIC_SINK, n as EpubDiagnosticCodes, o as EpubInvalidContainerError, p as EpubWriteError, r as EpubDiagnosticSeverity, s as EpubInvalidMimetypeError, t as EpubDiagnostic, u as EpubParseError } from "./diagnostics-tvGwPH46.js";
2
2
  export { EpubDiagnostic, EpubDiagnosticCodes, EpubDiagnosticSeverity, EpubDiagnosticSink, EpubEmptySpineError, EpubInvalidContainerError, EpubInvalidMimetypeError, EpubInvalidOpfError, EpubPackageFlattenError, EpubParseError, EpubUnbalancedConstructMarkersError, EpubUnsupportedDocumentKindError, EpubWriteError, NOOP_EPUB_DIAGNOSTIC_SINK };
@@ -9,6 +9,7 @@ const EpubDiagnosticCodes = {
9
9
  METADATA_FIELD_UNMAPPED: "epub/metadata-field-unmapped",
10
10
  IMAGE_FORMAT_UNSUPPORTED: "epub/image-format-unsupported",
11
11
  IMAGE_UNRESOLVED: "epub/image-unresolved",
12
+ IMAGE_INLINE_UNSUPPORTED: "epub/image-inline-unsupported",
12
13
  ELEMENT_UNMAPPED: "epub/element-unmapped",
13
14
  STYLE_RESIDUE: "epub/style-residue",
14
15
  FOOTNOTE_TARGET_UNRESOLVED: "epub/footnote-target-unresolved",
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { EpubBytesSchema, epubCodec, epubContentCodec } from "./codec.cjs";
2
- import { a as EpubEmptySpineError, c as EpubInvalidOpfError, d as EpubUnbalancedConstructMarkersError, f as EpubUnsupportedDocumentKindError, i as EpubDiagnosticSink, l as EpubPackageFlattenError, m as NOOP_EPUB_DIAGNOSTIC_SINK, n as EpubDiagnosticCodes, o as EpubInvalidContainerError, p as EpubWriteError, r as EpubDiagnosticSeverity, s as EpubInvalidMimetypeError, t as EpubDiagnostic, u as EpubParseError } from "./diagnostics-Ee4kG7mw.cjs";
2
+ import { a as EpubEmptySpineError, c as EpubInvalidOpfError, d as EpubUnbalancedConstructMarkersError, f as EpubUnsupportedDocumentKindError, i as EpubDiagnosticSink, l as EpubPackageFlattenError, m as NOOP_EPUB_DIAGNOSTIC_SINK, n as EpubDiagnosticCodes, o as EpubInvalidContainerError, p as EpubWriteError, r as EpubDiagnosticSeverity, s as EpubInvalidMimetypeError, t as EpubDiagnostic, u as EpubParseError } from "./diagnostics-tvGwPH46.cjs";
3
3
  import { EPUB_MIME_TYPE, OCF_CONTAINER_PATH, OCF_MIMETYPE_PATH } from "./format.cjs";
4
4
  import { EpubImageFormat, ImageDimensions, POINTS_PER_PIXEL, detectImageFormat, readImageDimensions } from "./image/dimensions.cjs";
5
5
  import { ZipEntry, unzipPackage, zipPackage } from "./zip.cjs";
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { EpubBytesSchema, epubCodec, epubContentCodec } from "./codec.js";
2
- import { a as EpubEmptySpineError, c as EpubInvalidOpfError, d as EpubUnbalancedConstructMarkersError, f as EpubUnsupportedDocumentKindError, i as EpubDiagnosticSink, l as EpubPackageFlattenError, m as NOOP_EPUB_DIAGNOSTIC_SINK, n as EpubDiagnosticCodes, o as EpubInvalidContainerError, p as EpubWriteError, r as EpubDiagnosticSeverity, s as EpubInvalidMimetypeError, t as EpubDiagnostic, u as EpubParseError } from "./diagnostics-Ee4kG7mw.js";
2
+ import { a as EpubEmptySpineError, c as EpubInvalidOpfError, d as EpubUnbalancedConstructMarkersError, f as EpubUnsupportedDocumentKindError, i as EpubDiagnosticSink, l as EpubPackageFlattenError, m as NOOP_EPUB_DIAGNOSTIC_SINK, n as EpubDiagnosticCodes, o as EpubInvalidContainerError, p as EpubWriteError, r as EpubDiagnosticSeverity, s as EpubInvalidMimetypeError, t as EpubDiagnostic, u as EpubParseError } from "./diagnostics-tvGwPH46.js";
3
3
  import { EPUB_MIME_TYPE, OCF_CONTAINER_PATH, OCF_MIMETYPE_PATH } from "./format.js";
4
4
  import { EpubImageFormat, ImageDimensions, POINTS_PER_PIXEL, detectImageFormat, readImageDimensions } from "./image/dimensions.js";
5
5
  import { ZipEntry, unzipPackage, zipPackage } from "./zip.js";
@@ -1,4 +1,4 @@
1
- import { i as EpubDiagnosticSink } from "../diagnostics-Ee4kG7mw.cjs";
1
+ import { i as EpubDiagnosticSink } from "../diagnostics-tvGwPH46.cjs";
2
2
  import { XmlElement } from "../xml/node.cjs";
3
3
  import { LayoutMetadata } from "document-schema.js";
4
4
  //#region src/opf/metadata.d.ts
@@ -1,4 +1,4 @@
1
- import { i as EpubDiagnosticSink } from "../diagnostics-Ee4kG7mw.js";
1
+ import { i as EpubDiagnosticSink } from "../diagnostics-tvGwPH46.js";
2
2
  import { XmlElement } from "../xml/node.js";
3
3
  import { LayoutMetadata } from "document-schema.js";
4
4
  //#region src/opf/metadata.d.ts
@@ -1,4 +1,4 @@
1
- import { i as EpubDiagnosticSink } from "../diagnostics-Ee4kG7mw.cjs";
1
+ import { i as EpubDiagnosticSink } from "../diagnostics-tvGwPH46.cjs";
2
2
  import { OpfPackage } from "./types.cjs";
3
3
  //#region src/opf/parse.d.ts
4
4
  declare function parseOpf(opfXml: string, sink?: EpubDiagnosticSink): OpfPackage;
@@ -1,4 +1,4 @@
1
- import { i as EpubDiagnosticSink } from "../diagnostics-Ee4kG7mw.js";
1
+ import { i as EpubDiagnosticSink } from "../diagnostics-tvGwPH46.js";
2
2
  import { OpfPackage } from "./types.js";
3
3
  //#region src/opf/parse.d.ts
4
4
  declare function parseOpf(opfXml: string, sink?: EpubDiagnosticSink): OpfPackage;
package/dist/read.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as EpubDiagnosticSink } from "./diagnostics-Ee4kG7mw.cjs";
1
+ import { i as EpubDiagnosticSink } from "./diagnostics-tvGwPH46.cjs";
2
2
  import { ContentDocument, DocumentTree } from "document-schema.js";
3
3
  //#region src/read.d.ts
4
4
  interface ReadEpubOptions {
package/dist/read.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as EpubDiagnosticSink } from "./diagnostics-Ee4kG7mw.js";
1
+ import { i as EpubDiagnosticSink } from "./diagnostics-tvGwPH46.js";
2
2
  import { ContentDocument, DocumentTree } from "document-schema.js";
3
3
  //#region src/read.d.ts
4
4
  interface ReadEpubOptions {
package/dist/write.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as EpubDiagnosticSink } from "./diagnostics-Ee4kG7mw.cjs";
1
+ import { i as EpubDiagnosticSink } from "./diagnostics-tvGwPH46.cjs";
2
2
  import { ContentDocument, DocumentTree } from "document-schema.js";
3
3
  //#region src/write.d.ts
4
4
  interface WriteEpubOptions {
package/dist/write.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as EpubDiagnosticSink } from "./diagnostics-Ee4kG7mw.js";
1
+ import { i as EpubDiagnosticSink } from "./diagnostics-tvGwPH46.js";
2
2
  import { ContentDocument, DocumentTree } from "document-schema.js";
3
3
  //#region src/write.d.ts
4
4
  interface WriteEpubOptions {
@@ -1,4 +1,4 @@
1
- import { i as EpubDiagnosticSink } from "../diagnostics-Ee4kG7mw.cjs";
1
+ import { i as EpubDiagnosticSink } from "../diagnostics-tvGwPH46.cjs";
2
2
  import { XmlElement } from "../xml/node.cjs";
3
3
  //#region src/xhtml/context.d.ts
4
4
  interface XhtmlReadContext {
@@ -1,4 +1,4 @@
1
- import { i as EpubDiagnosticSink } from "../diagnostics-Ee4kG7mw.js";
1
+ import { i as EpubDiagnosticSink } from "../diagnostics-tvGwPH46.js";
2
2
  import { XmlElement } from "../xml/node.js";
3
3
  //#region src/xhtml/context.d.ts
4
4
  interface XhtmlReadContext {
@@ -80,9 +80,24 @@ function appendElement(element, style, context, runs, constructs) {
80
80
  case "a":
81
81
  appendAnchor(element, style, context, runs, constructs);
82
82
  return;
83
+ case "img":
84
+ appendImageFallback(element, style, context, runs);
85
+ return;
83
86
  default: appendNested(element, style, context, runs, constructs);
84
87
  }
85
88
  }
89
+ function appendImageFallback(element, style, context, runs) {
90
+ const src = require_xml_query.attrValue(element, "src");
91
+ const alt = require_xml_query.attrValue(element, "alt");
92
+ const label = src === void 0 ? "<img>" : `<img src="${src}">`;
93
+ context.sink({
94
+ code: require_diagnostics.EpubDiagnosticCodes.IMAGE_INLINE_UNSUPPORTED,
95
+ severity: "warning",
96
+ message: `${label} is reached while building a flat run sequence with no block list left to insert a separate image block into; degraded to its alt text`,
97
+ href: context.sourceHref
98
+ });
99
+ if (alt !== void 0 && alt.length > 0) runs.push(styledRun(require_xml_entities.decodeEntities(alt), style));
100
+ }
86
101
  function appendNested(element, style, context, runs, constructs) {
87
102
  const nested = buildInlineRuns(element.children, style, context);
88
103
  runs.push(...nested.runs);
@@ -79,9 +79,24 @@ function appendElement(element, style, context, runs, constructs) {
79
79
  case "a":
80
80
  appendAnchor(element, style, context, runs, constructs);
81
81
  return;
82
+ case "img":
83
+ appendImageFallback(element, style, context, runs);
84
+ return;
82
85
  default: appendNested(element, style, context, runs, constructs);
83
86
  }
84
87
  }
88
+ function appendImageFallback(element, style, context, runs) {
89
+ const src = attrValue(element, "src");
90
+ const alt = attrValue(element, "alt");
91
+ const label = src === void 0 ? "<img>" : `<img src="${src}">`;
92
+ context.sink({
93
+ code: EpubDiagnosticCodes.IMAGE_INLINE_UNSUPPORTED,
94
+ severity: "warning",
95
+ message: `${label} is reached while building a flat run sequence with no block list left to insert a separate image block into; degraded to its alt text`,
96
+ href: context.sourceHref
97
+ });
98
+ if (alt !== void 0 && alt.length > 0) runs.push(styledRun(decodeEntities(alt), style));
99
+ }
85
100
  function appendNested(element, style, context, runs, constructs) {
86
101
  const nested = buildInlineRuns(element.children, style, context);
87
102
  runs.push(...nested.runs);
@@ -1,4 +1,4 @@
1
- import { i as EpubDiagnosticSink } from "../diagnostics-Ee4kG7mw.cjs";
1
+ import { i as EpubDiagnosticSink } from "../diagnostics-tvGwPH46.cjs";
2
2
  import { XmlElement } from "../xml/node.cjs";
3
3
  import { ContentBlock, ContentImageBlock } from "document-schema.js";
4
4
  //#region src/xhtml/write.d.ts
@@ -1,4 +1,4 @@
1
- import { i as EpubDiagnosticSink } from "../diagnostics-Ee4kG7mw.js";
1
+ import { i as EpubDiagnosticSink } from "../diagnostics-tvGwPH46.js";
2
2
  import { XmlElement } from "../xml/node.js";
3
3
  import { ContentBlock, ContentImageBlock } from "document-schema.js";
4
4
  //#region src/xhtml/write.d.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "epub-codec",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "EPUB 2/3 reading and deterministic EPUB 3 writing against the shared document-schema.js content pivot.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -57,6 +57,7 @@
57
57
  "_typecheck:attw": "attw --pack",
58
58
  "test": "turbo run _test",
59
59
  "_test": "vitest run --project unit",
60
+ "_test:coverage": "vitest run --project unit --coverage",
60
61
  "test:watch": "vitest --project unit",
61
62
  "test:workers": "turbo run _test:workers",
62
63
  "_test:workers": "vitest run --config vitest.workers.config.ts",
@@ -75,7 +76,7 @@
75
76
  "license": "MIT",
76
77
  "packageManager": "pnpm@11.6.0",
77
78
  "dependencies": {
78
- "document-schema.js": "^5.6.0",
79
+ "document-schema.js": "^6.0.0",
79
80
  "fast-xml-parser": "^5.10.1",
80
81
  "fflate": "^0.8.3",
81
82
  "zod": "^4.4.3"