@hirokisakabe/pom 3.0.0 → 4.1.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.
Files changed (35) hide show
  1. package/README.md +36 -24
  2. package/dist/calcYogaLayout/calcYogaLayout.d.ts.map +1 -1
  3. package/dist/calcYogaLayout/calcYogaLayout.js +29 -4
  4. package/dist/calcYogaLayout/fontLoader.d.ts +16 -0
  5. package/dist/calcYogaLayout/fontLoader.d.ts.map +1 -1
  6. package/dist/calcYogaLayout/fontLoader.js +28 -0
  7. package/dist/calcYogaLayout/measureCompositeNodes.d.ts +13 -1
  8. package/dist/calcYogaLayout/measureCompositeNodes.d.ts.map +1 -1
  9. package/dist/calcYogaLayout/measureCompositeNodes.js +26 -3
  10. package/dist/parseXml/inputSchema.d.ts +52 -0
  11. package/dist/parseXml/inputSchema.d.ts.map +1 -1
  12. package/dist/parseXml/inputSchema.js +9 -1
  13. package/dist/parseXml/parseXml.d.ts.map +1 -1
  14. package/dist/parseXml/parseXml.js +48 -30
  15. package/dist/renderPptx/nodes/index.d.ts +1 -0
  16. package/dist/renderPptx/nodes/index.d.ts.map +1 -1
  17. package/dist/renderPptx/nodes/index.js +1 -0
  18. package/dist/renderPptx/nodes/processArrow.d.ts.map +1 -1
  19. package/dist/renderPptx/nodes/processArrow.js +75 -15
  20. package/dist/renderPptx/nodes/pyramid.d.ts +8 -0
  21. package/dist/renderPptx/nodes/pyramid.d.ts.map +1 -0
  22. package/dist/renderPptx/nodes/pyramid.js +81 -0
  23. package/dist/renderPptx/nodes/table.d.ts.map +1 -1
  24. package/dist/renderPptx/nodes/table.js +2 -0
  25. package/dist/renderPptx/renderPptx.d.ts.map +1 -1
  26. package/dist/renderPptx/renderPptx.js +4 -1
  27. package/dist/shared/processArrowConstants.d.ts +7 -0
  28. package/dist/shared/processArrowConstants.d.ts.map +1 -0
  29. package/dist/shared/processArrowConstants.js +6 -0
  30. package/dist/toPositioned/toPositioned.d.ts.map +1 -1
  31. package/dist/toPositioned/toPositioned.js +9 -0
  32. package/dist/types.d.ts +69 -2
  33. package/dist/types.d.ts.map +1 -1
  34. package/dist/types.js +18 -0
  35. package/package.json +3 -3
