@hirokisakabe/pom 5.2.0 → 5.3.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/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 +43 -371
- 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 +479 -0
- package/dist/parseXml/inputSchema.d.ts +22 -105
- package/dist/parseXml/inputSchema.d.ts.map +1 -1
- package/dist/parseXml/inputSchema.js +5 -3
- package/dist/parseXml/parseXml.d.ts.map +1 -1
- package/dist/parseXml/parseXml.js +48 -277
- 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 +50 -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/nodes/icon.d.ts.map +1 -1
- package/dist/renderPptx/nodes/icon.js +22 -4
- package/dist/renderPptx/renderPptx.d.ts +2 -1
- package/dist/renderPptx/renderPptx.d.ts.map +1 -1
- package/dist/renderPptx/renderPptx.js +19 -60
- 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 +38 -54
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +11 -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, flexWrapSchema, } 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,54 +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
|
-
flexWrap: flexWrapSchema.optional(),
|
|
67
|
-
})),
|
|
68
|
-
hstack: extractShape(inputBaseNodeSchema.extend({
|
|
69
|
-
gap: z.number().optional(),
|
|
70
|
-
alignItems: alignItemsSchema.optional(),
|
|
71
|
-
justifyContent: justifyContentSchema.optional(),
|
|
72
|
-
shadow: shadowStyleSchema.optional(),
|
|
73
|
-
flexWrap: flexWrapSchema.optional(),
|
|
74
|
-
})),
|
|
75
|
-
layer: extractShape(inputBaseNodeSchema),
|
|
76
|
-
};
|
|
77
38
|
const CONTAINER_TYPES = new Set(["box", "vstack", "hstack", "layer"]);
|
|
78
39
|
const TEXT_CONTENT_NODES = new Set(["text", "shape"]);
|
|
79
40
|
// Attributes allowed on any node (e.g., x/y for Layer children positioning)
|
|
80
41
|
const UNIVERSAL_ATTRS = new Set(["x", "y"]);
|
|
81
42
|
// ===== Validation helpers =====
|
|
82
43
|
function getKnownAttributes(nodeType) {
|
|
83
|
-
const
|
|
84
|
-
if (!
|
|
44
|
+
const rules = NODE_COERCION_MAP[nodeType];
|
|
45
|
+
if (!rules)
|
|
85
46
|
return [];
|
|
86
|
-
return Object.keys(
|
|
47
|
+
return Object.keys(rules);
|
|
87
48
|
}
|
|
88
49
|
function levenshteinDistance(a, b) {
|
|
89
50
|
const m = a.length;
|
|
@@ -117,10 +78,10 @@ function findClosestMatch(input, candidates) {
|
|
|
117
78
|
return bestMatch;
|
|
118
79
|
}
|
|
119
80
|
function getKnownChildAttributes(tagName) {
|
|
120
|
-
const
|
|
121
|
-
if (!
|
|
81
|
+
const rules = CHILD_ELEMENT_COERCION_MAP[tagName];
|
|
82
|
+
if (!rules)
|
|
122
83
|
return [];
|
|
123
|
-
return Object.keys(
|
|
84
|
+
return Object.keys(rules);
|
|
124
85
|
}
|
|
125
86
|
// ===== Leaf node Zod validation schemas =====
|
|
126
87
|
const leafNodeValidationSchemas = {
|
|
@@ -231,165 +192,11 @@ function validateLeafNode(nodeType, result, errors) {
|
|
|
231
192
|
}
|
|
232
193
|
}
|
|
233
194
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
function getPropertySchema(nodeType, propertyName) {
|
|
238
|
-
const shape = leafNodeShapes[nodeType] ?? containerShapes[nodeType];
|
|
239
|
-
if (!shape)
|
|
240
|
-
return undefined;
|
|
241
|
-
return shape[propertyName];
|
|
242
|
-
}
|
|
243
|
-
function getZodType(schema) {
|
|
244
|
-
const def = getDef(schema);
|
|
245
|
-
return (def.type ?? def.typeName ?? "");
|
|
246
|
-
}
|
|
247
|
-
function unwrapSchema(schema) {
|
|
248
|
-
const typeName = getZodType(schema);
|
|
249
|
-
const def = getDef(schema);
|
|
250
|
-
switch (typeName) {
|
|
251
|
-
case "optional":
|
|
252
|
-
case "default":
|
|
253
|
-
case "nullable":
|
|
254
|
-
return unwrapSchema(def.innerType);
|
|
255
|
-
case "lazy":
|
|
256
|
-
return unwrapSchema(def.getter());
|
|
257
|
-
case "pipe":
|
|
258
|
-
return unwrapSchema(def.in);
|
|
259
|
-
default:
|
|
260
|
-
return schema;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
function resolveZodTypeName(schema) {
|
|
264
|
-
return getZodType(unwrapSchema(schema));
|
|
265
|
-
}
|
|
266
|
-
// ===== Value coercion =====
|
|
267
|
-
// Returns { value, error } — if error is non-null, coercion failed.
|
|
268
|
-
function coerceValue(value, schema) {
|
|
269
|
-
const unwrapped = unwrapSchema(schema);
|
|
270
|
-
const typeName = getZodType(unwrapped);
|
|
271
|
-
const def = getDef(unwrapped);
|
|
272
|
-
switch (typeName) {
|
|
273
|
-
case "number": {
|
|
274
|
-
const num = Number(value);
|
|
275
|
-
if (isNaN(num)) {
|
|
276
|
-
return {
|
|
277
|
-
value: undefined,
|
|
278
|
-
error: `Cannot convert "${value}" to number`,
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
return { value: num, error: null };
|
|
282
|
-
}
|
|
283
|
-
case "boolean":
|
|
284
|
-
if (value !== "true" && value !== "false") {
|
|
285
|
-
return {
|
|
286
|
-
value: undefined,
|
|
287
|
-
error: `Cannot convert "${value}" to boolean (expected "true" or "false")`,
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
return { value: value === "true", error: null };
|
|
291
|
-
case "string":
|
|
292
|
-
case "enum":
|
|
293
|
-
return { value, error: null };
|
|
294
|
-
case "literal": {
|
|
295
|
-
const values = def.values;
|
|
296
|
-
const singleValue = def.value;
|
|
297
|
-
return { value: values?.[0] ?? singleValue, error: null };
|
|
298
|
-
}
|
|
299
|
-
case "array":
|
|
300
|
-
case "object":
|
|
301
|
-
case "record":
|
|
302
|
-
case "tuple":
|
|
303
|
-
try {
|
|
304
|
-
return { value: JSON.parse(value), error: null };
|
|
305
|
-
}
|
|
306
|
-
catch {
|
|
307
|
-
return {
|
|
308
|
-
value: undefined,
|
|
309
|
-
error: `Cannot parse JSON value: "${value}"`,
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
case "union": {
|
|
313
|
-
const options = def.options;
|
|
314
|
-
return { value: coerceUnionValue(value, options), error: null };
|
|
315
|
-
}
|
|
316
|
-
default:
|
|
317
|
-
return { value: coerceFallback(value), error: null };
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
function coerceUnionValue(value, options) {
|
|
321
|
-
const typeNames = options.map((opt) => resolveZodTypeName(opt));
|
|
322
|
-
// Try boolean
|
|
323
|
-
if ((value === "true" || value === "false") &&
|
|
324
|
-
typeNames.includes("boolean")) {
|
|
325
|
-
return value === "true";
|
|
326
|
-
}
|
|
327
|
-
// Try number
|
|
328
|
-
if (typeNames.includes("number")) {
|
|
329
|
-
const num = Number(value);
|
|
330
|
-
if (!isNaN(num) && value !== "") {
|
|
331
|
-
return num;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
// Try literal
|
|
335
|
-
for (let i = 0; i < options.length; i++) {
|
|
336
|
-
if (typeNames[i] === "literal") {
|
|
337
|
-
const unwrapped = unwrapSchema(options[i]);
|
|
338
|
-
const def = getDef(unwrapped);
|
|
339
|
-
const values = def.values;
|
|
340
|
-
const singleValue = def.value;
|
|
341
|
-
const litVal = values?.[0] ?? singleValue;
|
|
342
|
-
if (litVal != null && `${litVal}` === value)
|
|
343
|
-
return litVal;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
// Try JSON parse for objects/arrays
|
|
347
|
-
if (typeNames.some((t) => ["array", "object", "record", "tuple"].includes(t))) {
|
|
348
|
-
if (value.startsWith("{") || value.startsWith("[")) {
|
|
349
|
-
try {
|
|
350
|
-
return JSON.parse(value);
|
|
351
|
-
}
|
|
352
|
-
catch {
|
|
353
|
-
/* ignore */
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
// Fallback to string
|
|
358
|
-
return value;
|
|
359
|
-
}
|
|
360
|
-
function coerceFallback(value) {
|
|
361
|
-
if (value === "true")
|
|
362
|
-
return true;
|
|
363
|
-
if (value === "false")
|
|
364
|
-
return false;
|
|
365
|
-
const num = Number(value);
|
|
366
|
-
if (value !== "" && !isNaN(num))
|
|
367
|
-
return num;
|
|
368
|
-
if (value.startsWith("{") || value.startsWith("[")) {
|
|
369
|
-
try {
|
|
370
|
-
return JSON.parse(value);
|
|
371
|
-
}
|
|
372
|
-
catch {
|
|
373
|
-
/* ignore */
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
return value;
|
|
195
|
+
// ===== Coercion rule lookup =====
|
|
196
|
+
function getCoercionRule(nodeType, propertyName) {
|
|
197
|
+
return NODE_COERCION_MAP[nodeType]?.[propertyName];
|
|
377
198
|
}
|
|
378
199
|
// ===== Dot notation helpers =====
|
|
379
|
-
/**
|
|
380
|
-
* Checks if a schema is a union containing both boolean and object types.
|
|
381
|
-
* Used to allow `endArrow="true" endArrow.type="triangle"` coexistence.
|
|
382
|
-
*/
|
|
383
|
-
function isBooleanObjectUnion(schema) {
|
|
384
|
-
const unwrapped = unwrapSchema(schema);
|
|
385
|
-
const typeName = getZodType(unwrapped);
|
|
386
|
-
if (typeName !== "union")
|
|
387
|
-
return false;
|
|
388
|
-
const def = getDef(unwrapped);
|
|
389
|
-
const options = def.options;
|
|
390
|
-
const typeNames = options.map((opt) => getZodType(unwrapSchema(opt)));
|
|
391
|
-
return typeNames.includes("boolean") && typeNames.includes("object");
|
|
392
|
-
}
|
|
393
200
|
// ===== Dot notation expansion =====
|
|
394
201
|
function expandDotNotation(attrs) {
|
|
395
202
|
const regular = {};
|
|
@@ -409,26 +216,13 @@ function expandDotNotation(attrs) {
|
|
|
409
216
|
}
|
|
410
217
|
return { regular, dotGroups };
|
|
411
218
|
}
|
|
412
|
-
function coerceDotGroup(prefix, subAttrs,
|
|
413
|
-
const
|
|
414
|
-
const typeName = getZodType(unwrapped);
|
|
415
|
-
let objectSchema;
|
|
416
|
-
if (typeName === "object") {
|
|
417
|
-
objectSchema = unwrapped;
|
|
418
|
-
}
|
|
419
|
-
else if (typeName === "union") {
|
|
420
|
-
const def = getDef(unwrapped);
|
|
421
|
-
const options = def.options;
|
|
422
|
-
objectSchema = options.find((opt) => getZodType(unwrapSchema(opt)) === "object");
|
|
423
|
-
if (objectSchema)
|
|
424
|
-
objectSchema = unwrapSchema(objectSchema);
|
|
425
|
-
}
|
|
219
|
+
function coerceDotGroup(prefix, subAttrs, rule, tagName, errors) {
|
|
220
|
+
const objectShape = getObjectShapeFromRule(rule);
|
|
426
221
|
const obj = {};
|
|
427
|
-
if (
|
|
428
|
-
const shape = extractShape(objectSchema);
|
|
222
|
+
if (objectShape) {
|
|
429
223
|
for (const [subKey, subValue] of Object.entries(subAttrs)) {
|
|
430
|
-
if (
|
|
431
|
-
const coerced =
|
|
224
|
+
if (objectShape[subKey]) {
|
|
225
|
+
const coerced = coerceWithRule(subValue, objectShape[subKey]);
|
|
432
226
|
if (coerced.error !== null) {
|
|
433
227
|
errors.push(`<${tagName}>: ${prefix}.${subKey}: ${coerced.error}`);
|
|
434
228
|
}
|
|
@@ -437,7 +231,7 @@ function coerceDotGroup(prefix, subAttrs, schema, tagName, errors) {
|
|
|
437
231
|
}
|
|
438
232
|
}
|
|
439
233
|
else {
|
|
440
|
-
const knownSubKeys = Object.keys(
|
|
234
|
+
const knownSubKeys = Object.keys(objectShape);
|
|
441
235
|
const suggestion = findClosestMatch(subKey, knownSubKeys);
|
|
442
236
|
errors.push(`<${tagName}>: Unknown sub-attribute "${prefix}.${subKey}"${suggestion ? `. Did you mean "${prefix}.${suggestion}"?` : ""}`);
|
|
443
237
|
}
|
|
@@ -490,30 +284,16 @@ function getTextContent(node) {
|
|
|
490
284
|
}
|
|
491
285
|
return textParts.length > 0 ? textParts.join("") : undefined;
|
|
492
286
|
}
|
|
493
|
-
// ===== Child element schemas for type coercion =====
|
|
494
|
-
const childElementShapes = {
|
|
495
|
-
ProcessArrowStep: extractShape(processArrowStepSchema),
|
|
496
|
-
PyramidLevel: extractShape(pyramidLevelSchema),
|
|
497
|
-
TimelineItem: extractShape(timelineItemSchema),
|
|
498
|
-
MatrixAxes: extractShape(matrixAxisSchema),
|
|
499
|
-
MatrixQuadrants: extractShape(matrixQuadrantsSchema),
|
|
500
|
-
MatrixItem: extractShape(matrixItemSchema),
|
|
501
|
-
FlowNode: extractShape(flowNodeItemSchema),
|
|
502
|
-
FlowConnection: extractShape(flowConnectionSchema),
|
|
503
|
-
TableColumn: extractShape(tableColumnSchema),
|
|
504
|
-
TableCell: extractShape(tableCellSchema),
|
|
505
|
-
Li: extractShape(inputLiNodeSchema),
|
|
506
|
-
};
|
|
507
287
|
function coerceChildAttrs(parentTagName, tagName, attrs, errors) {
|
|
508
|
-
const
|
|
288
|
+
const rules = CHILD_ELEMENT_COERCION_MAP[tagName];
|
|
509
289
|
const result = {};
|
|
510
290
|
const { regular: regularAttrs, dotGroups } = expandDotNotation(attrs);
|
|
511
291
|
// Process dot-notation attributes
|
|
512
292
|
for (const [prefix, subAttrs] of Object.entries(dotGroups)) {
|
|
513
|
-
if (
|
|
514
|
-
result[prefix] = coerceDotGroup(prefix, subAttrs,
|
|
293
|
+
if (rules && rules[prefix]) {
|
|
294
|
+
result[prefix] = coerceDotGroup(prefix, subAttrs, rules[prefix], `${parentTagName}.${tagName}`, errors);
|
|
515
295
|
}
|
|
516
|
-
else if (
|
|
296
|
+
else if (rules) {
|
|
517
297
|
const knownAttrs = getKnownChildAttributes(tagName);
|
|
518
298
|
const suggestion = findClosestMatch(prefix, knownAttrs);
|
|
519
299
|
errors.push(`<${parentTagName}>.<${tagName}>: Unknown attribute "${prefix}"${suggestion ? `. Did you mean "${suggestion}"?` : ""}`);
|
|
@@ -529,11 +309,11 @@ function coerceChildAttrs(parentTagName, tagName, attrs, errors) {
|
|
|
529
309
|
// Process regular attributes
|
|
530
310
|
for (const [key, value] of Object.entries(regularAttrs)) {
|
|
531
311
|
if (key in dotGroups) {
|
|
532
|
-
// When the
|
|
312
|
+
// When the rule is a union of boolean and object,
|
|
533
313
|
// allow boolean shorthand to coexist with dot-notation by ignoring the boolean value.
|
|
534
|
-
if (
|
|
535
|
-
|
|
536
|
-
|
|
314
|
+
if (rules &&
|
|
315
|
+
rules[key] &&
|
|
316
|
+
isBooleanObjectUnionRule(rules[key]) &&
|
|
537
317
|
(value === "true" || value === "false")) {
|
|
538
318
|
// Silently skip the boolean value; dot-notation takes priority
|
|
539
319
|
continue;
|
|
@@ -541,8 +321,8 @@ function coerceChildAttrs(parentTagName, tagName, attrs, errors) {
|
|
|
541
321
|
errors.push(`<${parentTagName}>.<${tagName}>: Attribute "${key}" conflicts with dot-notation attributes. Use one or the other, not both`);
|
|
542
322
|
continue;
|
|
543
323
|
}
|
|
544
|
-
if (
|
|
545
|
-
const coerced =
|
|
324
|
+
if (rules && rules[key]) {
|
|
325
|
+
const coerced = coerceWithRule(value, rules[key]);
|
|
546
326
|
if (coerced.error !== null) {
|
|
547
327
|
errors.push(`<${parentTagName}>.<${tagName}>: ${coerced.error}`);
|
|
548
328
|
}
|
|
@@ -550,7 +330,7 @@ function coerceChildAttrs(parentTagName, tagName, attrs, errors) {
|
|
|
550
330
|
result[key] = coerced.value;
|
|
551
331
|
}
|
|
552
332
|
}
|
|
553
|
-
else if (
|
|
333
|
+
else if (rules) {
|
|
554
334
|
// Unknown attribute on child element
|
|
555
335
|
const knownAttrs = getKnownChildAttributes(tagName);
|
|
556
336
|
const suggestion = findClosestMatch(key, knownAttrs);
|
|
@@ -644,7 +424,6 @@ function convertFlowChildren(childElements, result, errors) {
|
|
|
644
424
|
}
|
|
645
425
|
}
|
|
646
426
|
function convertChartChildren(childElements, result, errors) {
|
|
647
|
-
const dataShape = extractShape(chartDataSchema);
|
|
648
427
|
const data = [];
|
|
649
428
|
for (const child of childElements) {
|
|
650
429
|
const tag = getTagName(child);
|
|
@@ -658,19 +437,8 @@ function convertChartChildren(childElements, result, errors) {
|
|
|
658
437
|
values: [],
|
|
659
438
|
};
|
|
660
439
|
if (attrs.name !== undefined) {
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
const coerced = coerceValue(attrs.name, nameSchema);
|
|
664
|
-
if (coerced.error !== null) {
|
|
665
|
-
errors.push(`<Chart>.<ChartSeries>: ${coerced.error}`);
|
|
666
|
-
}
|
|
667
|
-
else {
|
|
668
|
-
series.name = coerced.value;
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
else {
|
|
672
|
-
series.name = attrs.name;
|
|
673
|
-
}
|
|
440
|
+
// chartDataSchema.name は z.string().optional() なのでそのまま文字列として使用
|
|
441
|
+
series.name = attrs.name;
|
|
674
442
|
}
|
|
675
443
|
for (const dp of getChildElements(child)) {
|
|
676
444
|
const dpTag = getTagName(dp);
|
|
@@ -840,9 +608,9 @@ function convertPomNode(nodeType, tagName, attrs, childElements, textContent, er
|
|
|
840
608
|
for (const [prefix, subAttrs] of Object.entries(dotGroups)) {
|
|
841
609
|
if (prefix === "type")
|
|
842
610
|
continue;
|
|
843
|
-
const
|
|
844
|
-
if (
|
|
845
|
-
result[prefix] = coerceDotGroup(prefix, subAttrs,
|
|
611
|
+
const rule = getCoercionRule(nodeType, prefix);
|
|
612
|
+
if (rule) {
|
|
613
|
+
result[prefix] = coerceDotGroup(prefix, subAttrs, rule, tagName, errors);
|
|
846
614
|
}
|
|
847
615
|
else {
|
|
848
616
|
const knownAttrs = getKnownAttributes(nodeType);
|
|
@@ -860,11 +628,11 @@ function convertPomNode(nodeType, tagName, attrs, childElements, textContent, er
|
|
|
860
628
|
continue;
|
|
861
629
|
// Conflict check: dot-notation and regular attribute for the same key
|
|
862
630
|
if (key in dotGroups) {
|
|
863
|
-
// When the
|
|
631
|
+
// When the rule is a union of boolean and object (e.g., endArrow),
|
|
864
632
|
// allow boolean shorthand to coexist with dot-notation by ignoring the boolean value.
|
|
865
|
-
const
|
|
866
|
-
if (
|
|
867
|
-
|
|
633
|
+
const ruleForConflict = getCoercionRule(nodeType, key);
|
|
634
|
+
if (ruleForConflict &&
|
|
635
|
+
isBooleanObjectUnionRule(ruleForConflict) &&
|
|
868
636
|
(value === "true" || value === "false")) {
|
|
869
637
|
// Silently skip the boolean value; dot-notation takes priority
|
|
870
638
|
continue;
|
|
@@ -872,9 +640,9 @@ function convertPomNode(nodeType, tagName, attrs, childElements, textContent, er
|
|
|
872
640
|
errors.push(`<${tagName}>: Attribute "${key}" conflicts with dot-notation attributes (e.g., "${key}.xxx"). Use one or the other, not both`);
|
|
873
641
|
continue;
|
|
874
642
|
}
|
|
875
|
-
const
|
|
876
|
-
if (
|
|
877
|
-
const coerced =
|
|
643
|
+
const rule = getCoercionRule(nodeType, key);
|
|
644
|
+
if (rule) {
|
|
645
|
+
const coerced = coerceWithRule(value, rule);
|
|
878
646
|
if (coerced.error !== null) {
|
|
879
647
|
errors.push(`<${tagName}>: ${coerced.error}`);
|
|
880
648
|
}
|
|
@@ -936,11 +704,14 @@ function convertPomNode(nodeType, tagName, attrs, childElements, textContent, er
|
|
|
936
704
|
if (!CONTAINER_TYPES.has(nodeType)) {
|
|
937
705
|
validateLeafNode(nodeType, result, errors);
|
|
938
706
|
}
|
|
939
|
-
// Normalize icon color: add # prefix if missing
|
|
940
|
-
if (nodeType === "icon"
|
|
941
|
-
typeof result.color === "string" &&
|
|
942
|
-
|
|
943
|
-
|
|
707
|
+
// Normalize icon color / bgColor: add # prefix if missing
|
|
708
|
+
if (nodeType === "icon") {
|
|
709
|
+
if (typeof result.color === "string" && !result.color.startsWith("#")) {
|
|
710
|
+
result.color = `#${result.color}`;
|
|
711
|
+
}
|
|
712
|
+
if (typeof result.bgColor === "string" && !result.bgColor.startsWith("#")) {
|
|
713
|
+
result.bgColor = `#${result.bgColor}`;
|
|
714
|
+
}
|
|
944
715
|
}
|
|
945
716
|
return result;
|
|
946
717
|
}
|
|
@@ -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,cAwDzB,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
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 iconSize = n.size ?? 24;
|
|
10
|
+
// variant 指定時はアイコンサイズ + パディング分を全体サイズとする
|
|
11
|
+
const totalSize = n.variant ? Math.ceil(iconSize * 1.75) : iconSize;
|
|
12
|
+
yn.setMeasureFunc(() => ({ width: totalSize, height: totalSize }));
|
|
13
|
+
},
|
|
14
|
+
toPositioned(pom, absoluteX, absoluteY, layout, ctx) {
|
|
15
|
+
const n = pom;
|
|
16
|
+
const iconSize = n.size ?? 24;
|
|
17
|
+
const rasterSize = Math.max(Math.ceil(n.variant ? iconSize : layout.width), Math.ceil(n.variant ? iconSize : layout.height), iconSize);
|
|
18
|
+
const iconImageData = rasterizeIcon(n.name, rasterSize, n.color ?? "#000000", ctx.iconRasterCache);
|
|
19
|
+
// variant 指定時はアイコンを中央に配置
|
|
20
|
+
const positioned = {
|
|
21
|
+
...omitYogaNode(n),
|
|
22
|
+
x: absoluteX,
|
|
23
|
+
y: absoluteY,
|
|
24
|
+
w: layout.width,
|
|
25
|
+
h: layout.height,
|
|
26
|
+
iconImageData,
|
|
27
|
+
};
|
|
28
|
+
if (n.variant) {
|
|
29
|
+
const totalSize = Math.ceil(iconSize * 1.75);
|
|
30
|
+
// 背景図形は totalSize の正方形として、layout 領域の中央に配置
|
|
31
|
+
const bgOffsetX = (layout.width - totalSize) / 2;
|
|
32
|
+
const bgOffsetY = (layout.height - totalSize) / 2;
|
|
33
|
+
positioned.bgX = absoluteX + bgOffsetX;
|
|
34
|
+
positioned.bgY = absoluteY + bgOffsetY;
|
|
35
|
+
positioned.bgW = totalSize;
|
|
36
|
+
positioned.bgH = totalSize;
|
|
37
|
+
// アイコンは背景図形の中央に配置
|
|
38
|
+
const iconOffsetX = (layout.width - iconSize) / 2;
|
|
39
|
+
const iconOffsetY = (layout.height - iconSize) / 2;
|
|
40
|
+
positioned.iconX = absoluteX + iconOffsetX;
|
|
41
|
+
positioned.iconY = absoluteY + iconOffsetY;
|
|
42
|
+
positioned.iconW = iconSize;
|
|
43
|
+
positioned.iconH = iconSize;
|
|
44
|
+
}
|
|
45
|
+
return positioned;
|
|
46
|
+
},
|
|
47
|
+
render(node, ctx) {
|
|
48
|
+
renderIconNode(node, ctx);
|
|
49
|
+
},
|
|
50
|
+
};
|
|
@@ -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"}
|