@hirokisakabe/pom 4.1.1 → 5.0.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 +2 -2
- package/dist/calcYogaLayout/calcYogaLayout.js +18 -8
- package/dist/calcYogaLayout/fontLoader.d.ts +1 -1
- package/dist/calcYogaLayout/fontLoader.js +1 -1
- package/dist/icons/iconData.d.ts +2 -0
- package/dist/icons/iconData.d.ts.map +1 -0
- package/dist/icons/iconData.js +53 -0
- package/dist/icons/index.d.ts +2 -0
- package/dist/icons/index.d.ts.map +1 -0
- package/dist/icons/index.js +1 -0
- package/dist/icons/renderIcon.d.ts +2 -0
- package/dist/icons/renderIcon.d.ts.map +1 -0
- package/dist/icons/renderIcon.js +23 -0
- package/dist/parseXml/inputSchema.d.ts +65 -21
- package/dist/parseXml/inputSchema.d.ts.map +1 -1
- package/dist/parseXml/inputSchema.js +22 -15
- package/dist/parseXml/parseXml.d.ts +1 -1
- package/dist/parseXml/parseXml.d.ts.map +1 -1
- package/dist/parseXml/parseXml.js +114 -4
- package/dist/renderPptx/nodes/icon.d.ts +8 -0
- package/dist/renderPptx/nodes/icon.d.ts.map +1 -0
- package/dist/renderPptx/nodes/icon.js +10 -0
- package/dist/renderPptx/nodes/index.d.ts +1 -0
- package/dist/renderPptx/nodes/index.d.ts.map +1 -1
- package/dist/renderPptx/nodes/index.js +1 -0
- package/dist/renderPptx/nodes/list.js +16 -16
- package/dist/renderPptx/nodes/processArrow.js +2 -2
- package/dist/renderPptx/nodes/pyramid.js +1 -1
- package/dist/renderPptx/nodes/shape.js +3 -3
- package/dist/renderPptx/nodes/table.js +2 -2
- package/dist/renderPptx/renderPptx.d.ts.map +1 -1
- package/dist/renderPptx/renderPptx.js +8 -5
- package/dist/renderPptx/textOptions.js +4 -4
- package/dist/toPositioned/toPositioned.d.ts.map +1 -1
- package/dist/toPositioned/toPositioned.js +13 -0
- package/dist/types.d.ts +90 -36
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +36 -20
- package/package.json +4 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { XMLParser } from "fast-xml-parser";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { inputTextNodeSchema, inputUlNodeSchema, inputOlNodeSchema, inputLiNodeSchema, inputImageNodeSchema, inputTableNodeSchema, inputShapeNodeSchema, inputChartNodeSchema, inputTimelineNodeSchema, inputMatrixNodeSchema, inputTreeNodeSchema, inputFlowNodeSchema, inputProcessArrowNodeSchema, inputPyramidNodeSchema, inputLineNodeSchema, inputBaseNodeSchema, } from "./inputSchema.js";
|
|
3
|
+
import { inputTextNodeSchema, inputUlNodeSchema, inputOlNodeSchema, inputLiNodeSchema, inputImageNodeSchema, inputTableNodeSchema, inputShapeNodeSchema, inputChartNodeSchema, inputTimelineNodeSchema, inputMatrixNodeSchema, inputTreeNodeSchema, inputFlowNodeSchema, inputProcessArrowNodeSchema, inputPyramidNodeSchema, inputLineNodeSchema, inputIconNodeSchema, inputBaseNodeSchema, } from "./inputSchema.js";
|
|
4
4
|
import { alignItemsSchema, justifyContentSchema, shadowStyleSchema, processArrowStepSchema, pyramidLevelSchema, timelineItemSchema, matrixAxisSchema, matrixQuadrantsSchema, matrixItemSchema, flowNodeItemSchema, flowConnectionSchema, chartDataSchema, tableColumnSchema, tableCellSchema, } from "../types.js";
|
|
5
5
|
// ===== ParseXmlError =====
|
|
6
6
|
export class ParseXmlError extends Error {
|
|
@@ -32,6 +32,7 @@ const TAG_TO_TYPE = {
|
|
|
32
32
|
VStack: "vstack",
|
|
33
33
|
HStack: "hstack",
|
|
34
34
|
Layer: "layer",
|
|
35
|
+
Icon: "icon",
|
|
35
36
|
};
|
|
36
37
|
// Reverse mapping: node type → tag name
|
|
37
38
|
const TYPE_TO_TAG = Object.fromEntries(Object.entries(TAG_TO_TYPE).map(([tag, type]) => [type, tag]));
|
|
@@ -53,6 +54,7 @@ const leafNodeShapes = {
|
|
|
53
54
|
line: extractShape(inputLineNodeSchema),
|
|
54
55
|
ul: extractShape(inputUlNodeSchema),
|
|
55
56
|
ol: extractShape(inputOlNodeSchema),
|
|
57
|
+
icon: extractShape(inputIconNodeSchema),
|
|
56
58
|
};
|
|
57
59
|
const containerShapes = {
|
|
58
60
|
box: extractShape(inputBaseNodeSchema.extend({ shadow: shadowStyleSchema.optional() })),
|
|
@@ -132,6 +134,7 @@ const leafNodeValidationSchemas = {
|
|
|
132
134
|
line: inputLineNodeSchema,
|
|
133
135
|
ul: inputUlNodeSchema,
|
|
134
136
|
ol: inputOlNodeSchema,
|
|
137
|
+
icon: inputIconNodeSchema,
|
|
135
138
|
};
|
|
136
139
|
function formatZodIssue(issue, tagName) {
|
|
137
140
|
const path = issue.path;
|
|
@@ -368,6 +371,64 @@ function coerceFallback(value) {
|
|
|
368
371
|
}
|
|
369
372
|
return value;
|
|
370
373
|
}
|
|
374
|
+
// ===== Dot notation expansion =====
|
|
375
|
+
function expandDotNotation(attrs) {
|
|
376
|
+
const regular = {};
|
|
377
|
+
const dotGroups = {};
|
|
378
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
379
|
+
const dotIndex = key.indexOf(".");
|
|
380
|
+
if (dotIndex > 0) {
|
|
381
|
+
const prefix = key.substring(0, dotIndex);
|
|
382
|
+
const suffix = key.substring(dotIndex + 1);
|
|
383
|
+
if (!dotGroups[prefix])
|
|
384
|
+
dotGroups[prefix] = {};
|
|
385
|
+
dotGroups[prefix][suffix] = value;
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
regular[key] = value;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return { regular, dotGroups };
|
|
392
|
+
}
|
|
393
|
+
function coerceDotGroup(prefix, subAttrs, schema, tagName, errors) {
|
|
394
|
+
const unwrapped = unwrapSchema(schema);
|
|
395
|
+
const typeName = getZodType(unwrapped);
|
|
396
|
+
let objectSchema;
|
|
397
|
+
if (typeName === "object") {
|
|
398
|
+
objectSchema = unwrapped;
|
|
399
|
+
}
|
|
400
|
+
else if (typeName === "union") {
|
|
401
|
+
const def = getDef(unwrapped);
|
|
402
|
+
const options = def.options;
|
|
403
|
+
objectSchema = options.find((opt) => getZodType(unwrapSchema(opt)) === "object");
|
|
404
|
+
if (objectSchema)
|
|
405
|
+
objectSchema = unwrapSchema(objectSchema);
|
|
406
|
+
}
|
|
407
|
+
const obj = {};
|
|
408
|
+
if (objectSchema) {
|
|
409
|
+
const shape = extractShape(objectSchema);
|
|
410
|
+
for (const [subKey, subValue] of Object.entries(subAttrs)) {
|
|
411
|
+
if (shape[subKey]) {
|
|
412
|
+
const coerced = coerceValue(subValue, shape[subKey]);
|
|
413
|
+
if (coerced.error !== null) {
|
|
414
|
+
errors.push(`<${tagName}>: ${prefix}.${subKey}: ${coerced.error}`);
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
obj[subKey] = coerced.value;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
const knownSubKeys = Object.keys(shape);
|
|
422
|
+
const suggestion = findClosestMatch(subKey, knownSubKeys);
|
|
423
|
+
errors.push(`<${tagName}>: Unknown sub-attribute "${prefix}.${subKey}"${suggestion ? `. Did you mean "${prefix}.${suggestion}"?` : ""}`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
errors.push(`<${tagName}>: Attribute "${prefix}" does not support dot notation`);
|
|
429
|
+
}
|
|
430
|
+
return obj;
|
|
431
|
+
}
|
|
371
432
|
// ===== XML node helpers =====
|
|
372
433
|
function isTextNode(node) {
|
|
373
434
|
return "#text" in node;
|
|
@@ -427,7 +488,31 @@ const childElementShapes = {
|
|
|
427
488
|
function coerceChildAttrs(parentTagName, tagName, attrs, errors) {
|
|
428
489
|
const shape = childElementShapes[tagName];
|
|
429
490
|
const result = {};
|
|
430
|
-
|
|
491
|
+
const { regular: regularAttrs, dotGroups } = expandDotNotation(attrs);
|
|
492
|
+
// Process dot-notation attributes
|
|
493
|
+
for (const [prefix, subAttrs] of Object.entries(dotGroups)) {
|
|
494
|
+
if (shape && shape[prefix]) {
|
|
495
|
+
result[prefix] = coerceDotGroup(prefix, subAttrs, shape[prefix], `${parentTagName}.${tagName}`, errors);
|
|
496
|
+
}
|
|
497
|
+
else if (shape) {
|
|
498
|
+
const knownAttrs = getKnownChildAttributes(tagName);
|
|
499
|
+
const suggestion = findClosestMatch(prefix, knownAttrs);
|
|
500
|
+
errors.push(`<${parentTagName}>.<${tagName}>: Unknown attribute "${prefix}"${suggestion ? `. Did you mean "${suggestion}"?` : ""}`);
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
result[prefix] = {};
|
|
504
|
+
for (const [subKey, subValue] of Object.entries(subAttrs)) {
|
|
505
|
+
result[prefix][subKey] =
|
|
506
|
+
coerceFallback(subValue);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
// Process regular attributes
|
|
511
|
+
for (const [key, value] of Object.entries(regularAttrs)) {
|
|
512
|
+
if (key in dotGroups) {
|
|
513
|
+
errors.push(`<${parentTagName}>.<${tagName}>: Attribute "${key}" conflicts with dot-notation attributes. Use one or the other, not both`);
|
|
514
|
+
continue;
|
|
515
|
+
}
|
|
431
516
|
if (shape && shape[key]) {
|
|
432
517
|
const coerced = coerceValue(value, shape[key]);
|
|
433
518
|
if (coerced.error !== null) {
|
|
@@ -722,9 +807,34 @@ function convertElement(node, errors) {
|
|
|
722
807
|
}
|
|
723
808
|
function convertPomNode(nodeType, tagName, attrs, childElements, textContent, errors) {
|
|
724
809
|
const result = { type: nodeType };
|
|
725
|
-
|
|
810
|
+
// Expand dot-notation attributes (e.g., fill.color="hex" → { fill: { color: "hex" } })
|
|
811
|
+
const { regular: regularAttrs, dotGroups } = expandDotNotation(attrs);
|
|
812
|
+
for (const [prefix, subAttrs] of Object.entries(dotGroups)) {
|
|
813
|
+
if (prefix === "type")
|
|
814
|
+
continue;
|
|
815
|
+
const propSchema = getPropertySchema(nodeType, prefix);
|
|
816
|
+
if (propSchema) {
|
|
817
|
+
result[prefix] = coerceDotGroup(prefix, subAttrs, propSchema, tagName, errors);
|
|
818
|
+
}
|
|
819
|
+
else {
|
|
820
|
+
const knownAttrs = getKnownAttributes(nodeType);
|
|
821
|
+
const suggestion = findClosestMatch(prefix, knownAttrs);
|
|
822
|
+
if (suggestion) {
|
|
823
|
+
errors.push(`<${tagName}>: Unknown attribute "${prefix}". Did you mean "${suggestion}"?`);
|
|
824
|
+
}
|
|
825
|
+
else {
|
|
826
|
+
errors.push(`<${tagName}>: Unknown attribute "${prefix}"`);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
for (const [key, value] of Object.entries(regularAttrs)) {
|
|
726
831
|
if (key === "type")
|
|
727
832
|
continue;
|
|
833
|
+
// Conflict check: dot-notation and regular attribute for the same key
|
|
834
|
+
if (key in dotGroups) {
|
|
835
|
+
errors.push(`<${tagName}>: Attribute "${key}" conflicts with dot-notation attributes (e.g., "${key}.xxx"). Use one or the other, not both`);
|
|
836
|
+
continue;
|
|
837
|
+
}
|
|
728
838
|
const propSchema = getPropertySchema(nodeType, key);
|
|
729
839
|
if (propSchema) {
|
|
730
840
|
const coerced = coerceValue(value, propSchema);
|
|
@@ -804,7 +914,7 @@ function convertPomNode(nodeType, tagName, attrs, childElements, textContent, er
|
|
|
804
914
|
*
|
|
805
915
|
* const xml = `
|
|
806
916
|
* <VStack gap="16" padding="32">
|
|
807
|
-
* <Text
|
|
917
|
+
* <Text fontSize="32" bold="true">売上レポート</Text>
|
|
808
918
|
* </VStack>
|
|
809
919
|
* `;
|
|
810
920
|
*
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PositionedNode } from "../../types.ts";
|
|
2
|
+
import type { RenderContext } from "../types.ts";
|
|
3
|
+
type IconPositionedNode = Extract<PositionedNode, {
|
|
4
|
+
type: "icon";
|
|
5
|
+
}>;
|
|
6
|
+
export declare function renderIconNode(node: IconPositionedNode, ctx: RenderContext): void;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=icon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/icon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,KAAK,kBAAkB,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEpE,wBAAgB,cAAc,CAC5B,IAAI,EAAE,kBAAkB,EACxB,GAAG,EAAE,aAAa,GACjB,IAAI,CAQN"}
|
|
@@ -11,4 +11,5 @@ export { renderProcessArrowNode } from "./processArrow.ts";
|
|
|
11
11
|
export { renderPyramidNode } from "./pyramid.ts";
|
|
12
12
|
export { renderLineNode } from "./line.ts";
|
|
13
13
|
export { renderUlNode, renderOlNode } from "./list.ts";
|
|
14
|
+
export { renderIconNode } from "./icon.ts";
|
|
14
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -2,7 +2,7 @@ import { pxToIn, pxToPt } from "../units.js";
|
|
|
2
2
|
import { convertUnderline, convertStrike } from "../textOptions.js";
|
|
3
3
|
function resolveStyle(li, parent) {
|
|
4
4
|
return {
|
|
5
|
-
|
|
5
|
+
fontSize: li.fontSize ?? parent.fontSize ?? 24,
|
|
6
6
|
color: li.color ?? parent.color,
|
|
7
7
|
bold: li.bold ?? parent.bold,
|
|
8
8
|
italic: li.italic ?? parent.italic,
|
|
@@ -13,7 +13,7 @@ function resolveStyle(li, parent) {
|
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
function hasItemStyleOverride(items) {
|
|
16
|
-
return items.some((li) => li.
|
|
16
|
+
return items.some((li) => li.fontSize !== undefined ||
|
|
17
17
|
li.color !== undefined ||
|
|
18
18
|
li.bold !== undefined ||
|
|
19
19
|
li.italic !== undefined ||
|
|
@@ -23,9 +23,9 @@ function hasItemStyleOverride(items) {
|
|
|
23
23
|
li.fontFamily !== undefined);
|
|
24
24
|
}
|
|
25
25
|
export function renderUlNode(node, ctx) {
|
|
26
|
-
const fontSizePx = node.
|
|
26
|
+
const fontSizePx = node.fontSize ?? 24;
|
|
27
27
|
const fontFamily = node.fontFamily ?? "Noto Sans JP";
|
|
28
|
-
const
|
|
28
|
+
const lineHeight = node.lineHeight ?? 1.3;
|
|
29
29
|
if (hasItemStyleOverride(node.items)) {
|
|
30
30
|
// Li に個別スタイルがある場合は配列形式を使用
|
|
31
31
|
const textItems = node.items.map((li, i) => {
|
|
@@ -33,7 +33,7 @@ export function renderUlNode(node, ctx) {
|
|
|
33
33
|
return {
|
|
34
34
|
text: i < node.items.length - 1 ? li.text + "\n" : li.text,
|
|
35
35
|
options: {
|
|
36
|
-
fontSize: pxToPt(style.
|
|
36
|
+
fontSize: pxToPt(style.fontSize),
|
|
37
37
|
fontFace: style.fontFamily,
|
|
38
38
|
color: style.color,
|
|
39
39
|
bold: style.bold,
|
|
@@ -50,10 +50,10 @@ export function renderUlNode(node, ctx) {
|
|
|
50
50
|
y: pxToIn(node.y),
|
|
51
51
|
w: pxToIn(node.w),
|
|
52
52
|
h: pxToIn(node.h),
|
|
53
|
-
align: node.
|
|
53
|
+
align: node.textAlign ?? "left",
|
|
54
54
|
valign: "top",
|
|
55
55
|
margin: 0,
|
|
56
|
-
lineSpacingMultiple,
|
|
56
|
+
lineSpacingMultiple: lineHeight,
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
else {
|
|
@@ -66,10 +66,10 @@ export function renderUlNode(node, ctx) {
|
|
|
66
66
|
h: pxToIn(node.h),
|
|
67
67
|
fontSize: pxToPt(fontSizePx),
|
|
68
68
|
fontFace: fontFamily,
|
|
69
|
-
align: node.
|
|
69
|
+
align: node.textAlign ?? "left",
|
|
70
70
|
valign: "top",
|
|
71
71
|
margin: 0,
|
|
72
|
-
lineSpacingMultiple,
|
|
72
|
+
lineSpacingMultiple: lineHeight,
|
|
73
73
|
color: node.color,
|
|
74
74
|
bold: node.bold,
|
|
75
75
|
italic: node.italic,
|
|
@@ -81,9 +81,9 @@ export function renderUlNode(node, ctx) {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
export function renderOlNode(node, ctx) {
|
|
84
|
-
const fontSizePx = node.
|
|
84
|
+
const fontSizePx = node.fontSize ?? 24;
|
|
85
85
|
const fontFamily = node.fontFamily ?? "Noto Sans JP";
|
|
86
|
-
const
|
|
86
|
+
const lineHeight = node.lineHeight ?? 1.3;
|
|
87
87
|
const bulletOptions = { type: "number" };
|
|
88
88
|
if (node.numberType !== undefined) {
|
|
89
89
|
bulletOptions.numberType = node.numberType;
|
|
@@ -97,7 +97,7 @@ export function renderOlNode(node, ctx) {
|
|
|
97
97
|
return {
|
|
98
98
|
text: i < node.items.length - 1 ? li.text + "\n" : li.text,
|
|
99
99
|
options: {
|
|
100
|
-
fontSize: pxToPt(style.
|
|
100
|
+
fontSize: pxToPt(style.fontSize),
|
|
101
101
|
fontFace: style.fontFamily,
|
|
102
102
|
color: style.color,
|
|
103
103
|
bold: style.bold,
|
|
@@ -114,10 +114,10 @@ export function renderOlNode(node, ctx) {
|
|
|
114
114
|
y: pxToIn(node.y),
|
|
115
115
|
w: pxToIn(node.w),
|
|
116
116
|
h: pxToIn(node.h),
|
|
117
|
-
align: node.
|
|
117
|
+
align: node.textAlign ?? "left",
|
|
118
118
|
valign: "top",
|
|
119
119
|
margin: 0,
|
|
120
|
-
lineSpacingMultiple,
|
|
120
|
+
lineSpacingMultiple: lineHeight,
|
|
121
121
|
});
|
|
122
122
|
}
|
|
123
123
|
else {
|
|
@@ -129,10 +129,10 @@ export function renderOlNode(node, ctx) {
|
|
|
129
129
|
h: pxToIn(node.h),
|
|
130
130
|
fontSize: pxToPt(fontSizePx),
|
|
131
131
|
fontFace: fontFamily,
|
|
132
|
-
align: node.
|
|
132
|
+
align: node.textAlign ?? "left",
|
|
133
133
|
valign: "top",
|
|
134
134
|
margin: 0,
|
|
135
|
-
lineSpacingMultiple,
|
|
135
|
+
lineSpacingMultiple: lineHeight,
|
|
136
136
|
color: node.color,
|
|
137
137
|
bold: node.bold,
|
|
138
138
|
italic: node.italic,
|
|
@@ -77,7 +77,7 @@ function renderHorizontalProcessArrow(node, ctx, steps, stepCount, itemWidth, it
|
|
|
77
77
|
y: pxToIn(stepY),
|
|
78
78
|
w: pxToIn(textWidth),
|
|
79
79
|
h: pxToIn(itemHeight),
|
|
80
|
-
fontSize: pxToPt((node.
|
|
80
|
+
fontSize: pxToPt((node.fontSize ?? 14) * scaleFactor),
|
|
81
81
|
fontFace: "Noto Sans JP",
|
|
82
82
|
color: textColor,
|
|
83
83
|
bold: node.bold ?? false,
|
|
@@ -137,7 +137,7 @@ function renderVerticalProcessArrow(node, ctx, steps, stepCount, itemWidth, item
|
|
|
137
137
|
y: pxToIn(stepY + textOffsetTop),
|
|
138
138
|
w: pxToIn(itemWidth),
|
|
139
139
|
h: pxToIn(textHeight),
|
|
140
|
-
fontSize: pxToPt((node.
|
|
140
|
+
fontSize: pxToPt((node.fontSize ?? 14) * scaleFactor),
|
|
141
141
|
fontFace: "Noto Sans JP",
|
|
142
142
|
color: textColor,
|
|
143
143
|
bold: node.bold ?? false,
|
|
@@ -69,7 +69,7 @@ export function renderPyramidNode(node, ctx) {
|
|
|
69
69
|
y: pxToIn(layerY),
|
|
70
70
|
w: pxToIn(bboxW),
|
|
71
71
|
h: pxToIn(layerHeight),
|
|
72
|
-
fontSize: pxToPt((node.
|
|
72
|
+
fontSize: pxToPt((node.fontSize ?? 14) * scaleFactor),
|
|
73
73
|
fontFace: "Noto Sans JP",
|
|
74
74
|
color: textColor,
|
|
75
75
|
bold: node.bold ?? false,
|
|
@@ -35,7 +35,7 @@ export function renderShapeNode(node, ctx) {
|
|
|
35
35
|
ctx.slide.addText(node.text, {
|
|
36
36
|
...shapeOptions,
|
|
37
37
|
shape: node.shapeType,
|
|
38
|
-
fontSize: pxToPt(node.
|
|
38
|
+
fontSize: pxToPt(node.fontSize ?? 24),
|
|
39
39
|
fontFace: node.fontFamily ?? "Noto Sans JP",
|
|
40
40
|
color: node.color,
|
|
41
41
|
bold: node.bold,
|
|
@@ -43,9 +43,9 @@ export function renderShapeNode(node, ctx) {
|
|
|
43
43
|
underline: convertUnderline(node.underline),
|
|
44
44
|
strike: convertStrike(node.strike),
|
|
45
45
|
highlight: node.highlight,
|
|
46
|
-
align: node.
|
|
46
|
+
align: node.textAlign ?? "center",
|
|
47
47
|
valign: "middle",
|
|
48
|
-
lineSpacingMultiple: node.
|
|
48
|
+
lineSpacingMultiple: node.lineHeight ?? 1.3,
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
else {
|
|
@@ -4,14 +4,14 @@ import { convertUnderline, convertStrike } from "../textOptions.js";
|
|
|
4
4
|
export function renderTableNode(node, ctx) {
|
|
5
5
|
const tableRows = node.rows.map((row) => row.cells.map((cell) => {
|
|
6
6
|
const cellOptions = {
|
|
7
|
-
fontSize: pxToPt(cell.
|
|
7
|
+
fontSize: pxToPt(cell.fontSize ?? 18),
|
|
8
8
|
color: cell.color,
|
|
9
9
|
bold: cell.bold,
|
|
10
10
|
italic: cell.italic,
|
|
11
11
|
underline: convertUnderline(cell.underline),
|
|
12
12
|
strike: convertStrike(cell.strike),
|
|
13
13
|
highlight: cell.highlight,
|
|
14
|
-
align: cell.
|
|
14
|
+
align: cell.textAlign ?? "left",
|
|
15
15
|
fill: cell.backgroundColor
|
|
16
16
|
? { color: cell.backgroundColor }
|
|
17
17
|
: undefined,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderPptx.d.ts","sourceRoot":"","sources":["../../src/renderPptx/renderPptx.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAEnB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"renderPptx.d.ts","sourceRoot":"","sources":["../../src/renderPptx/renderPptx.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAEnB,MAAM,aAAa,CAAC;AAwBrB,KAAK,OAAO,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAqJxC;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE,OAAO,EAChB,MAAM,CAAC,EAAE,kBAAkB,+BAqL5B"}
|
|
@@ -9,7 +9,7 @@ import { pxToIn, pxToPt } from "./units.js";
|
|
|
9
9
|
import { convertUnderline, convertStrike } from "./textOptions.js";
|
|
10
10
|
import { getImageData } from "../shared/measureImage.js";
|
|
11
11
|
import { renderBackgroundAndBorder } from "./utils/backgroundBorder.js";
|
|
12
|
-
import { renderTextNode, renderImageNode, renderTableNode, renderShapeNode, renderChartNode, renderTimelineNode, renderMatrixNode, renderTreeNode, renderFlowNode, renderProcessArrowNode, renderPyramidNode, renderLineNode, renderUlNode, renderOlNode, } from "./nodes/index.js";
|
|
12
|
+
import { renderTextNode, renderImageNode, renderTableNode, renderShapeNode, renderChartNode, renderTimelineNode, renderMatrixNode, renderTreeNode, renderFlowNode, renderProcessArrowNode, renderPyramidNode, renderLineNode, renderUlNode, renderOlNode, renderIconNode, } from "./nodes/index.js";
|
|
13
13
|
const DEFAULT_MASTER_NAME = "POM_MASTER";
|
|
14
14
|
/**
|
|
15
15
|
* MasterObject を pptxgenjs の objects 形式に変換する
|
|
@@ -25,7 +25,7 @@ function convertMasterObject(obj) {
|
|
|
25
25
|
y: pxToIn(obj.y),
|
|
26
26
|
w: pxToIn(obj.w),
|
|
27
27
|
h: pxToIn(obj.h),
|
|
28
|
-
fontSize: obj.
|
|
28
|
+
fontSize: obj.fontSize ? pxToPt(obj.fontSize) : undefined,
|
|
29
29
|
fontFace: obj.fontFamily,
|
|
30
30
|
color: obj.color,
|
|
31
31
|
bold: obj.bold,
|
|
@@ -33,7 +33,7 @@ function convertMasterObject(obj) {
|
|
|
33
33
|
underline: convertUnderline(obj.underline),
|
|
34
34
|
strike: convertStrike(obj.strike),
|
|
35
35
|
highlight: obj.highlight,
|
|
36
|
-
align: obj.
|
|
36
|
+
align: obj.textAlign,
|
|
37
37
|
},
|
|
38
38
|
},
|
|
39
39
|
};
|
|
@@ -138,8 +138,8 @@ function defineSlideMasterFromOptions(pptx, master) {
|
|
|
138
138
|
y: pxToIn(master.slideNumber.y),
|
|
139
139
|
w: master.slideNumber.w ? pxToIn(master.slideNumber.w) : undefined,
|
|
140
140
|
h: master.slideNumber.h ? pxToIn(master.slideNumber.h) : undefined,
|
|
141
|
-
fontSize: master.slideNumber.
|
|
142
|
-
? pxToPt(master.slideNumber.
|
|
141
|
+
fontSize: master.slideNumber.fontSize
|
|
142
|
+
? pxToPt(master.slideNumber.fontSize)
|
|
143
143
|
: undefined,
|
|
144
144
|
fontFace: master.slideNumber.fontFamily,
|
|
145
145
|
color: master.slideNumber.color,
|
|
@@ -247,6 +247,9 @@ export function renderPptx(pages, slidePx, master) {
|
|
|
247
247
|
case "image":
|
|
248
248
|
renderImageNode(node, ctx);
|
|
249
249
|
break;
|
|
250
|
+
case "icon":
|
|
251
|
+
renderIconNode(node, ctx);
|
|
252
|
+
break;
|
|
250
253
|
case "box":
|
|
251
254
|
// 子要素を再帰的に処理
|
|
252
255
|
renderNode(node.children);
|
|
@@ -23,9 +23,9 @@ export function convertStrike(strike) {
|
|
|
23
23
|
return undefined;
|
|
24
24
|
}
|
|
25
25
|
export function createTextOptions(node) {
|
|
26
|
-
const fontSizePx = node.
|
|
26
|
+
const fontSizePx = node.fontSize ?? 24;
|
|
27
27
|
const fontFamily = node.fontFamily ?? "Noto Sans JP";
|
|
28
|
-
const
|
|
28
|
+
const lineHeight = node.lineHeight ?? 1.3;
|
|
29
29
|
return {
|
|
30
30
|
x: pxToIn(node.x),
|
|
31
31
|
y: pxToIn(node.y),
|
|
@@ -33,10 +33,10 @@ export function createTextOptions(node) {
|
|
|
33
33
|
h: pxToIn(node.h),
|
|
34
34
|
fontSize: pxToPt(fontSizePx),
|
|
35
35
|
fontFace: fontFamily,
|
|
36
|
-
align: node.
|
|
36
|
+
align: node.textAlign ?? "left",
|
|
37
37
|
valign: "top",
|
|
38
38
|
margin: 0,
|
|
39
|
-
lineSpacingMultiple,
|
|
39
|
+
lineSpacingMultiple: lineHeight,
|
|
40
40
|
color: node.color,
|
|
41
41
|
bold: node.bold,
|
|
42
42
|
italic: node.italic,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toPositioned.d.ts","sourceRoot":"","sources":["../../src/toPositioned/toPositioned.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"toPositioned.d.ts","sourceRoot":"","sources":["../../src/toPositioned/toPositioned.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAI3D;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,OAAO,EACZ,OAAO,SAAI,EACX,OAAO,SAAI,GACV,cAAc,CAwOhB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getImageData } from "../shared/measureImage.js";
|
|
2
|
+
import { rasterizeIcon } from "../icons/index.js";
|
|
2
3
|
/**
|
|
3
4
|
* POMNode ツリーを絶対座標付きの PositionedNode ツリーに変換する
|
|
4
5
|
* @param pom 入力 POMNode
|
|
@@ -147,6 +148,18 @@ export function toPositioned(pom, parentX = 0, parentY = 0) {
|
|
|
147
148
|
children: pom.children.map((child) => toPositioned(child, absoluteX, absoluteY)),
|
|
148
149
|
};
|
|
149
150
|
}
|
|
151
|
+
case "icon": {
|
|
152
|
+
const rasterSize = Math.max(Math.ceil(layout.width), Math.ceil(layout.height), pom.size ?? 24);
|
|
153
|
+
const iconImageData = rasterizeIcon(pom.name, rasterSize, pom.color ?? "#000000");
|
|
154
|
+
return {
|
|
155
|
+
...pom,
|
|
156
|
+
x: absoluteX,
|
|
157
|
+
y: absoluteY,
|
|
158
|
+
w: layout.width,
|
|
159
|
+
h: layout.height,
|
|
160
|
+
iconImageData,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
150
163
|
case "line": {
|
|
151
164
|
// line ノードは絶対座標(x1, y1, x2, y2)を持つため、
|
|
152
165
|
// yogaNode の座標ではなく自身の座標からバウンディングボックスを計算
|