@@ -1,7 +1,7 @@
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, inputLineNodeSchema, inputBaseNodeSchema, } from "./inputSchema.js";
4
- import { alignItemsSchema, justifyContentSchema, shadowStyleSchema, processArrowStepSchema, timelineItemSchema, matrixAxisSchema, matrixQuadrantsSchema, matrixItemSchema, flowNodeItemSchema, flowConnectionSchema, chartDataSchema, tableColumnSchema, tableCellSchema, } from "../types.js";
3
+ import { inputTextNodeSchema, inputUlNodeSchema, inputOlNodeSchema, inputLiNodeSchema, inputImageNodeSchema, inputTableNodeSchema, inputShapeNodeSchema, inputChartNodeSchema, inputTimelineNodeSchema, inputMatrixNodeSchema, inputTreeNodeSchema, inputFlowNodeSchema, inputProcessArrowNodeSchema, inputPyramidNodeSchema, inputLineNodeSchema, inputBaseNodeSchema, } from "./inputSchema.js";
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 {
7
7
  errors;
@@ -24,6 +24,7 @@ const TAG_TO_TYPE = {
24
24
  Tree: "tree",
25
25
  Flow: "flow",
26
26
  ProcessArrow: "processArrow",
27
+ Pyramid: "pyramid",
27
28
  Ul: "ul",
28
29
  Ol: "ol",
29
30
  Line: "line",
@@ -48,6 +49,7 @@ const leafNodeShapes = {
48
49
  tree: extractShape(inputTreeNodeSchema),
49
50
  flow: extractShape(inputFlowNodeSchema),
50
51
  processArrow: extractShape(inputProcessArrowNodeSchema),
52
+ pyramid: extractShape(inputPyramidNodeSchema),
51
53
  line: extractShape(inputLineNodeSchema),
52
54
  ul: extractShape(inputUlNodeSchema),
53
55
  ol: extractShape(inputOlNodeSchema),
@@ -126,6 +128,7 @@ const leafNodeValidationSchemas = {
126
128
  tree: inputTreeNodeSchema,
127
129
  flow: inputFlowNodeSchema,
128
130
  processArrow: inputProcessArrowNodeSchema,
131
+ pyramid: inputPyramidNodeSchema,
129
132
  line: inputLineNodeSchema,
130
133
  ul: inputUlNodeSchema,
131
134
  ol: inputOlNodeSchema,
@@ -185,6 +188,7 @@ const CHILD_ELEMENT_PROPS = {
185
188
  timeline: new Set(["items"]),
186
189
  matrix: new Set(["axes", "items", "quadrants"]),
187
190
  processArrow: new Set(["steps"]),
191
+ pyramid: new Set(["levels"]),
188
192
  tree: new Set(["data"]),
189
193
  ul: new Set(["items"]),
190
194
  ol: new Set(["items"]),
@@ -408,15 +412,16 @@ function getTextContent(node) {
408
412
  }
409
413
  // ===== Child element schemas for type coercion =====
410
414
  const childElementShapes = {
411
- Step: extractShape(processArrowStepSchema),
415
+ ProcessArrowStep: extractShape(processArrowStepSchema),
416
+ PyramidLevel: extractShape(pyramidLevelSchema),
412
417
  TimelineItem: extractShape(timelineItemSchema),
413
- Axes: extractShape(matrixAxisSchema),
414
- Quadrants: extractShape(matrixQuadrantsSchema),
418
+ MatrixAxes: extractShape(matrixAxisSchema),
419
+ MatrixQuadrants: extractShape(matrixQuadrantsSchema),
415
420
  MatrixItem: extractShape(matrixItemSchema),
416
421
  FlowNode: extractShape(flowNodeItemSchema),
417
- Connection: extractShape(flowConnectionSchema),
418
- Column: extractShape(tableColumnSchema),
419
- Cell: extractShape(tableCellSchema),
422
+ FlowConnection: extractShape(flowConnectionSchema),
423
+ TableColumn: extractShape(tableColumnSchema),
424
+ TableCell: extractShape(tableCellSchema),
420
425
  Li: extractShape(inputLiNodeSchema),
421
426
  };
422
427
  function coerceChildAttrs(parentTagName, tagName, attrs, errors) {
@@ -448,14 +453,26 @@ function convertProcessArrowChildren(childElements, result, errors) {
448
453
  const steps = [];
449
454
  for (const child of childElements) {
450
455
  const tag = getTagName(child);
451
- if (tag !== "Step") {
452
- errors.push(`Unknown child element <${tag}> inside <ProcessArrow>. Expected: <Step>`);
456
+ if (tag !== "ProcessArrowStep") {
457
+ errors.push(`Unknown child element <${tag}> inside <ProcessArrow>. Expected: <ProcessArrowStep>`);
453
458
  continue;
454
459
  }
455
460
  steps.push(coerceChildAttrs("ProcessArrow", tag, getAttributes(child), errors));
456
461
  }
457
462
  result.steps = steps;
458
463
  }
464
+ function convertPyramidChildren(childElements, result, errors) {
465
+ const levels = [];
466
+ for (const child of childElements) {
467
+ const tag = getTagName(child);
468
+ if (tag !== "PyramidLevel") {
469
+ errors.push(`Unknown child element <${tag}> inside <Pyramid>. Expected: <PyramidLevel>`);
470
+ continue;
471
+ }
472
+ levels.push(coerceChildAttrs("Pyramid", tag, getAttributes(child), errors));
473
+ }
474
+ result.levels = levels;
475
+ }
459
476
  function convertTimelineChildren(childElements, result, errors) {
460
477
  const items = [];
461
478
  for (const child of childElements) {
@@ -473,17 +490,17 @@ function convertMatrixChildren(childElements, result, errors) {
473
490
  for (const child of childElements) {
474
491
  const tag = getTagName(child);
475
492
  switch (tag) {
476
- case "Axes":
493
+ case "MatrixAxes":
477
494
  result.axes = coerceChildAttrs("Matrix", tag, getAttributes(child), errors);
478
495
  break;
479
- case "Quadrants":
496
+ case "MatrixQuadrants":
480
497
  result.quadrants = coerceChildAttrs("Matrix", tag, getAttributes(child), errors);
481
498
  break;
482
499
  case "MatrixItem":
483
500
  items.push(coerceChildAttrs("Matrix", tag, getAttributes(child), errors));
484
501
  break;
485
502
  default:
486
- errors.push(`Unknown child element <${tag}> inside <Matrix>. Expected: <Axes>, <Quadrants>, or <MatrixItem>`);
503
+ errors.push(`Unknown child element <${tag}> inside <Matrix>. Expected: <MatrixAxes>, <MatrixQuadrants>, or <MatrixItem>`);
487
504
  }
488
505
  }
489
506
  if (items.length > 0) {
@@ -499,11 +516,11 @@ function convertFlowChildren(childElements, result, errors) {
499
516
  case "FlowNode":
500
517
  nodes.push(coerceChildAttrs("Flow", tag, getAttributes(child), errors));
501
518
  break;
502
- case "Connection":
519
+ case "FlowConnection":
503
520
  connections.push(coerceChildAttrs("Flow", tag, getAttributes(child), errors));
504
521
  break;
505
522
  default:
506
- errors.push(`Unknown child element <${tag}> inside <Flow>. Expected: <FlowNode> or <Connection>`);
523
+ errors.push(`Unknown child element <${tag}> inside <Flow>. Expected: <FlowNode> or <FlowConnection>`);
507
524
  }
508
525
  }
509
526
  if (nodes.length > 0) {
@@ -518,8 +535,8 @@ function convertChartChildren(childElements, result, errors) {
518
535
  const data = [];
519
536
  for (const child of childElements) {
520
537
  const tag = getTagName(child);
521
- if (tag !== "Series") {
522
- errors.push(`Unknown child element <${tag}> inside <Chart>. Expected: <Series>`);
538
+ if (tag !== "ChartSeries") {
539
+ errors.push(`Unknown child element <${tag}> inside <Chart>. Expected: <ChartSeries>`);
523
540
  continue;
524
541
  }
525
542
  const attrs = getAttributes(child);
@@ -532,7 +549,7 @@ function convertChartChildren(childElements, result, errors) {
532
549
  if (nameSchema) {
533
550
  const coerced = coerceValue(attrs.name, nameSchema);
534
551
  if (coerced.error !== null) {
535
- errors.push(`<Chart>.<Series>: ${coerced.error}`);
552
+ errors.push(`<Chart>.<ChartSeries>: ${coerced.error}`);
536
553
  }
537
554
  else {
538
555
  series.name = coerced.value;
@@ -544,23 +561,23 @@ function convertChartChildren(childElements, result, errors) {
544
561
  }
545
562
  for (const dp of getChildElements(child)) {
546
563
  const dpTag = getTagName(dp);
547
- if (dpTag !== "DataPoint") {
548
- errors.push(`Unknown child element <${dpTag}> inside <Series>. Expected: <DataPoint>`);
564
+ if (dpTag !== "ChartDataPoint") {
565
+ errors.push(`Unknown child element <${dpTag}> inside <ChartSeries>. Expected: <ChartDataPoint>`);
549
566
  continue;
550
567
  }
551
568
  const dpAttrs = getAttributes(dp);
552
569
  if (dpAttrs.label === undefined) {
553
- errors.push('<DataPoint> requires a "label" attribute');
570
+ errors.push('<ChartDataPoint> requires a "label" attribute');
554
571
  }
555
572
  if (dpAttrs.value === undefined) {
556
- errors.push('<DataPoint> requires a "value" attribute');
573
+ errors.push('<ChartDataPoint> requires a "value" attribute');
557
574
  }
558
575
  if (dpAttrs.label === undefined || dpAttrs.value === undefined) {
559
576
  continue;
560
577
  }
561
578
  const numValue = Number(dpAttrs.value);
562
579
  if (isNaN(numValue)) {
563
- errors.push(`Cannot convert "${dpAttrs.value}" to number in <DataPoint> "value" attribute`);
580
+ errors.push(`Cannot convert "${dpAttrs.value}" to number in <ChartDataPoint> "value" attribute`);
564
581
  continue;
565
582
  }
566
583
  series.labels.push(dpAttrs.label);
@@ -576,19 +593,19 @@ function convertTableChildren(childElements, result, errors) {
576
593
  for (const child of childElements) {
577
594
  const tag = getTagName(child);
578
595
  switch (tag) {
579
- case "Column":
596
+ case "TableColumn":
580
597
  columns.push(coerceChildAttrs("Table", tag, getAttributes(child), errors));
581
598
  break;
582
- case "Row": {
599
+ case "TableRow": {
583
600
  const rowAttrs = getAttributes(child);
584
601
  const cells = [];
585
602
  for (const cellEl of getChildElements(child)) {
586
603
  const cellTag = getTagName(cellEl);
587
- if (cellTag !== "Cell") {
588
- errors.push(`Unknown child element <${cellTag}> inside <Row>. Expected: <Cell>`);
604
+ if (cellTag !== "TableCell") {
605
+ errors.push(`Unknown child element <${cellTag}> inside <TableRow>. Expected: <TableCell>`);
589
606
  continue;
590
607
  }
591
- const cellAttrs = coerceChildAttrs("Row", cellTag, getAttributes(cellEl), errors);
608
+ const cellAttrs = coerceChildAttrs("TableRow", cellTag, getAttributes(cellEl), errors);
592
609
  const cellText = getTextContent(cellEl);
593
610
  if (cellText !== undefined && !("text" in cellAttrs)) {
594
611
  cellAttrs.text = cellText;
@@ -599,7 +616,7 @@ function convertTableChildren(childElements, result, errors) {
599
616
  if (rowAttrs.height !== undefined) {
600
617
  const h = Number(rowAttrs.height);
601
618
  if (isNaN(h)) {
602
- errors.push(`Cannot convert "${rowAttrs.height}" to number in <Row> "height" attribute`);
619
+ errors.push(`Cannot convert "${rowAttrs.height}" to number in <TableRow> "height" attribute`);
603
620
  }
604
621
  else {
605
622
  row.height = h;
@@ -609,7 +626,7 @@ function convertTableChildren(childElements, result, errors) {
609
626
  break;
610
627
  }
611
628
  default:
612
- errors.push(`Unknown child element <${tag}> inside <Table>. Expected: <Column> or <Row>`);
629
+ errors.push(`Unknown child element <${tag}> inside <Table>. Expected: <TableColumn> or <TableRow>`);
613
630
  }
614
631
  }
615
632
  if (columns.length > 0) {
@@ -680,6 +697,7 @@ const CHILD_ELEMENT_CONVERTERS = {
680
697
  ul: (childElements, result, errors) => convertListChildren("Ul", childElements, result, errors),
681
698
  ol: (childElements, result, errors) => convertListChildren("Ol", childElements, result, errors),
682
699
  processArrow: convertProcessArrowChildren,
700
+ pyramid: convertPyramidChildren,
683
701
  timeline: convertTimelineChildren,
684
702
  matrix: convertMatrixChildren,
685
703
  flow: convertFlowChildren,
@@ -8,6 +8,7 @@ export { renderMatrixNode } from "./matrix.ts";
8
8
  export { renderTreeNode } from "./tree.ts";
9
9
  export { renderFlowNode } from "./flow.ts";
10
10
  export { renderProcessArrowNode } from "./processArrow.ts";
11
+ export { renderPyramidNode } from "./pyramid.ts";
11
12
  export { renderLineNode } from "./line.ts";
12
13
  export { renderUlNode, renderOlNode } from "./list.ts";
13
14
  //# 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,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"}
@@ -8,5 +8,6 @@ export { renderMatrixNode } from "./matrix.js";
8
8
  export { renderTreeNode } from "./tree.js";
9
9
  export { renderFlowNode } from "./flow.js";
10
10
  export { renderProcessArrowNode } from "./processArrow.js";
11
+ export { renderPyramidNode } from "./pyramid.js";
11
12
  export { renderLineNode } from "./line.js";
12
13
  export { renderUlNode, renderOlNode } from "./list.js";
@@ -1 +1 @@
1
- {"version":3,"file":"processArrow.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/processArrow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjD,KAAK,0BAA0B,GAAG,OAAO,CACvC,cAAc,EACd;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,CACzB,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,0BAA0B,EAChC,GAAG,EAAE,aAAa,GACjB,IAAI,CAsDN"}
1
+ {"version":3,"file":"processArrow.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/processArrow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAWjD,KAAK,0BAA0B,GAAG,OAAO,CACvC,cAAc,EACd;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,CACzB,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,0BAA0B,EAChC,GAAG,EAAE,aAAa,GACjB,IAAI,CA0DN"}
@@ -2,6 +2,7 @@ import { pxToIn, pxToPt } from "../units.js";
2
2
  import { convertUnderline, convertStrike } from "../textOptions.js";
3
3
  import { measureProcessArrow } from "../../calcYogaLayout/measureCompositeNodes.js";
4
4
  import { calcScaleFactor } from "../utils/scaleToFit.js";
5
+ import { ARROW_DEPTH_RATIO, DEFAULT_PROCESS_ARROW_ITEM_WIDTH, DEFAULT_PROCESS_ARROW_ITEM_HEIGHT, } from "../../shared/processArrowConstants.js";
5
6
  export function renderProcessArrowNode(node, ctx) {
6
7
  const direction = node.direction ?? "horizontal";
7
8
  const steps = node.steps;
@@ -10,23 +11,25 @@ export function renderProcessArrowNode(node, ctx) {
10
11
  return;
11
12
  const defaultColor = "4472C4"; // PowerPoint標準の青
12
13
  const defaultTextColor = "FFFFFF";
13
- const itemWidth = node.itemWidth ?? 150;
14
- const itemHeight = node.itemHeight ?? 60;
15
- const gap = node.gap ?? -15; // 負の値でシェブロンを重ねる
14
+ const itemWidth = node.itemWidth ?? DEFAULT_PROCESS_ARROW_ITEM_WIDTH;
15
+ const itemHeight = node.itemHeight ?? DEFAULT_PROCESS_ARROW_ITEM_HEIGHT;
16
+ const arrowDepth = itemHeight * ARROW_DEPTH_RATIO;
17
+ const gap = node.gap ?? -arrowDepth;
16
18
  // スケール係数を計算
17
19
  const intrinsic = measureProcessArrow(node);
18
20
  const scaleFactor = calcScaleFactor(node.w, node.h, intrinsic.width, intrinsic.height, "processArrow");
19
21
  const scaledItemWidth = itemWidth * scaleFactor;
20
22
  const scaledItemHeight = itemHeight * scaleFactor;
21
23
  const scaledGap = gap * scaleFactor;
24
+ const scaledArrowDepth = arrowDepth * scaleFactor;
22
25
  if (direction === "horizontal") {
23
- renderHorizontalProcessArrow(node, ctx, steps, stepCount, scaledItemWidth, scaledItemHeight, scaledGap, defaultColor, defaultTextColor, scaleFactor);
26
+ renderHorizontalProcessArrow(node, ctx, steps, stepCount, scaledItemWidth, scaledItemHeight, scaledGap, scaledArrowDepth, defaultColor, defaultTextColor, scaleFactor);
24
27
  }
25
28
  else {
26
- renderVerticalProcessArrow(node, ctx, steps, stepCount, scaledItemWidth, scaledItemHeight, scaledGap, defaultColor, defaultTextColor, scaleFactor);
29
+ renderVerticalProcessArrow(node, ctx, steps, stepCount, scaledItemWidth, scaledItemHeight, scaledGap, scaledArrowDepth, defaultColor, defaultTextColor, scaleFactor);
27
30
  }
28
31
  }
29
- function renderHorizontalProcessArrow(node, ctx, steps, stepCount, itemWidth, itemHeight, gap, defaultColor, defaultTextColor, scaleFactor) {
32
+ function renderHorizontalProcessArrow(node, ctx, steps, stepCount, itemWidth, itemHeight, gap, arrowDepth, defaultColor, defaultTextColor, scaleFactor) {
30
33
  const totalWidth = stepCount * itemWidth + (stepCount - 1) * gap;
31
34
  const startX = node.x + (node.w - totalWidth) / 2;
32
35
  const centerY = node.y + node.h / 2;
@@ -35,16 +38,45 @@ function renderHorizontalProcessArrow(node, ctx, steps, stepCount, itemWidth, it
35
38
  const stepY = centerY - itemHeight / 2;
36
39
  const fillColor = step.color?.replace("#", "") ?? defaultColor;
37
40
  const textColor = step.textColor?.replace("#", "") ?? defaultTextColor;
38
- // 最初のステップは homePlate、以降は chevron
39
- const shapeType = index === 0 ? ctx.pptx.ShapeType.homePlate : ctx.pptx.ShapeType.chevron;
40
- ctx.slide.addText(step.label, {
41
+ // custGeom でシェブロン形状を描画
42
+ const isFirst = index === 0;
43
+ const points = isFirst
44
+ ? [
45
+ // homePlate 風: 左辺フラット、右辺が矢印
46
+ { x: 0, y: 0 },
47
+ { x: pxToIn(itemWidth - arrowDepth), y: 0 },
48
+ { x: pxToIn(itemWidth), y: pxToIn(itemHeight / 2) },
49
+ { x: pxToIn(itemWidth - arrowDepth), y: pxToIn(itemHeight) },
50
+ { x: 0, y: pxToIn(itemHeight) },
51
+ { close: true },
52
+ ]
53
+ : [
54
+ // chevron 風: 左辺に切り欠き、右辺が矢印
55
+ { x: 0, y: 0 },
56
+ { x: pxToIn(itemWidth - arrowDepth), y: 0 },
57
+ { x: pxToIn(itemWidth), y: pxToIn(itemHeight / 2) },
58
+ { x: pxToIn(itemWidth - arrowDepth), y: pxToIn(itemHeight) },
59
+ { x: 0, y: pxToIn(itemHeight) },
60
+ { x: pxToIn(arrowDepth), y: pxToIn(itemHeight / 2) },
61
+ { close: true },
62
+ ];
63
+ ctx.slide.addShape("custGeom", {
41
64
  x: pxToIn(stepX),
42
65
  y: pxToIn(stepY),
43
66
  w: pxToIn(itemWidth),
44
67
  h: pxToIn(itemHeight),
45
- shape: shapeType,
68
+ points,
46
69
  fill: { color: fillColor },
47
70
  line: { type: "none" },
71
+ });
72
+ // テキストを図形の中央(矢印部分を除いた領域)に配置
73
+ const textOffsetLeft = isFirst ? 0 : arrowDepth;
74
+ const textWidth = Math.max(1, itemWidth - arrowDepth - textOffsetLeft);
75
+ ctx.slide.addText(step.label, {
76
+ x: pxToIn(stepX + textOffsetLeft),
77
+ y: pxToIn(stepY),
78
+ w: pxToIn(textWidth),
79
+ h: pxToIn(itemHeight),
48
80
  fontSize: pxToPt((node.fontPx ?? 14) * scaleFactor),
49
81
  fontFace: "Noto Sans JP",
50
82
  color: textColor,
@@ -58,7 +90,7 @@ function renderHorizontalProcessArrow(node, ctx, steps, stepCount, itemWidth, it
58
90
  });
59
91
  });
60
92
  }
61
- function renderVerticalProcessArrow(node, ctx, steps, stepCount, itemWidth, itemHeight, gap, defaultColor, defaultTextColor, scaleFactor) {
93
+ function renderVerticalProcessArrow(node, ctx, steps, stepCount, itemWidth, itemHeight, gap, arrowDepth, defaultColor, defaultTextColor, scaleFactor) {
62
94
  const totalHeight = stepCount * itemHeight + (stepCount - 1) * gap;
63
95
  const startY = node.y + (node.h - totalHeight) / 2;
64
96
  const centerX = node.x + node.w / 2;
@@ -67,16 +99,44 @@ function renderVerticalProcessArrow(node, ctx, steps, stepCount, itemWidth, item
67
99
  const stepY = startY + index * (itemHeight + gap);
68
100
  const fillColor = step.color?.replace("#", "") ?? defaultColor;
69
101
  const textColor = step.textColor?.replace("#", "") ?? defaultTextColor;
70
- // 垂直方向では pentagon を使用(下向き矢印風)
71
- const shapeType = index === 0 ? ctx.pptx.ShapeType.rect : ctx.pptx.ShapeType.pentagon;
72
- ctx.slide.addText(step.label, {
102
+ const isFirst = index === 0;
103
+ const points = isFirst
104
+ ? [
105
+ // rect 風: 上辺フラット、下辺が矢印
106
+ { x: 0, y: 0 },
107
+ { x: pxToIn(itemWidth), y: 0 },
108
+ { x: pxToIn(itemWidth), y: pxToIn(itemHeight - arrowDepth) },
109
+ { x: pxToIn(itemWidth / 2), y: pxToIn(itemHeight) },
110
+ { x: 0, y: pxToIn(itemHeight - arrowDepth) },
111
+ { close: true },
112
+ ]
113
+ : [
114
+ // pentagon 風: 上辺に切り欠き、下辺が矢印
115
+ { x: pxToIn(itemWidth / 2), y: 0 },
116
+ { x: pxToIn(itemWidth), y: pxToIn(arrowDepth) },
117
+ { x: pxToIn(itemWidth), y: pxToIn(itemHeight - arrowDepth) },
118
+ { x: pxToIn(itemWidth / 2), y: pxToIn(itemHeight) },
119
+ { x: 0, y: pxToIn(itemHeight - arrowDepth) },
120
+ { x: 0, y: pxToIn(arrowDepth) },
121
+ { close: true },
122
+ ];
123
+ ctx.slide.addShape("custGeom", {
73
124
  x: pxToIn(stepX),
74
125
  y: pxToIn(stepY),
75
126
  w: pxToIn(itemWidth),
76
127
  h: pxToIn(itemHeight),
77
- shape: shapeType,
128
+ points,
78
129
  fill: { color: fillColor },
79
130
  line: { type: "none" },
131
+ });
132
+ // テキストを図形の中央(矢印部分を除いた領域)に配置
133
+ const textOffsetTop = isFirst ? 0 : arrowDepth;
134
+ const textHeight = Math.max(1, itemHeight - arrowDepth - textOffsetTop);
135
+ ctx.slide.addText(step.label, {
136
+ x: pxToIn(stepX),
137
+ y: pxToIn(stepY + textOffsetTop),
138
+ w: pxToIn(itemWidth),
139
+ h: pxToIn(textHeight),
80
140
  fontSize: pxToPt((node.fontPx ?? 14) * scaleFactor),
81
141
  fontFace: "Noto Sans JP",
82
142
  color: textColor,
@@ -0,0 +1,8 @@
1
+ import type { PositionedNode } from "../../types.ts";
2
+ import type { RenderContext } from "../types.ts";
3
+ type PyramidPositionedNode = Extract<PositionedNode, {
4
+ type: "pyramid";
5
+ }>;
6
+ export declare function renderPyramidNode(node: PyramidPositionedNode, ctx: RenderContext): void;
7
+ export {};
8
+ //# sourceMappingURL=pyramid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pyramid.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/pyramid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,KAAK,qBAAqB,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AAE1E,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,qBAAqB,EAC3B,GAAG,EAAE,aAAa,GACjB,IAAI,CAgGN"}
@@ -0,0 +1,81 @@
1
+ import { pxToIn, pxToPt } from "../units.js";
2
+ import { measurePyramid } from "../../calcYogaLayout/measureCompositeNodes.js";
3
+ import { calcScaleFactor } from "../utils/scaleToFit.js";
4
+ export function renderPyramidNode(node, ctx) {
5
+ const direction = node.direction ?? "up";
6
+ const levels = node.levels;
7
+ const levelCount = levels.length;
8
+ if (levelCount === 0)
9
+ return;
10
+ const defaultColor = "4472C4";
11
+ const defaultTextColor = "FFFFFF";
12
+ // スケール係数を計算
13
+ const intrinsic = measurePyramid(node);
14
+ const scaleFactor = calcScaleFactor(node.w, node.h, intrinsic.width, intrinsic.height, "pyramid");
15
+ const baseWidth = 400 * scaleFactor;
16
+ const layerHeight = 50 * scaleFactor;
17
+ const gap = 2 * scaleFactor;
18
+ const totalHeight = levelCount * layerHeight + (levelCount - 1) * gap;
19
+ const startX = node.x + (node.w - baseWidth) / 2;
20
+ const startY = node.y + (node.h - totalHeight) / 2;
21
+ for (let i = 0; i < levelCount; i++) {
22
+ const level = levels[i];
23
+ const fillColor = level.color?.replace("#", "") ?? defaultColor;
24
+ const textColor = level.textColor?.replace("#", "") ?? defaultTextColor;
25
+ const layerY = startY + i * (layerHeight + gap);
26
+ // direction="up": i=0 が最上段(最も狭い=三角形)、i=levelCount-1 が最下段(最も広い)
27
+ // direction="down": i=0 が最上段(最も広い)、i=levelCount-1 が最下段(最も狭い=三角形)
28
+ // 頂点層の上辺は幅0(三角形)、それ以外は台形
29
+ let topWidthRatio;
30
+ let bottomWidthRatio;
31
+ if (direction === "up") {
32
+ topWidthRatio = i / levelCount;
33
+ bottomWidthRatio = (i + 1) / levelCount;
34
+ }
35
+ else {
36
+ topWidthRatio = (levelCount - i) / levelCount;
37
+ bottomWidthRatio = (levelCount - i - 1) / levelCount;
38
+ }
39
+ const topWidth = baseWidth * topWidthRatio;
40
+ const bottomWidth = baseWidth * bottomWidthRatio;
41
+ const topLeftX = startX + (baseWidth - topWidth) / 2;
42
+ const topRightX = topLeftX + topWidth;
43
+ const bottomLeftX = startX + (baseWidth - bottomWidth) / 2;
44
+ const bottomRightX = bottomLeftX + bottomWidth;
45
+ // custGeom のバウンディングボックス
46
+ const bboxX = Math.min(topLeftX, bottomLeftX);
47
+ const bboxW = Math.max(topRightX, bottomRightX) - bboxX;
48
+ // points はバウンディングボックス内の相対インチ座標
49
+ const points = [
50
+ { x: pxToIn(topLeftX - bboxX), y: 0 },
51
+ { x: pxToIn(topRightX - bboxX), y: 0 },
52
+ { x: pxToIn(bottomRightX - bboxX), y: pxToIn(layerHeight) },
53
+ { x: pxToIn(bottomLeftX - bboxX), y: pxToIn(layerHeight) },
54
+ { close: true },
55
+ ];
56
+ // 図形を描画(頂点層は三角形、それ以外は台形)
57
+ ctx.slide.addShape("custGeom", {
58
+ x: pxToIn(bboxX),
59
+ y: pxToIn(layerY),
60
+ w: pxToIn(bboxW),
61
+ h: pxToIn(layerHeight),
62
+ points,
63
+ fill: { color: fillColor },
64
+ line: { type: "none" },
65
+ });
66
+ // テキストを図形の中央に重ねて描画
67
+ ctx.slide.addText(level.label, {
68
+ x: pxToIn(bboxX),
69
+ y: pxToIn(layerY),
70
+ w: pxToIn(bboxW),
71
+ h: pxToIn(layerHeight),
72
+ fontSize: pxToPt((node.fontPx ?? 14) * scaleFactor),
73
+ fontFace: "Noto Sans JP",
74
+ color: textColor,
75
+ bold: node.bold ?? false,
76
+ align: "center",
77
+ valign: "middle",
78
+ autoFit: true,
79
+ });
80
+ }
81
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAQjD,KAAK,mBAAmB,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEtE,wBAAgB,eAAe,CAC7B,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,aAAa,GACjB,IAAI,CAmCN"}
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/renderPptx/nodes/table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAQjD,KAAK,mBAAmB,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEtE,wBAAgB,eAAe,CAC7B,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,aAAa,GACjB,IAAI,CAqCN"}
@@ -15,6 +15,8 @@ export function renderTableNode(node, ctx) {
15
15
  fill: cell.backgroundColor
16
16
  ? { color: cell.backgroundColor }
17
17
  : undefined,
18
+ colspan: cell.colspan,
19
+ rowspan: cell.rowspan,
18
20
  };
19
21
  return {
20
22
  text: cell.text,
@@ -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;AAsBrB,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,+BA6K5B"}
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;AAuBrB,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,+BAiL5B"}
@@ -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, renderLineNode, renderUlNode, renderOlNode, } from "./nodes/index.js";
12
+ import { renderTextNode, renderImageNode, renderTableNode, renderShapeNode, renderChartNode, renderTimelineNode, renderMatrixNode, renderTreeNode, renderFlowNode, renderProcessArrowNode, renderPyramidNode, renderLineNode, renderUlNode, renderOlNode, } from "./nodes/index.js";
13
13
  const DEFAULT_MASTER_NAME = "POM_MASTER";
14
14
  /**
15
15
  * MasterObject を pptxgenjs の objects 形式に変換する
@@ -282,6 +282,9 @@ export function renderPptx(pages, slidePx, master) {
282
282
  case "processArrow":
283
283
  renderProcessArrowNode(node, ctx);
284
284
  break;
285
+ case "pyramid":
286
+ renderPyramidNode(node, ctx);
287
+ break;
285
288
  case "line":
286
289
  renderLineNode(node, ctx);
287
290
  break;
@@ -0,0 +1,7 @@
1
+ /** 矢印の先端/切り欠きの深さ(itemHeight に対する比率) */
2
+ export declare const ARROW_DEPTH_RATIO = 0.35;
3
+ /** ProcessArrow のデフォルト itemHeight(px) */
4
+ export declare const DEFAULT_PROCESS_ARROW_ITEM_HEIGHT = 80;
5
+ /** ProcessArrow のデフォルト itemWidth(px) */
6
+ export declare const DEFAULT_PROCESS_ARROW_ITEM_WIDTH = 150;
7
+ //# sourceMappingURL=processArrowConstants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processArrowConstants.d.ts","sourceRoot":"","sources":["../../src/shared/processArrowConstants.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAEtC,yCAAyC;AACzC,eAAO,MAAM,iCAAiC,KAAK,CAAC;AAEpD,wCAAwC;AACxC,eAAO,MAAM,gCAAgC,MAAM,CAAC"}
@@ -0,0 +1,6 @@
1
+ /** 矢印の先端/切り欠きの深さ(itemHeight に対する比率) */
2
+ export const ARROW_DEPTH_RATIO = 0.35;
3
+ /** ProcessArrow のデフォルト itemHeight(px) */
4
+ export const DEFAULT_PROCESS_ARROW_ITEM_HEIGHT = 80;
5
+ /** ProcessArrow のデフォルト itemWidth(px) */
6
+ export const DEFAULT_PROCESS_ARROW_ITEM_WIDTH = 150;
@@ -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;AAG3D;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,OAAO,EACZ,OAAO,SAAI,EACX,OAAO,SAAI,GACV,cAAc,CA2MhB"}
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;AAG3D;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,OAAO,EACZ,OAAO,SAAI,EACX,OAAO,SAAI,GACV,cAAc,CAoNhB"}
@@ -108,6 +108,15 @@ export function toPositioned(pom, parentX = 0, parentY = 0) {
108
108
  h: layout.height,
109
109
  };
110
110
  }
111
+ case "pyramid": {
112
+ return {
113
+ ...pom,
114
+ x: absoluteX,
115
+ y: absoluteY,
116
+ w: layout.width,
117
+ h: layout.height,
118
+ };
119
+ }
111
120
  case "box": {
112
121
  return {
113
122
  ...pom,