@segnavia/idml 0.33.0 → 0.34.0
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/dist/anchored-frames.js +81 -0
- package/dist/chapter-openings.js +16 -0
- package/dist/map-book.js +65 -14
- package/dist/master-regions.js +89 -0
- package/dist/masters.js +30 -67
- package/dist/model.d.ts +2 -1
- package/dist/model.js +13 -6
- package/dist/openers.js +2 -14
- package/dist/paragraph-box.js +123 -0
- package/dist/placements.js +20 -14
- package/dist/positioned-box.js +9 -1
- package/dist/report.d.ts +1 -0
- package/dist/report.js +16 -6
- package/dist/stories.js +39 -13
- package/dist/story-model.js +9 -1
- package/dist/style-mappings.js +20 -0
- package/dist/style-property-report.js +19 -16
- package/dist/styles.js +75 -34
- package/dist/swatch-color.js +5 -5
- package/dist/types.d.ts +21 -1
- package/dist/unsupported-elements.js +2 -1
- package/package.json +3 -3
package/dist/styles.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { idmlDirection, localName } from "./xml.js";
|
|
2
2
|
import { resolveSwatchColor } from "./swatch-color.js";
|
|
3
|
-
import {
|
|
3
|
+
import { paragraphBoxDeclarations } from "./paragraph-box.js";
|
|
4
|
+
import { STYLE_PROPERTY_MAPPINGS, stylePropertyMapping } from "./style-mappings.js";
|
|
4
5
|
import { reportableStyleProperties } from "./style-property-report.js";
|
|
5
6
|
import { isTag } from "domhandler";
|
|
6
7
|
//#region src/styles.ts
|
|
7
8
|
const PARAGRAPH_ROOT = "$ID/[No paragraph style]";
|
|
8
9
|
const CHARACTER_ROOT = "$ID/[No character style]";
|
|
10
|
+
const OBJECT_ROOT = "$ID/[None]";
|
|
9
11
|
function text(element) {
|
|
10
12
|
return element.children.map((child) => "data" in child ? child.data : isTag(child) ? text(child) : "").join("").trim();
|
|
11
13
|
}
|
|
@@ -21,14 +23,18 @@ function properties(element) {
|
|
|
21
23
|
}
|
|
22
24
|
function parseStyles(roots, part) {
|
|
23
25
|
const result = [];
|
|
24
|
-
for (const kind of [
|
|
26
|
+
for (const kind of [
|
|
27
|
+
"ParagraphStyle",
|
|
28
|
+
"CharacterStyle",
|
|
29
|
+
"ObjectStyle"
|
|
30
|
+
]) for (const element of roots.filter((candidate) => localName(candidate.name) === kind)) {
|
|
25
31
|
const values = properties(element);
|
|
26
32
|
const id = values.Self;
|
|
27
33
|
if (!id) continue;
|
|
28
34
|
result.push({
|
|
29
35
|
id,
|
|
30
36
|
name: values.Name ?? id.split("/").at(-1) ?? id,
|
|
31
|
-
kind: kind === "ParagraphStyle" ? "paragraph" : "character",
|
|
37
|
+
kind: kind === "ParagraphStyle" ? "paragraph" : kind === "CharacterStyle" ? "character" : "object",
|
|
32
38
|
...values.BasedOn ? { basedOn: values.BasedOn } : {},
|
|
33
39
|
properties: Object.fromEntries(Object.entries(values).filter(([name]) => ![
|
|
34
40
|
"Self",
|
|
@@ -59,7 +65,32 @@ function parseSwatches(roots) {
|
|
|
59
65
|
return result;
|
|
60
66
|
}
|
|
61
67
|
function rootName(kind) {
|
|
62
|
-
return kind === "paragraph" ? PARAGRAPH_ROOT : CHARACTER_ROOT;
|
|
68
|
+
return kind === "paragraph" ? PARAGRAPH_ROOT : kind === "character" ? CHARACTER_ROOT : OBJECT_ROOT;
|
|
69
|
+
}
|
|
70
|
+
function findStyle(styles, id, kind) {
|
|
71
|
+
if (!id) return void 0;
|
|
72
|
+
const exact = styles.find((style) => style.id === id);
|
|
73
|
+
if (exact?.kind === kind) return exact;
|
|
74
|
+
return styles.find((style) => style.kind === kind && (style.name === id || style.id.endsWith(`/${id}`)));
|
|
75
|
+
}
|
|
76
|
+
function rootStyle(styles, kind) {
|
|
77
|
+
return styles.find((style) => style.kind === kind && (style.name === rootName(kind) || style.id.endsWith(`/${rootName(kind)}`)));
|
|
78
|
+
}
|
|
79
|
+
function styleChain(styles, id, kind) {
|
|
80
|
+
const root = rootStyle(styles, kind);
|
|
81
|
+
const chain = [];
|
|
82
|
+
const seen = /* @__PURE__ */ new Set();
|
|
83
|
+
let current = findStyle(styles, id, kind);
|
|
84
|
+
while (current && !seen.has(current.id)) {
|
|
85
|
+
seen.add(current.id);
|
|
86
|
+
chain.unshift(current);
|
|
87
|
+
current = findStyle(styles, current.basedOn, kind);
|
|
88
|
+
}
|
|
89
|
+
if (root && !chain.includes(root)) chain.unshift(root);
|
|
90
|
+
return chain;
|
|
91
|
+
}
|
|
92
|
+
function flattenedStyle(styles, id, kind) {
|
|
93
|
+
return Object.assign({}, ...styleChain(styles, id, kind).map((style) => style.properties));
|
|
63
94
|
}
|
|
64
95
|
function slug(value) {
|
|
65
96
|
return value.normalize("NFKD").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "style";
|
|
@@ -92,6 +123,21 @@ function resolvedFontProperties(changed, resolved) {
|
|
|
92
123
|
...resolved.FontStyle === void 0 ? {} : { FontStyle: resolved.FontStyle }
|
|
93
124
|
};
|
|
94
125
|
}
|
|
126
|
+
const PARAGRAPH_BOX_PROPERTIES = [
|
|
127
|
+
"SpaceBefore",
|
|
128
|
+
"SpaceAfter",
|
|
129
|
+
"LeftIndent",
|
|
130
|
+
"RightIndent",
|
|
131
|
+
...Object.keys(STYLE_PROPERTY_MAPPINGS).filter((name) => name.startsWith("ParagraphShading"))
|
|
132
|
+
];
|
|
133
|
+
function paragraphBoxOverrideProperties(changed, resolved, base) {
|
|
134
|
+
const touchesBox = Object.keys(changed).some((name) => PARAGRAPH_BOX_PROPERTIES.includes(name));
|
|
135
|
+
const hasShading = [base.ParagraphShadingOn, resolved.ParagraphShadingOn].some((value) => value?.trim().toLowerCase() === "true");
|
|
136
|
+
if (!touchesBox || !hasShading) return changed;
|
|
137
|
+
const output = { ...changed };
|
|
138
|
+
for (const name of PARAGRAPH_BOX_PROPERTIES) if (resolved[name] !== void 0) output[name] = resolved[name];
|
|
139
|
+
return output;
|
|
140
|
+
}
|
|
95
141
|
var StyleMapper = class {
|
|
96
142
|
swatches;
|
|
97
143
|
report;
|
|
@@ -110,6 +156,7 @@ var StyleMapper = class {
|
|
|
110
156
|
this.byId = new Map(styles.map((style) => [style.id, style]));
|
|
111
157
|
const taken = /* @__PURE__ */ new Set();
|
|
112
158
|
for (const style of styles) {
|
|
159
|
+
if (style.kind === "object") continue;
|
|
113
160
|
const base = `${style.kind === "paragraph" ? "idml-p-" : "idml-c-"}${slug(style.name)}`;
|
|
114
161
|
let candidate = base;
|
|
115
162
|
let suffix = 2;
|
|
@@ -119,20 +166,10 @@ var StyleMapper = class {
|
|
|
119
166
|
}
|
|
120
167
|
}
|
|
121
168
|
flattened(id, kind) {
|
|
122
|
-
return
|
|
169
|
+
return flattenedStyle([...this.byId.values()], id, kind);
|
|
123
170
|
}
|
|
124
171
|
styleChain(id, kind) {
|
|
125
|
-
|
|
126
|
-
const chain = [];
|
|
127
|
-
const seen = /* @__PURE__ */ new Set();
|
|
128
|
-
let current = this.findStyle(id, kind);
|
|
129
|
-
while (current && !seen.has(current.id)) {
|
|
130
|
-
seen.add(current.id);
|
|
131
|
-
chain.unshift(current);
|
|
132
|
-
current = this.findStyle(current.basedOn, kind);
|
|
133
|
-
}
|
|
134
|
-
if (root && !chain.includes(root)) chain.unshift(root);
|
|
135
|
-
return chain;
|
|
172
|
+
return styleChain([...this.byId.values()], id, kind);
|
|
136
173
|
}
|
|
137
174
|
styleClass(id, _kind) {
|
|
138
175
|
if (!id || id.includes("[None]") || id.includes("[No character style]")) return void 0;
|
|
@@ -142,11 +179,13 @@ var StyleMapper = class {
|
|
|
142
179
|
return value;
|
|
143
180
|
}
|
|
144
181
|
overrideClass(values, base, directionValue, location, styleDirection) {
|
|
145
|
-
|
|
182
|
+
let changed = Object.fromEntries(Object.entries(values).filter(([name, value]) => stylePropertyMapping(name)?.kind !== "non-formatting" && value !== base[name]));
|
|
146
183
|
const resolved = {
|
|
147
184
|
...base,
|
|
148
185
|
...values
|
|
149
186
|
};
|
|
187
|
+
const resetShading = base.ParagraphShadingOn?.trim().toLowerCase() === "true" && values.ParagraphShadingOn?.trim().toLowerCase() === "false";
|
|
188
|
+
changed = paragraphBoxOverrideProperties(changed, resolved, base);
|
|
150
189
|
for (const name of reportableStyleProperties(changed, resolved)) this.report.add(this.report.unsupportedOverrideProperties, name, location);
|
|
151
190
|
if (changed.AppliedFont !== void 0 || changed.FontStyle !== void 0) this.report.font(resolved.AppliedFont, resolved.FontStyle, location);
|
|
152
191
|
const cssProperties = Object.fromEntries(Object.entries(changed).filter(([name]) => stylePropertyMapping(name)?.kind === "css"));
|
|
@@ -156,7 +195,7 @@ var StyleMapper = class {
|
|
|
156
195
|
for (const name of ["Justification"]) if (base[name] !== void 0 && cssProperties[name] === void 0) cssProperties[name] = base[name];
|
|
157
196
|
}
|
|
158
197
|
if (Object.keys(cssProperties).length === 0) return void 0;
|
|
159
|
-
const key = JSON.stringify(Object.entries(cssProperties).sort(([a], [b]) => a.localeCompare(b))) + directionValue;
|
|
198
|
+
const key = JSON.stringify(Object.entries(cssProperties).sort(([a], [b]) => a.localeCompare(b))) + directionValue + resetShading;
|
|
160
199
|
const found = this.overrides.get(key);
|
|
161
200
|
if (found) return found.name;
|
|
162
201
|
const name = `idml-o-${this.overrides.size + 1}`;
|
|
@@ -164,7 +203,8 @@ var StyleMapper = class {
|
|
|
164
203
|
name,
|
|
165
204
|
properties: cssProperties,
|
|
166
205
|
direction: directionValue,
|
|
167
|
-
location
|
|
206
|
+
location,
|
|
207
|
+
resetShading
|
|
168
208
|
});
|
|
169
209
|
return name;
|
|
170
210
|
}
|
|
@@ -194,16 +234,16 @@ var StyleMapper = class {
|
|
|
194
234
|
this.reportUnmappedStyleProperties(style);
|
|
195
235
|
this.report.font(values.AppliedFont, values.FontStyle, style.location);
|
|
196
236
|
const dir = style.kind === "paragraph" ? this.paragraphStyleDirection(values) : this.bookDirection;
|
|
197
|
-
const declarations = this.declarations(values, dir, style.location);
|
|
237
|
+
const declarations = this.declarations(values, dir, style.location, this.report.unsupportedStyleProperties, false);
|
|
198
238
|
rules.push(`.${name}{${declarations}}`);
|
|
199
239
|
}
|
|
200
240
|
for (const value of this.overrides.values()) {
|
|
201
|
-
const declarations = this.declarations(value.properties, value.direction, value.location, this.report.unsupportedOverrideProperties);
|
|
241
|
+
const declarations = this.declarations(value.properties, value.direction, value.location, this.report.unsupportedOverrideProperties, value.resetShading);
|
|
202
242
|
if (declarations) rules.push(`.${value.name}{${declarations}}`);
|
|
203
243
|
}
|
|
204
244
|
return rules.join("");
|
|
205
245
|
}
|
|
206
|
-
declarations(values, dir, location, unsupported
|
|
246
|
+
declarations(values, dir, location, unsupported, resetShading) {
|
|
207
247
|
const output = [];
|
|
208
248
|
output.push(...this.fonts?.declarations(values.AppliedFont, values.FontStyle, location) ?? []);
|
|
209
249
|
const mapped = new Set(Object.keys(values).filter((name) => stylePropertyMapping(name)?.kind === "css"));
|
|
@@ -217,13 +257,17 @@ var StyleMapper = class {
|
|
|
217
257
|
else pt("Leading", "line-height");
|
|
218
258
|
const tracking = Number(values.Tracking);
|
|
219
259
|
if (mapped.has("Tracking") && Number.isFinite(tracking)) output.push(`letter-spacing:${tracking / 1e3}em`);
|
|
220
|
-
pt("SpaceBefore", "margin-block-start");
|
|
221
|
-
pt("SpaceAfter", "margin-block-end");
|
|
222
260
|
pt("FirstLineIndent", "text-indent");
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
261
|
+
output.push(...paragraphBoxDeclarations({
|
|
262
|
+
values,
|
|
263
|
+
mapped,
|
|
264
|
+
resetShading,
|
|
265
|
+
direction: dir,
|
|
266
|
+
swatches: this.swatches,
|
|
267
|
+
report: this.report,
|
|
268
|
+
unsupported,
|
|
269
|
+
location
|
|
270
|
+
}));
|
|
227
271
|
textDeclarations(values, mapped, output);
|
|
228
272
|
if (mapped.has("Justification")) this.justification(values.Justification, dir, output, location, unsupported);
|
|
229
273
|
if (hasCssMapping(mapped, "keeps")) this.keeps(values, output);
|
|
@@ -233,13 +277,10 @@ var StyleMapper = class {
|
|
|
233
277
|
return output.join(";");
|
|
234
278
|
}
|
|
235
279
|
findStyle(id, kind) {
|
|
236
|
-
|
|
237
|
-
const exact = this.byId.get(id);
|
|
238
|
-
if (exact?.kind === kind) return exact;
|
|
239
|
-
return [...this.byId.values()].find((style) => style.kind === kind && (style.name === id || style.id.endsWith(`/${id}`)));
|
|
280
|
+
return findStyle([...this.byId.values()], id, kind);
|
|
240
281
|
}
|
|
241
282
|
rootStyle(kind) {
|
|
242
|
-
return [...this.byId.values()]
|
|
283
|
+
return rootStyle([...this.byId.values()], kind);
|
|
243
284
|
}
|
|
244
285
|
reportUnmappedStyleProperties(style) {
|
|
245
286
|
const root = this.rootStyle(style.kind);
|
|
@@ -279,4 +320,4 @@ var StyleMapper = class {
|
|
|
279
320
|
}
|
|
280
321
|
};
|
|
281
322
|
//#endregion
|
|
282
|
-
export { StyleMapper, parseStyles, parseSwatches };
|
|
323
|
+
export { StyleMapper, flattenedStyle, parseStyles, parseSwatches };
|
package/dist/swatch-color.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
//#region src/swatch-color.ts
|
|
2
2
|
const colorComponent = (value) => Math.round(value + 1e-9);
|
|
3
|
-
function unresolved(id, location, use, report) {
|
|
4
|
-
report.add(report.unsupportedStyleProperties,
|
|
3
|
+
function unresolved(id, location, use, report, property) {
|
|
4
|
+
report.add(report.unsupportedStyleProperties, `${property}:${id}`, location);
|
|
5
5
|
return use === "fill" ? "currentColor" : void 0;
|
|
6
6
|
}
|
|
7
|
-
function resolveSwatchColor(id, swatches, report, location, use) {
|
|
7
|
+
function resolveSwatchColor(id, swatches, report, location, use, property = "FillColor") {
|
|
8
8
|
if (!id || id.endsWith("/None") || id === "None") return use === "fill" ? "none" : void 0;
|
|
9
9
|
if (id.endsWith("/Black") || id === "Black") return "#000";
|
|
10
10
|
if (id.endsWith("/Paper") || id === "Paper") return "#fff";
|
|
11
11
|
const swatch = swatches.find((value) => value.id === id || value.name === id);
|
|
12
|
-
if (!swatch) return unresolved(id, location, use, report);
|
|
12
|
+
if (!swatch) return unresolved(id, location, use, report, property);
|
|
13
13
|
if (swatch.model === "spot") {
|
|
14
14
|
report.add(report.spotColors, swatch.name, location);
|
|
15
15
|
return use === "fill" ? "currentColor" : void 0;
|
|
@@ -19,7 +19,7 @@ function resolveSwatchColor(id, swatches, report, location, use) {
|
|
|
19
19
|
const [c, m, y, k] = swatch.values.map((value) => value / 100);
|
|
20
20
|
return `rgb(${colorComponent(255 * (1 - c) * (1 - k))} ${colorComponent(255 * (1 - m) * (1 - k))} ${colorComponent(255 * (1 - y) * (1 - k))})`;
|
|
21
21
|
}
|
|
22
|
-
return unresolved(id, location, use, report);
|
|
22
|
+
return unresolved(id, location, use, report, property);
|
|
23
23
|
}
|
|
24
24
|
//#endregion
|
|
25
25
|
export { resolveSwatchColor };
|
package/dist/types.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface IdmlTextNode {
|
|
|
10
10
|
export interface IdmlStyle {
|
|
11
11
|
id: string;
|
|
12
12
|
name: string;
|
|
13
|
-
kind: 'paragraph' | 'character';
|
|
13
|
+
kind: 'paragraph' | 'character' | 'object';
|
|
14
14
|
basedOn?: string;
|
|
15
15
|
properties: Record<string, string>;
|
|
16
16
|
location: string;
|
|
@@ -87,6 +87,24 @@ export interface IdmlStory {
|
|
|
87
87
|
root?: IdmlTextNode;
|
|
88
88
|
frame?: IdmlFramePreference;
|
|
89
89
|
}
|
|
90
|
+
export interface IdmlAnchoredFrame {
|
|
91
|
+
story: string;
|
|
92
|
+
location: string;
|
|
93
|
+
width?: number;
|
|
94
|
+
position: string;
|
|
95
|
+
anchorYoffset?: number;
|
|
96
|
+
fill?: string;
|
|
97
|
+
stroke?: {
|
|
98
|
+
color: string;
|
|
99
|
+
weight: number;
|
|
100
|
+
};
|
|
101
|
+
corners?: {
|
|
102
|
+
topLeft?: number;
|
|
103
|
+
topRight?: number;
|
|
104
|
+
bottomLeft?: number;
|
|
105
|
+
bottomRight?: number;
|
|
106
|
+
};
|
|
107
|
+
}
|
|
90
108
|
export interface IdmlTextVariable {
|
|
91
109
|
id: string;
|
|
92
110
|
name: string;
|
|
@@ -111,6 +129,7 @@ export interface IdmlDocumentPreferences {
|
|
|
111
129
|
export interface IdmlPage {
|
|
112
130
|
id: string;
|
|
113
131
|
appliedMaster?: string;
|
|
132
|
+
showMasterItems?: boolean;
|
|
114
133
|
stories: string[];
|
|
115
134
|
side?: 'left' | 'right' | 'single';
|
|
116
135
|
bodyFrames?: IdmlFramePlacement[];
|
|
@@ -140,6 +159,7 @@ export interface IdmlMasterSpread {
|
|
|
140
159
|
id: string;
|
|
141
160
|
name: string;
|
|
142
161
|
basedOn?: string;
|
|
162
|
+
showMasterItems?: boolean;
|
|
143
163
|
pages: IdmlMasterPage[];
|
|
144
164
|
unmappedItems: {
|
|
145
165
|
type: string;
|
|
@@ -39,6 +39,7 @@ const MAPPED_ELEMENTS = /* @__PURE__ */ new Set([
|
|
|
39
39
|
"CharacterStyleGroup",
|
|
40
40
|
"ParagraphStyle",
|
|
41
41
|
"CharacterStyle",
|
|
42
|
+
"AnchoredObjectSetting",
|
|
42
43
|
"Color",
|
|
43
44
|
"TextVariable",
|
|
44
45
|
"MatchCharacterStylePreference",
|
|
@@ -48,7 +49,7 @@ function insideMappedResource(element) {
|
|
|
48
49
|
let parent = element.parent;
|
|
49
50
|
while (parent && "name" in parent) {
|
|
50
51
|
const name = localName(parent.name);
|
|
51
|
-
if (name === "ParagraphStyle" || name === "CharacterStyle" || name === "Color") return true;
|
|
52
|
+
if (name === "ParagraphStyle" || name === "CharacterStyle" || name === "ObjectStyle" || name === "Color") return true;
|
|
52
53
|
parent = parent.parent;
|
|
53
54
|
}
|
|
54
55
|
return false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@segnavia/idml",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@segnavia/format": "0.
|
|
30
|
-
"@segnavia/html": "0.
|
|
29
|
+
"@segnavia/format": "0.34.0",
|
|
30
|
+
"@segnavia/html": "0.34.0",
|
|
31
31
|
"dom-serializer": "^2.0.0",
|
|
32
32
|
"domhandler": "^5.0.3",
|
|
33
33
|
"htmlparser2": "^10.0.0"
|