@hirokisakabe/pom 5.1.0 → 5.2.1
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 +10 -11
- package/dist/autoFit/autoFit.d.ts +2 -1
- package/dist/autoFit/autoFit.d.ts.map +1 -1
- package/dist/autoFit/autoFit.js +7 -7
- package/dist/autoFit/strategies/reduceFontSize.js +1 -1
- package/dist/autoFit/strategies/reduceGapAndPadding.js +1 -1
- package/dist/autoFit/strategies/reduceTableRowHeight.js +1 -1
- package/dist/autoFit/strategies/uniformScale.js +1 -1
- package/dist/buildContext.d.ts +12 -0
- package/dist/buildContext.d.ts.map +1 -0
- package/dist/buildContext.js +8 -0
- package/dist/buildPptx.d.ts +1 -1
- package/dist/buildPptx.d.ts.map +1 -1
- package/dist/buildPptx.js +15 -15
- package/dist/calcYogaLayout/calcYogaLayout.d.ts +3 -1
- package/dist/calcYogaLayout/calcYogaLayout.d.ts.map +1 -1
- package/dist/calcYogaLayout/calcYogaLayout.js +85 -341
- package/dist/calcYogaLayout/measureText.d.ts +1 -5
- package/dist/calcYogaLayout/measureText.d.ts.map +1 -1
- package/dist/calcYogaLayout/measureText.js +2 -10
- package/dist/icons/renderIcon.d.ts +1 -1
- package/dist/icons/renderIcon.d.ts.map +1 -1
- package/dist/icons/renderIcon.js +3 -4
- package/dist/parseXml/coercionRules.d.ts +35 -0
- package/dist/parseXml/coercionRules.d.ts.map +1 -0
- package/dist/parseXml/coercionRules.js +477 -0
- package/dist/parseXml/inputSchema.d.ts +326 -64
- package/dist/parseXml/inputSchema.d.ts.map +1 -1
- package/dist/parseXml/inputSchema.js +13 -3
- package/dist/parseXml/parseXml.d.ts.map +1 -1
- package/dist/parseXml/parseXml.js +40 -270
- package/dist/registry/definitions/box.d.ts +3 -0
- package/dist/registry/definitions/box.d.ts.map +1 -0
- package/dist/registry/definitions/box.js +6 -0
- package/dist/registry/definitions/chart.d.ts +3 -0
- package/dist/registry/definitions/chart.d.ts.map +1 -0
- package/dist/registry/definitions/chart.js +8 -0
- package/dist/registry/definitions/compositeNodes.d.ts +8 -0
- package/dist/registry/definitions/compositeNodes.d.ts.map +1 -0
- package/dist/registry/definitions/compositeNodes.js +81 -0
- package/dist/registry/definitions/icon.d.ts +3 -0
- package/dist/registry/definitions/icon.d.ts.map +1 -0
- package/dist/registry/definitions/icon.js +28 -0
- package/dist/registry/definitions/image.d.ts +3 -0
- package/dist/registry/definitions/image.d.ts.map +1 -0
- package/dist/registry/definitions/image.js +34 -0
- package/dist/registry/definitions/layer.d.ts +3 -0
- package/dist/registry/definitions/layer.d.ts.map +1 -0
- package/dist/registry/definitions/layer.js +49 -0
- package/dist/registry/definitions/line.d.ts +3 -0
- package/dist/registry/definitions/line.d.ts.map +1 -0
- package/dist/registry/definitions/line.js +26 -0
- package/dist/registry/definitions/list.d.ts +4 -0
- package/dist/registry/definitions/list.d.ts.map +1 -0
- package/dist/registry/definitions/list.js +53 -0
- package/dist/registry/definitions/shape.d.ts +3 -0
- package/dist/registry/definitions/shape.d.ts.map +1 -0
- package/dist/registry/definitions/shape.js +37 -0
- package/dist/registry/definitions/stack.d.ts +4 -0
- package/dist/registry/definitions/stack.d.ts.map +1 -0
- package/dist/registry/definitions/stack.js +78 -0
- package/dist/registry/definitions/table.d.ts +3 -0
- package/dist/registry/definitions/table.d.ts.map +1 -0
- package/dist/registry/definitions/table.js +16 -0
- package/dist/registry/definitions/text.d.ts +3 -0
- package/dist/registry/definitions/text.d.ts.map +1 -0
- package/dist/registry/definitions/text.js +35 -0
- package/dist/registry/index.d.ts +2 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +34 -0
- package/dist/registry/nodeRegistry.d.ts +7 -0
- package/dist/registry/nodeRegistry.d.ts.map +1 -0
- package/dist/registry/nodeRegistry.js +13 -0
- package/dist/registry/types.d.ts +26 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +1 -0
- package/dist/renderPptx/renderPptx.d.ts +2 -1
- package/dist/renderPptx/renderPptx.d.ts.map +1 -1
- package/dist/renderPptx/renderPptx.js +30 -61
- package/dist/renderPptx/types.d.ts +2 -0
- package/dist/renderPptx/types.d.ts.map +1 -1
- package/dist/renderPptx/utils/backgroundBorder.d.ts.map +1 -1
- package/dist/renderPptx/utils/backgroundBorder.js +1 -1
- package/dist/shared/freeYogaTree.d.ts.map +1 -0
- package/dist/shared/measureImage.d.ts +13 -3
- package/dist/shared/measureImage.d.ts.map +1 -1
- package/dist/shared/measureImage.js +14 -19
- package/dist/shared/walkTree.d.ts.map +1 -0
- package/dist/toPositioned/toPositioned.d.ts +8 -1
- package/dist/toPositioned/toPositioned.d.ts.map +1 -1
- package/dist/toPositioned/toPositioned.js +32 -189
- package/dist/types.d.ts +371 -37
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +20 -1
- package/package.json +3 -3
- package/dist/autoFit/freeYogaTree.d.ts.map +0 -1
- package/dist/autoFit/walkTree.d.ts.map +0 -1
- package/dist/renderPptx/nodes/index.d.ts +0 -15
- package/dist/renderPptx/nodes/index.d.ts.map +0 -1
- package/dist/renderPptx/nodes/index.js +0 -14
- /package/dist/{autoFit → shared}/freeYogaTree.d.ts +0 -0
- /package/dist/{autoFit → shared}/freeYogaTree.js +0 -0
- /package/dist/{autoFit → shared}/walkTree.d.ts +0 -0
- /package/dist/{autoFit → shared}/walkTree.js +0 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { XMLParser } from "fast-xml-parser";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { alignItemsSchema, justifyContentSchema, shadowStyleSchema, processArrowStepSchema, pyramidLevelSchema, timelineItemSchema, matrixAxisSchema, matrixQuadrantsSchema, matrixItemSchema, flowNodeItemSchema, flowConnectionSchema, chartDataSchema, tableColumnSchema, tableCellSchema, } from "../types.js";
|
|
2
|
+
import { inputTextNodeSchema, inputUlNodeSchema, inputOlNodeSchema, inputImageNodeSchema, inputTableNodeSchema, inputShapeNodeSchema, inputChartNodeSchema, inputTimelineNodeSchema, inputMatrixNodeSchema, inputTreeNodeSchema, inputFlowNodeSchema, inputProcessArrowNodeSchema, inputPyramidNodeSchema, inputLineNodeSchema, inputIconNodeSchema, } from "./inputSchema.js";
|
|
3
|
+
import { NODE_COERCION_MAP, CHILD_ELEMENT_COERCION_MAP, coerceWithRule, coerceFallback, getObjectShapeFromRule, isBooleanObjectUnionRule, } from "./coercionRules.js";
|
|
5
4
|
// ===== ParseXmlError =====
|
|
6
5
|
export class ParseXmlError extends Error {
|
|
7
6
|
errors;
|
|
@@ -36,52 +35,16 @@ const TAG_TO_TYPE = {
|
|
|
36
35
|
};
|
|
37
36
|
// Reverse mapping: node type → tag name
|
|
38
37
|
const TYPE_TO_TAG = Object.fromEntries(Object.entries(TAG_TO_TYPE).map(([tag, type]) => [type, tag]));
|
|
39
|
-
function extractShape(schema) {
|
|
40
|
-
return schema.shape;
|
|
41
|
-
}
|
|
42
|
-
const leafNodeShapes = {
|
|
43
|
-
text: extractShape(inputTextNodeSchema),
|
|
44
|
-
image: extractShape(inputImageNodeSchema),
|
|
45
|
-
table: extractShape(inputTableNodeSchema),
|
|
46
|
-
shape: extractShape(inputShapeNodeSchema),
|
|
47
|
-
chart: extractShape(inputChartNodeSchema),
|
|
48
|
-
timeline: extractShape(inputTimelineNodeSchema),
|
|
49
|
-
matrix: extractShape(inputMatrixNodeSchema),
|
|
50
|
-
tree: extractShape(inputTreeNodeSchema),
|
|
51
|
-
flow: extractShape(inputFlowNodeSchema),
|
|
52
|
-
processArrow: extractShape(inputProcessArrowNodeSchema),
|
|
53
|
-
pyramid: extractShape(inputPyramidNodeSchema),
|
|
54
|
-
line: extractShape(inputLineNodeSchema),
|
|
55
|
-
ul: extractShape(inputUlNodeSchema),
|
|
56
|
-
ol: extractShape(inputOlNodeSchema),
|
|
57
|
-
icon: extractShape(inputIconNodeSchema),
|
|
58
|
-
};
|
|
59
|
-
const containerShapes = {
|
|
60
|
-
box: extractShape(inputBaseNodeSchema.extend({ shadow: shadowStyleSchema.optional() })),
|
|
61
|
-
vstack: extractShape(inputBaseNodeSchema.extend({
|
|
62
|
-
gap: z.number().optional(),
|
|
63
|
-
alignItems: alignItemsSchema.optional(),
|
|
64
|
-
justifyContent: justifyContentSchema.optional(),
|
|
65
|
-
shadow: shadowStyleSchema.optional(),
|
|
66
|
-
})),
|
|
67
|
-
hstack: extractShape(inputBaseNodeSchema.extend({
|
|
68
|
-
gap: z.number().optional(),
|
|
69
|
-
alignItems: alignItemsSchema.optional(),
|
|
70
|
-
justifyContent: justifyContentSchema.optional(),
|
|
71
|
-
shadow: shadowStyleSchema.optional(),
|
|
72
|
-
})),
|
|
73
|
-
layer: extractShape(inputBaseNodeSchema),
|
|
74
|
-
};
|
|
75
38
|
const CONTAINER_TYPES = new Set(["box", "vstack", "hstack", "layer"]);
|
|
76
39
|
const TEXT_CONTENT_NODES = new Set(["text", "shape"]);
|
|
77
40
|
// Attributes allowed on any node (e.g., x/y for Layer children positioning)
|
|
78
41
|
const UNIVERSAL_ATTRS = new Set(["x", "y"]);
|
|
79
42
|
// ===== Validation helpers =====
|
|
80
43
|
function getKnownAttributes(nodeType) {
|
|
81
|
-
const
|
|
82
|
-
if (!
|
|
44
|
+
const rules = NODE_COERCION_MAP[nodeType];
|
|
45
|
+
if (!rules)
|
|
83
46
|
return [];
|
|
84
|
-
return Object.keys(
|
|
47
|
+
return Object.keys(rules);
|
|
85
48
|
}
|
|
86
49
|
function levenshteinDistance(a, b) {
|
|
87
50
|
const m = a.length;
|
|
@@ -115,10 +78,10 @@ function findClosestMatch(input, candidates) {
|
|
|
115
78
|
return bestMatch;
|
|
116
79
|
}
|
|
117
80
|
function getKnownChildAttributes(tagName) {
|
|
118
|
-
const
|
|
119
|
-
if (!
|
|
81
|
+
const rules = CHILD_ELEMENT_COERCION_MAP[tagName];
|
|
82
|
+
if (!rules)
|
|
120
83
|
return [];
|
|
121
|
-
return Object.keys(
|
|
84
|
+
return Object.keys(rules);
|
|
122
85
|
}
|
|
123
86
|
// ===== Leaf node Zod validation schemas =====
|
|
124
87
|
const leafNodeValidationSchemas = {
|
|
@@ -229,165 +192,11 @@ function validateLeafNode(nodeType, result, errors) {
|
|
|
229
192
|
}
|
|
230
193
|
}
|
|
231
194
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
function getPropertySchema(nodeType, propertyName) {
|
|
236
|
-
const shape = leafNodeShapes[nodeType] ?? containerShapes[nodeType];
|
|
237
|
-
if (!shape)
|
|
238
|
-
return undefined;
|
|
239
|
-
return shape[propertyName];
|
|
240
|
-
}
|
|
241
|
-
function getZodType(schema) {
|
|
242
|
-
const def = getDef(schema);
|
|
243
|
-
return (def.type ?? def.typeName ?? "");
|
|
244
|
-
}
|
|
245
|
-
function unwrapSchema(schema) {
|
|
246
|
-
const typeName = getZodType(schema);
|
|
247
|
-
const def = getDef(schema);
|
|
248
|
-
switch (typeName) {
|
|
249
|
-
case "optional":
|
|
250
|
-
case "default":
|
|
251
|
-
case "nullable":
|
|
252
|
-
return unwrapSchema(def.innerType);
|
|
253
|
-
case "lazy":
|
|
254
|
-
return unwrapSchema(def.getter());
|
|
255
|
-
case "pipe":
|
|
256
|
-
return unwrapSchema(def.in);
|
|
257
|
-
default:
|
|
258
|
-
return schema;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
function resolveZodTypeName(schema) {
|
|
262
|
-
return getZodType(unwrapSchema(schema));
|
|
263
|
-
}
|
|
264
|
-
// ===== Value coercion =====
|
|
265
|
-
// Returns { value, error } — if error is non-null, coercion failed.
|
|
266
|
-
function coerceValue(value, schema) {
|
|
267
|
-
const unwrapped = unwrapSchema(schema);
|
|
268
|
-
const typeName = getZodType(unwrapped);
|
|
269
|
-
const def = getDef(unwrapped);
|
|
270
|
-
switch (typeName) {
|
|
271
|
-
case "number": {
|
|
272
|
-
const num = Number(value);
|
|
273
|
-
if (isNaN(num)) {
|
|
274
|
-
return {
|
|
275
|
-
value: undefined,
|
|
276
|
-
error: `Cannot convert "${value}" to number`,
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
return { value: num, error: null };
|
|
280
|
-
}
|
|
281
|
-
case "boolean":
|
|
282
|
-
if (value !== "true" && value !== "false") {
|
|
283
|
-
return {
|
|
284
|
-
value: undefined,
|
|
285
|
-
error: `Cannot convert "${value}" to boolean (expected "true" or "false")`,
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
return { value: value === "true", error: null };
|
|
289
|
-
case "string":
|
|
290
|
-
case "enum":
|
|
291
|
-
return { value, error: null };
|
|
292
|
-
case "literal": {
|
|
293
|
-
const values = def.values;
|
|
294
|
-
const singleValue = def.value;
|
|
295
|
-
return { value: values?.[0] ?? singleValue, error: null };
|
|
296
|
-
}
|
|
297
|
-
case "array":
|
|
298
|
-
case "object":
|
|
299
|
-
case "record":
|
|
300
|
-
case "tuple":
|
|
301
|
-
try {
|
|
302
|
-
return { value: JSON.parse(value), error: null };
|
|
303
|
-
}
|
|
304
|
-
catch {
|
|
305
|
-
return {
|
|
306
|
-
value: undefined,
|
|
307
|
-
error: `Cannot parse JSON value: "${value}"`,
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
case "union": {
|
|
311
|
-
const options = def.options;
|
|
312
|
-
return { value: coerceUnionValue(value, options), error: null };
|
|
313
|
-
}
|
|
314
|
-
default:
|
|
315
|
-
return { value: coerceFallback(value), error: null };
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
function coerceUnionValue(value, options) {
|
|
319
|
-
const typeNames = options.map((opt) => resolveZodTypeName(opt));
|
|
320
|
-
// Try boolean
|
|
321
|
-
if ((value === "true" || value === "false") &&
|
|
322
|
-
typeNames.includes("boolean")) {
|
|
323
|
-
return value === "true";
|
|
324
|
-
}
|
|
325
|
-
// Try number
|
|
326
|
-
if (typeNames.includes("number")) {
|
|
327
|
-
const num = Number(value);
|
|
328
|
-
if (!isNaN(num) && value !== "") {
|
|
329
|
-
return num;
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
// Try literal
|
|
333
|
-
for (let i = 0; i < options.length; i++) {
|
|
334
|
-
if (typeNames[i] === "literal") {
|
|
335
|
-
const unwrapped = unwrapSchema(options[i]);
|
|
336
|
-
const def = getDef(unwrapped);
|
|
337
|
-
const values = def.values;
|
|
338
|
-
const singleValue = def.value;
|
|
339
|
-
const litVal = values?.[0] ?? singleValue;
|
|
340
|
-
if (litVal != null && `${litVal}` === value)
|
|
341
|
-
return litVal;
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
// Try JSON parse for objects/arrays
|
|
345
|
-
if (typeNames.some((t) => ["array", "object", "record", "tuple"].includes(t))) {
|
|
346
|
-
if (value.startsWith("{") || value.startsWith("[")) {
|
|
347
|
-
try {
|
|
348
|
-
return JSON.parse(value);
|
|
349
|
-
}
|
|
350
|
-
catch {
|
|
351
|
-
/* ignore */
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
// Fallback to string
|
|
356
|
-
return value;
|
|
357
|
-
}
|
|
358
|
-
function coerceFallback(value) {
|
|
359
|
-
if (value === "true")
|
|
360
|
-
return true;
|
|
361
|
-
if (value === "false")
|
|
362
|
-
return false;
|
|
363
|
-
const num = Number(value);
|
|
364
|
-
if (value !== "" && !isNaN(num))
|
|
365
|
-
return num;
|
|
366
|
-
if (value.startsWith("{") || value.startsWith("[")) {
|
|
367
|
-
try {
|
|
368
|
-
return JSON.parse(value);
|
|
369
|
-
}
|
|
370
|
-
catch {
|
|
371
|
-
/* ignore */
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
return value;
|
|
195
|
+
// ===== Coercion rule lookup =====
|
|
196
|
+
function getCoercionRule(nodeType, propertyName) {
|
|
197
|
+
return NODE_COERCION_MAP[nodeType]?.[propertyName];
|
|
375
198
|
}
|
|
376
199
|
// ===== Dot notation helpers =====
|
|
377
|
-
/**
|
|
378
|
-
* Checks if a schema is a union containing both boolean and object types.
|
|
379
|
-
* Used to allow `endArrow="true" endArrow.type="triangle"` coexistence.
|
|
380
|
-
*/
|
|
381
|
-
function isBooleanObjectUnion(schema) {
|
|
382
|
-
const unwrapped = unwrapSchema(schema);
|
|
383
|
-
const typeName = getZodType(unwrapped);
|
|
384
|
-
if (typeName !== "union")
|
|
385
|
-
return false;
|
|
386
|
-
const def = getDef(unwrapped);
|
|
387
|
-
const options = def.options;
|
|
388
|
-
const typeNames = options.map((opt) => getZodType(unwrapSchema(opt)));
|
|
389
|
-
return typeNames.includes("boolean") && typeNames.includes("object");
|
|
390
|
-
}
|
|
391
200
|
// ===== Dot notation expansion =====
|
|
392
201
|
function expandDotNotation(attrs) {
|
|
393
202
|
const regular = {};
|
|
@@ -407,26 +216,13 @@ function expandDotNotation(attrs) {
|
|
|
407
216
|
}
|
|
408
217
|
return { regular, dotGroups };
|
|
409
218
|
}
|
|
410
|
-
function coerceDotGroup(prefix, subAttrs,
|
|
411
|
-
const
|
|
412
|
-
const typeName = getZodType(unwrapped);
|
|
413
|
-
let objectSchema;
|
|
414
|
-
if (typeName === "object") {
|
|
415
|
-
objectSchema = unwrapped;
|
|
416
|
-
}
|
|
417
|
-
else if (typeName === "union") {
|
|
418
|
-
const def = getDef(unwrapped);
|
|
419
|
-
const options = def.options;
|
|
420
|
-
objectSchema = options.find((opt) => getZodType(unwrapSchema(opt)) === "object");
|
|
421
|
-
if (objectSchema)
|
|
422
|
-
objectSchema = unwrapSchema(objectSchema);
|
|
423
|
-
}
|
|
219
|
+
function coerceDotGroup(prefix, subAttrs, rule, tagName, errors) {
|
|
220
|
+
const objectShape = getObjectShapeFromRule(rule);
|
|
424
221
|
const obj = {};
|
|
425
|
-
if (
|
|
426
|
-
const shape = extractShape(objectSchema);
|
|
222
|
+
if (objectShape) {
|
|
427
223
|
for (const [subKey, subValue] of Object.entries(subAttrs)) {
|
|
428
|
-
if (
|
|
429
|
-
const coerced =
|
|
224
|
+
if (objectShape[subKey]) {
|
|
225
|
+
const coerced = coerceWithRule(subValue, objectShape[subKey]);
|
|
430
226
|
if (coerced.error !== null) {
|
|
431
227
|
errors.push(`<${tagName}>: ${prefix}.${subKey}: ${coerced.error}`);
|
|
432
228
|
}
|
|
@@ -435,7 +231,7 @@ function coerceDotGroup(prefix, subAttrs, schema, tagName, errors) {
|
|
|
435
231
|
}
|
|
436
232
|
}
|
|
437
233
|
else {
|
|
438
|
-
const knownSubKeys = Object.keys(
|
|
234
|
+
const knownSubKeys = Object.keys(objectShape);
|
|
439
235
|
const suggestion = findClosestMatch(subKey, knownSubKeys);
|
|
440
236
|
errors.push(`<${tagName}>: Unknown sub-attribute "${prefix}.${subKey}"${suggestion ? `. Did you mean "${prefix}.${suggestion}"?` : ""}`);
|
|
441
237
|
}
|
|
@@ -488,30 +284,16 @@ function getTextContent(node) {
|
|
|
488
284
|
}
|
|
489
285
|
return textParts.length > 0 ? textParts.join("") : undefined;
|
|
490
286
|
}
|
|
491
|
-
// ===== Child element schemas for type coercion =====
|
|
492
|
-
const childElementShapes = {
|
|
493
|
-
ProcessArrowStep: extractShape(processArrowStepSchema),
|
|
494
|
-
PyramidLevel: extractShape(pyramidLevelSchema),
|
|
495
|
-
TimelineItem: extractShape(timelineItemSchema),
|
|
496
|
-
MatrixAxes: extractShape(matrixAxisSchema),
|
|
497
|
-
MatrixQuadrants: extractShape(matrixQuadrantsSchema),
|
|
498
|
-
MatrixItem: extractShape(matrixItemSchema),
|
|
499
|
-
FlowNode: extractShape(flowNodeItemSchema),
|
|
500
|
-
FlowConnection: extractShape(flowConnectionSchema),
|
|
501
|
-
TableColumn: extractShape(tableColumnSchema),
|
|
502
|
-
TableCell: extractShape(tableCellSchema),
|
|
503
|
-
Li: extractShape(inputLiNodeSchema),
|
|
504
|
-
};
|
|
505
287
|
function coerceChildAttrs(parentTagName, tagName, attrs, errors) {
|
|
506
|
-
const
|
|
288
|
+
const rules = CHILD_ELEMENT_COERCION_MAP[tagName];
|
|
507
289
|
const result = {};
|
|
508
290
|
const { regular: regularAttrs, dotGroups } = expandDotNotation(attrs);
|
|
509
291
|
// Process dot-notation attributes
|
|
510
292
|
for (const [prefix, subAttrs] of Object.entries(dotGroups)) {
|
|
511
|
-
if (
|
|
512
|
-
result[prefix] = coerceDotGroup(prefix, subAttrs,
|
|
293
|
+
if (rules && rules[prefix]) {
|
|
294
|
+
result[prefix] = coerceDotGroup(prefix, subAttrs, rules[prefix], `${parentTagName}.${tagName}`, errors);
|
|
513
295
|
}
|
|
514
|
-
else if (
|
|
296
|
+
else if (rules) {
|
|
515
297
|
const knownAttrs = getKnownChildAttributes(tagName);
|
|
516
298
|
const suggestion = findClosestMatch(prefix, knownAttrs);
|
|
517
299
|
errors.push(`<${parentTagName}>.<${tagName}>: Unknown attribute "${prefix}"${suggestion ? `. Did you mean "${suggestion}"?` : ""}`);
|
|
@@ -527,11 +309,11 @@ function coerceChildAttrs(parentTagName, tagName, attrs, errors) {
|
|
|
527
309
|
// Process regular attributes
|
|
528
310
|
for (const [key, value] of Object.entries(regularAttrs)) {
|
|
529
311
|
if (key in dotGroups) {
|
|
530
|
-
// When the
|
|
312
|
+
// When the rule is a union of boolean and object,
|
|
531
313
|
// allow boolean shorthand to coexist with dot-notation by ignoring the boolean value.
|
|
532
|
-
if (
|
|
533
|
-
|
|
534
|
-
|
|
314
|
+
if (rules &&
|
|
315
|
+
rules[key] &&
|
|
316
|
+
isBooleanObjectUnionRule(rules[key]) &&
|
|
535
317
|
(value === "true" || value === "false")) {
|
|
536
318
|
// Silently skip the boolean value; dot-notation takes priority
|
|
537
319
|
continue;
|
|
@@ -539,8 +321,8 @@ function coerceChildAttrs(parentTagName, tagName, attrs, errors) {
|
|
|
539
321
|
errors.push(`<${parentTagName}>.<${tagName}>: Attribute "${key}" conflicts with dot-notation attributes. Use one or the other, not both`);
|
|
540
322
|
continue;
|
|
541
323
|
}
|
|
542
|
-
if (
|
|
543
|
-
const coerced =
|
|
324
|
+
if (rules && rules[key]) {
|
|
325
|
+
const coerced = coerceWithRule(value, rules[key]);
|
|
544
326
|
if (coerced.error !== null) {
|
|
545
327
|
errors.push(`<${parentTagName}>.<${tagName}>: ${coerced.error}`);
|
|
546
328
|
}
|
|
@@ -548,7 +330,7 @@ function coerceChildAttrs(parentTagName, tagName, attrs, errors) {
|
|
|
548
330
|
result[key] = coerced.value;
|
|
549
331
|
}
|
|
550
332
|
}
|
|
551
|
-
else if (
|
|
333
|
+
else if (rules) {
|
|
552
334
|
// Unknown attribute on child element
|
|
553
335
|
const knownAttrs = getKnownChildAttributes(tagName);
|
|
554
336
|
const suggestion = findClosestMatch(key, knownAttrs);
|
|
@@ -642,7 +424,6 @@ function convertFlowChildren(childElements, result, errors) {
|
|
|
642
424
|
}
|
|
643
425
|
}
|
|
644
426
|
function convertChartChildren(childElements, result, errors) {
|
|
645
|
-
const dataShape = extractShape(chartDataSchema);
|
|
646
427
|
const data = [];
|
|
647
428
|
for (const child of childElements) {
|
|
648
429
|
const tag = getTagName(child);
|
|
@@ -656,19 +437,8 @@ function convertChartChildren(childElements, result, errors) {
|
|
|
656
437
|
values: [],
|
|
657
438
|
};
|
|
658
439
|
if (attrs.name !== undefined) {
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
const coerced = coerceValue(attrs.name, nameSchema);
|
|
662
|
-
if (coerced.error !== null) {
|
|
663
|
-
errors.push(`<Chart>.<ChartSeries>: ${coerced.error}`);
|
|
664
|
-
}
|
|
665
|
-
else {
|
|
666
|
-
series.name = coerced.value;
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
else {
|
|
670
|
-
series.name = attrs.name;
|
|
671
|
-
}
|
|
440
|
+
// chartDataSchema.name は z.string().optional() なのでそのまま文字列として使用
|
|
441
|
+
series.name = attrs.name;
|
|
672
442
|
}
|
|
673
443
|
for (const dp of getChildElements(child)) {
|
|
674
444
|
const dpTag = getTagName(dp);
|
|
@@ -838,9 +608,9 @@ function convertPomNode(nodeType, tagName, attrs, childElements, textContent, er
|
|
|
838
608
|
for (const [prefix, subAttrs] of Object.entries(dotGroups)) {
|
|
839
609
|
if (prefix === "type")
|
|
840
610
|
continue;
|
|
841
|
-
const
|
|
842
|
-
if (
|
|
843
|
-
result[prefix] = coerceDotGroup(prefix, subAttrs,
|
|
611
|
+
const rule = getCoercionRule(nodeType, prefix);
|
|
612
|
+
if (rule) {
|
|
613
|
+
result[prefix] = coerceDotGroup(prefix, subAttrs, rule, tagName, errors);
|
|
844
614
|
}
|
|
845
615
|
else {
|
|
846
616
|
const knownAttrs = getKnownAttributes(nodeType);
|
|
@@ -858,11 +628,11 @@ function convertPomNode(nodeType, tagName, attrs, childElements, textContent, er
|
|
|
858
628
|
continue;
|
|
859
629
|
// Conflict check: dot-notation and regular attribute for the same key
|
|
860
630
|
if (key in dotGroups) {
|
|
861
|
-
// When the
|
|
631
|
+
// When the rule is a union of boolean and object (e.g., endArrow),
|
|
862
632
|
// allow boolean shorthand to coexist with dot-notation by ignoring the boolean value.
|
|
863
|
-
const
|
|
864
|
-
if (
|
|
865
|
-
|
|
633
|
+
const ruleForConflict = getCoercionRule(nodeType, key);
|
|
634
|
+
if (ruleForConflict &&
|
|
635
|
+
isBooleanObjectUnionRule(ruleForConflict) &&
|
|
866
636
|
(value === "true" || value === "false")) {
|
|
867
637
|
// Silently skip the boolean value; dot-notation takes priority
|
|
868
638
|
continue;
|
|
@@ -870,9 +640,9 @@ function convertPomNode(nodeType, tagName, attrs, childElements, textContent, er
|
|
|
870
640
|
errors.push(`<${tagName}>: Attribute "${key}" conflicts with dot-notation attributes (e.g., "${key}.xxx"). Use one or the other, not both`);
|
|
871
641
|
continue;
|
|
872
642
|
}
|
|
873
|
-
const
|
|
874
|
-
if (
|
|
875
|
-
const coerced =
|
|
643
|
+
const rule = getCoercionRule(nodeType, key);
|
|
644
|
+
if (rule) {
|
|
645
|
+
const coerced = coerceWithRule(value, rule);
|
|
876
646
|
if (coerced.error !== null) {
|
|
877
647
|
errors.push(`<${tagName}>: ${coerced.error}`);
|
|
878
648
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/box.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,eAAO,MAAM,UAAU,EAAE,cAKxB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/chart.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,eAAO,MAAM,YAAY,EAAE,cAM1B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { NodeDefinition } from "../types.ts";
|
|
2
|
+
export declare const timelineNodeDef: NodeDefinition;
|
|
3
|
+
export declare const matrixNodeDef: NodeDefinition;
|
|
4
|
+
export declare const treeNodeDef: NodeDefinition;
|
|
5
|
+
export declare const flowNodeDef: NodeDefinition;
|
|
6
|
+
export declare const processArrowNodeDef: NodeDefinition;
|
|
7
|
+
export declare const pyramidNodeDef: NodeDefinition;
|
|
8
|
+
//# sourceMappingURL=compositeNodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compositeNodes.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/compositeNodes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAQ,MAAM,aAAa,CAAC;AAqDxD,eAAO,MAAM,eAAe,EAAE,cAS7B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,cAS3B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,cASzB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,cASzB,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,cAYjC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,cAS5B,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { measureProcessArrow, measureTimeline, measureMatrix, measureTree, measureFlow, measurePyramid, } from "../../calcYogaLayout/measureCompositeNodes.js";
|
|
2
|
+
import { renderTimelineNode } from "../../renderPptx/nodes/timeline.js";
|
|
3
|
+
import { renderMatrixNode } from "../../renderPptx/nodes/matrix.js";
|
|
4
|
+
import { renderTreeNode } from "../../renderPptx/nodes/tree.js";
|
|
5
|
+
import { renderFlowNode } from "../../renderPptx/nodes/flow.js";
|
|
6
|
+
import { renderProcessArrowNode } from "../../renderPptx/nodes/processArrow.js";
|
|
7
|
+
import { renderPyramidNode } from "../../renderPptx/nodes/pyramid.js";
|
|
8
|
+
/**
|
|
9
|
+
* コンポジットノードの最小スケール閾値。
|
|
10
|
+
* renderPptx/utils/scaleToFit.ts の MIN_SCALE_THRESHOLD と同じ値を維持すること。
|
|
11
|
+
*/
|
|
12
|
+
const MIN_SCALE_THRESHOLD = 0.5;
|
|
13
|
+
/** 制約付きサイズを閾値でクランプする */
|
|
14
|
+
function constrainWithMinScale(intrinsicSize, availableSize) {
|
|
15
|
+
const minSize = intrinsicSize * MIN_SCALE_THRESHOLD;
|
|
16
|
+
return Math.max(minSize, Math.min(intrinsicSize, availableSize));
|
|
17
|
+
}
|
|
18
|
+
/** コンポジットノード共通の measureFunc セットアップ */
|
|
19
|
+
function applyCompositeMeasure(measureFn) {
|
|
20
|
+
return (node, yn, yoga) => {
|
|
21
|
+
yn.setMeasureFunc((width, widthMode, height, heightMode) => {
|
|
22
|
+
const intrinsic = measureFn(node);
|
|
23
|
+
return {
|
|
24
|
+
width: widthMode !== yoga.MEASURE_MODE_UNDEFINED
|
|
25
|
+
? constrainWithMinScale(intrinsic.width, width)
|
|
26
|
+
: intrinsic.width,
|
|
27
|
+
height: heightMode !== yoga.MEASURE_MODE_UNDEFINED
|
|
28
|
+
? constrainWithMinScale(intrinsic.height, height)
|
|
29
|
+
: intrinsic.height,
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export const timelineNodeDef = {
|
|
35
|
+
type: "timeline",
|
|
36
|
+
category: "leaf",
|
|
37
|
+
applyYogaStyle: applyCompositeMeasure(measureTimeline),
|
|
38
|
+
render(node, ctx) {
|
|
39
|
+
renderTimelineNode(node, ctx);
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
export const matrixNodeDef = {
|
|
43
|
+
type: "matrix",
|
|
44
|
+
category: "leaf",
|
|
45
|
+
applyYogaStyle: applyCompositeMeasure(measureMatrix),
|
|
46
|
+
render(node, ctx) {
|
|
47
|
+
renderMatrixNode(node, ctx);
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
export const treeNodeDef = {
|
|
51
|
+
type: "tree",
|
|
52
|
+
category: "leaf",
|
|
53
|
+
applyYogaStyle: applyCompositeMeasure(measureTree),
|
|
54
|
+
render(node, ctx) {
|
|
55
|
+
renderTreeNode(node, ctx);
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
export const flowNodeDef = {
|
|
59
|
+
type: "flow",
|
|
60
|
+
category: "leaf",
|
|
61
|
+
applyYogaStyle: applyCompositeMeasure(measureFlow),
|
|
62
|
+
render(node, ctx) {
|
|
63
|
+
renderFlowNode(node, ctx);
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
export const processArrowNodeDef = {
|
|
67
|
+
type: "processArrow",
|
|
68
|
+
category: "leaf",
|
|
69
|
+
applyYogaStyle: applyCompositeMeasure(measureProcessArrow),
|
|
70
|
+
render(node, ctx) {
|
|
71
|
+
renderProcessArrowNode(node, ctx);
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
export const pyramidNodeDef = {
|
|
75
|
+
type: "pyramid",
|
|
76
|
+
category: "leaf",
|
|
77
|
+
applyYogaStyle: applyCompositeMeasure(measurePyramid),
|
|
78
|
+
render(node, ctx) {
|
|
79
|
+
renderPyramidNode(node, ctx);
|
|
80
|
+
},
|
|
81
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/icon.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD,eAAO,MAAM,WAAW,EAAE,cAiCzB,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { rasterizeIcon } from "../../icons/index.js";
|
|
2
|
+
import { omitYogaNode } from "../../toPositioned/toPositioned.js";
|
|
3
|
+
import { renderIconNode } from "../../renderPptx/nodes/icon.js";
|
|
4
|
+
export const iconNodeDef = {
|
|
5
|
+
type: "icon",
|
|
6
|
+
category: "leaf",
|
|
7
|
+
applyYogaStyle(node, yn) {
|
|
8
|
+
const n = node;
|
|
9
|
+
const size = n.size ?? 24;
|
|
10
|
+
yn.setMeasureFunc(() => ({ width: size, height: size }));
|
|
11
|
+
},
|
|
12
|
+
toPositioned(pom, absoluteX, absoluteY, layout, ctx) {
|
|
13
|
+
const n = pom;
|
|
14
|
+
const rasterSize = Math.max(Math.ceil(layout.width), Math.ceil(layout.height), n.size ?? 24);
|
|
15
|
+
const iconImageData = rasterizeIcon(n.name, rasterSize, n.color ?? "#000000", ctx.iconRasterCache);
|
|
16
|
+
return {
|
|
17
|
+
...omitYogaNode(n),
|
|
18
|
+
x: absoluteX,
|
|
19
|
+
y: absoluteY,
|
|
20
|
+
w: layout.width,
|
|
21
|
+
h: layout.height,
|
|
22
|
+
iconImageData,
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
render(node, ctx) {
|
|
26
|
+
renderIconNode(node, ctx);
|
|
27
|
+
},
|
|
28
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/image.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAQ,MAAM,aAAa,CAAC;AAOxD,eAAO,MAAM,YAAY,EAAE,cA+B1B,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { measureImage, getImageData } from "../../shared/measureImage.js";
|
|
2
|
+
import { renderImageNode } from "../../renderPptx/nodes/image.js";
|
|
3
|
+
import { omitYogaNode } from "../../toPositioned/toPositioned.js";
|
|
4
|
+
export const imageNodeDef = {
|
|
5
|
+
type: "image",
|
|
6
|
+
category: "leaf",
|
|
7
|
+
applyYogaStyle(node, yn, _yoga, ctx) {
|
|
8
|
+
const n = node;
|
|
9
|
+
const src = n.src;
|
|
10
|
+
yn.setMeasureFunc(() => {
|
|
11
|
+
const { widthPx, heightPx } = measureImage(src, ctx.imageSizeCache);
|
|
12
|
+
return { width: widthPx, height: heightPx };
|
|
13
|
+
});
|
|
14
|
+
},
|
|
15
|
+
toPositioned(pom, absoluteX, absoluteY, layout, ctx) {
|
|
16
|
+
const n = pom;
|
|
17
|
+
const imageData = getImageData(n.src, ctx.imageDataCache);
|
|
18
|
+
return {
|
|
19
|
+
...omitYogaNode(n),
|
|
20
|
+
x: absoluteX,
|
|
21
|
+
y: absoluteY,
|
|
22
|
+
w: layout.width,
|
|
23
|
+
h: layout.height,
|
|
24
|
+
imageData,
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
render(node, ctx) {
|
|
28
|
+
renderImageNode(node, ctx);
|
|
29
|
+
},
|
|
30
|
+
collectImageSources(node) {
|
|
31
|
+
const n = node;
|
|
32
|
+
return [n.src];
|
|
33
|
+
},
|
|
34
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layer.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/layer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,eAAO,MAAM,YAAY,EAAE,cAwD1B,CAAC"}
|