yumiamd 0.1.30 → 0.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +1 -1
- package/dist/{chunk-MXMPDHHS.js → chunk-Y2OWK5OP.js} +393 -174
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -1
- package/package.json +10 -10
package/dist/bin.js
CHANGED
|
@@ -2193,7 +2193,7 @@ var NativeYumiaParser = class {
|
|
|
2193
2193
|
}
|
|
2194
2194
|
} else if (dLine.startsWith("node ")) {
|
|
2195
2195
|
const nParts = dLine.slice(5).trim();
|
|
2196
|
-
const nIdMatch = nParts.match(/^(\
|
|
2196
|
+
const nIdMatch = nParts.match(/^(\[[^\]]+\]|\([^)]+\)|\{[^}]+\}|[a-zA-Z0-9_-]+(?:\[\([^)]+\)\]|\(\([^)]+\)\)|\[[^\]]+\]|\{[^}]+\})?)/);
|
|
2197
2197
|
const nLabelMatch = nParts.match(/\blabel=["']([^"']+)["']/);
|
|
2198
2198
|
const nShapeMatch = nParts.match(/\bshape=["']?([^"'\s]+)["']?/);
|
|
2199
2199
|
const nVarMatch = nParts.match(/\bvariant=["']?([^"'\s]+)["']?/);
|
|
@@ -2202,6 +2202,7 @@ var NativeYumiaParser = class {
|
|
|
2202
2202
|
const explicitLabel = nLabelMatch ? nLabelMatch[1] : void 0;
|
|
2203
2203
|
const node = ensureNode(nId, nShapeMatch ? nShapeMatch[1] : void 0, nVarMatch ? nVarMatch[1] : void 0, explicitLabel);
|
|
2204
2204
|
nodeMap.set(nId.toLowerCase(), node);
|
|
2205
|
+
nodeMap.set(node.id, node);
|
|
2205
2206
|
}
|
|
2206
2207
|
}
|
|
2207
2208
|
nextIdx++;
|
|
@@ -2753,9 +2754,17 @@ function computeDiagramLayout(diagram, availableWidth, isLR = (diagram.direction
|
|
|
2753
2754
|
};
|
|
2754
2755
|
if (nodeIds.length === 0)
|
|
2755
2756
|
return empty;
|
|
2757
|
+
const connected = /* @__PURE__ */ new Set();
|
|
2758
|
+
diagram.edges.forEach((e) => {
|
|
2759
|
+
connected.add(e.from);
|
|
2760
|
+
connected.add(e.to);
|
|
2761
|
+
});
|
|
2762
|
+
const activeIds = connected.size > 0 ? nodeIds.filter((id) => connected.has(id)) : nodeIds;
|
|
2763
|
+
if (activeIds.length === 0)
|
|
2764
|
+
return empty;
|
|
2756
2765
|
const inDegree = {};
|
|
2757
2766
|
const adj = {};
|
|
2758
|
-
|
|
2767
|
+
activeIds.forEach((id) => {
|
|
2759
2768
|
inDegree[id] = 0;
|
|
2760
2769
|
adj[id] = [];
|
|
2761
2770
|
});
|
|
@@ -2769,20 +2778,20 @@ function computeDiagramLayout(diagram, availableWidth, isLR = (diagram.direction
|
|
|
2769
2778
|
});
|
|
2770
2779
|
const ranks = {};
|
|
2771
2780
|
const queue = [];
|
|
2772
|
-
const visitBudget = Math.max(4,
|
|
2781
|
+
const visitBudget = Math.max(4, activeIds.length * 2);
|
|
2773
2782
|
const visits = {};
|
|
2774
|
-
|
|
2783
|
+
activeIds.forEach((id) => {
|
|
2775
2784
|
if (inDegree[id] === 0) {
|
|
2776
2785
|
ranks[id] = 0;
|
|
2777
2786
|
queue.push(id);
|
|
2778
2787
|
}
|
|
2779
2788
|
});
|
|
2780
2789
|
if (queue.length === 0) {
|
|
2781
|
-
ranks[
|
|
2782
|
-
queue.push(
|
|
2790
|
+
ranks[activeIds[0]] = 0;
|
|
2791
|
+
queue.push(activeIds[0]);
|
|
2783
2792
|
}
|
|
2784
2793
|
let steps = 0;
|
|
2785
|
-
const maxSteps =
|
|
2794
|
+
const maxSteps = activeIds.length * activeIds.length + 8;
|
|
2786
2795
|
while (queue.length > 0 && steps < maxSteps) {
|
|
2787
2796
|
steps++;
|
|
2788
2797
|
const u = queue.shift();
|
|
@@ -2791,7 +2800,7 @@ function computeDiagramLayout(diagram, availableWidth, isLR = (diagram.direction
|
|
|
2791
2800
|
continue;
|
|
2792
2801
|
const r = ranks[u] ?? 0;
|
|
2793
2802
|
for (const v of adj[u] || []) {
|
|
2794
|
-
const nextR = Math.min(
|
|
2803
|
+
const nextR = Math.min(activeIds.length - 1, r + 1);
|
|
2795
2804
|
if (ranks[v] === void 0 || ranks[v] < nextR) {
|
|
2796
2805
|
ranks[v] = nextR;
|
|
2797
2806
|
if ((visits[v] || 0) <= visitBudget) {
|
|
@@ -2800,13 +2809,13 @@ function computeDiagramLayout(diagram, availableWidth, isLR = (diagram.direction
|
|
|
2800
2809
|
}
|
|
2801
2810
|
}
|
|
2802
2811
|
}
|
|
2803
|
-
|
|
2812
|
+
activeIds.forEach((id, idx) => {
|
|
2804
2813
|
if (ranks[id] === void 0) {
|
|
2805
|
-
ranks[id] = Math.min(idx,
|
|
2814
|
+
ranks[id] = Math.min(idx, activeIds.length - 1);
|
|
2806
2815
|
}
|
|
2807
2816
|
});
|
|
2808
2817
|
const rankGroups = {};
|
|
2809
|
-
|
|
2818
|
+
activeIds.forEach((id) => {
|
|
2810
2819
|
const r = ranks[id] ?? 0;
|
|
2811
2820
|
if (!rankGroups[r])
|
|
2812
2821
|
rankGroups[r] = [];
|
|
@@ -2819,13 +2828,14 @@ function computeDiagramLayout(diagram, availableWidth, isLR = (diagram.direction
|
|
|
2819
2828
|
maxLane = Math.max(maxLane, rankGroups[r].length);
|
|
2820
2829
|
});
|
|
2821
2830
|
const titleOffset = diagram.title ? options.titleHeight ?? 28 : 0;
|
|
2822
|
-
const gapX = isLR ?
|
|
2823
|
-
const gapY = isLR ?
|
|
2824
|
-
const nodeWidth = isLR ? Math.max(
|
|
2825
|
-
const
|
|
2826
|
-
const
|
|
2831
|
+
const gapX = isLR ? 36 : 24;
|
|
2832
|
+
const gapY = isLR ? 22 : 32;
|
|
2833
|
+
const nodeWidth = isLR ? Math.max(100, Math.min(260, (availableWidth - 48 - gapX * (numRanks - 1)) / numRanks)) : Math.max(100, Math.min(220, (availableWidth - 48 - gapX * (maxLane - 1)) / Math.max(1, maxLane)));
|
|
2834
|
+
const activeNodes = diagram.nodes.filter((n) => activeIds.includes(n.id));
|
|
2835
|
+
const longestLabel = Math.max(1, ...activeNodes.map((n) => (n.label || n.id).length));
|
|
2836
|
+
const charsPerLine = Math.max(8, Math.floor((nodeWidth - 16) / 6.5));
|
|
2827
2837
|
const labelLines = Math.max(1, Math.ceil(longestLabel / charsPerLine));
|
|
2828
|
-
const nodeHeight = Math.max(
|
|
2838
|
+
const nodeHeight = Math.max(40, Math.min(84, 20 + labelLines * 16));
|
|
2829
2839
|
const contentH = isLR ? maxLane * (nodeHeight + gapY) - gapY : numRanks * (nodeHeight + gapY) - gapY;
|
|
2830
2840
|
const height = titleOffset + 24 + contentH + 16;
|
|
2831
2841
|
const originX = options.originX ?? 0;
|
|
@@ -2872,6 +2882,28 @@ function computeDiagramLayout(diagram, availableWidth, isLR = (diagram.direction
|
|
|
2872
2882
|
positions
|
|
2873
2883
|
};
|
|
2874
2884
|
}
|
|
2885
|
+
function orthogonalEdgePoints(isLR, p1, p2, nodeW, nodeH) {
|
|
2886
|
+
const x1 = isLR ? p1.x + nodeW : p1.x + nodeW / 2;
|
|
2887
|
+
const y1 = isLR ? p1.y + nodeH / 2 : p1.y + nodeH;
|
|
2888
|
+
const x2 = isLR ? p2.x : p2.x + nodeW / 2;
|
|
2889
|
+
const y2 = isLR ? p2.y + nodeH / 2 : p2.y;
|
|
2890
|
+
if (isLR) {
|
|
2891
|
+
const midX = (x1 + x2) / 2;
|
|
2892
|
+
return [
|
|
2893
|
+
{ x: x1, y: y1 },
|
|
2894
|
+
{ x: midX, y: y1 },
|
|
2895
|
+
{ x: midX, y: y2 },
|
|
2896
|
+
{ x: x2, y: y2 }
|
|
2897
|
+
];
|
|
2898
|
+
}
|
|
2899
|
+
const midY = (y1 + y2) / 2;
|
|
2900
|
+
return [
|
|
2901
|
+
{ x: x1, y: y1 },
|
|
2902
|
+
{ x: x1, y: midY },
|
|
2903
|
+
{ x: x2, y: midY },
|
|
2904
|
+
{ x: x2, y: y2 }
|
|
2905
|
+
];
|
|
2906
|
+
}
|
|
2875
2907
|
function fitDiagramLabel(label, maxChars) {
|
|
2876
2908
|
const clean = label.replace(/\s+/g, " ").trim();
|
|
2877
2909
|
if (clean.length <= maxChars)
|
|
@@ -2934,18 +2966,19 @@ var DefaultLayoutEngine = class {
|
|
|
2934
2966
|
layoutElementList(elements, startX, startY, availableWidth, gap) {
|
|
2935
2967
|
let currentY = startY;
|
|
2936
2968
|
const nodes = [];
|
|
2969
|
+
const compactHero = elements.length > 1 && elements.some((el) => el.type === "hero");
|
|
2937
2970
|
for (const element of elements) {
|
|
2938
|
-
const node = this.layoutSingleElement(element, startX, currentY, availableWidth, gap);
|
|
2971
|
+
const node = this.layoutSingleElement(element, startX, currentY, availableWidth, gap, compactHero);
|
|
2939
2972
|
nodes.push(node);
|
|
2940
2973
|
currentY += node.bounds.height + gap;
|
|
2941
2974
|
}
|
|
2942
2975
|
const totalHeight = elements.length > 0 ? currentY - startY - gap : 0;
|
|
2943
2976
|
return { nodes, totalHeight };
|
|
2944
2977
|
}
|
|
2945
|
-
layoutSingleElement(element, x, y, width, gap) {
|
|
2978
|
+
layoutSingleElement(element, x, y, width, gap, compactHero = false) {
|
|
2946
2979
|
switch (element.type) {
|
|
2947
2980
|
case "hero": {
|
|
2948
|
-
return this.layoutHero(element, x, y, width, gap);
|
|
2981
|
+
return this.layoutHero(element, x, y, width, gap, compactHero);
|
|
2949
2982
|
}
|
|
2950
2983
|
case "heading": {
|
|
2951
2984
|
const height = this.estimateHeadingHeight(element, width);
|
|
@@ -2960,7 +2993,7 @@ var DefaultLayoutEngine = class {
|
|
|
2960
2993
|
return { element, bounds: { x, y, width, height } };
|
|
2961
2994
|
}
|
|
2962
2995
|
case "code": {
|
|
2963
|
-
const height = this.estimateCodeHeight(element);
|
|
2996
|
+
const height = this.estimateCodeHeight(element, width);
|
|
2964
2997
|
return { element, bounds: { x, y, width, height } };
|
|
2965
2998
|
}
|
|
2966
2999
|
case "quote": {
|
|
@@ -2982,11 +3015,11 @@ var DefaultLayoutEngine = class {
|
|
|
2982
3015
|
case "callout": {
|
|
2983
3016
|
const c = element;
|
|
2984
3017
|
const lines = Math.ceil(c.text.length / Math.max(15, Math.floor(width / 14))) || 1;
|
|
2985
|
-
const height = Math.max(
|
|
3018
|
+
const height = Math.max(100, lines * 30 + (c.title ? 52 : 0) + 40);
|
|
2986
3019
|
return { element, bounds: { x, y, width, height } };
|
|
2987
3020
|
}
|
|
2988
3021
|
case "badge": {
|
|
2989
|
-
return { element, bounds: { x, y, width, height:
|
|
3022
|
+
return { element, bounds: { x, y, width, height: 52 } };
|
|
2990
3023
|
}
|
|
2991
3024
|
case "math": {
|
|
2992
3025
|
const height = 90;
|
|
@@ -3061,47 +3094,61 @@ var DefaultLayoutEngine = class {
|
|
|
3061
3094
|
}
|
|
3062
3095
|
}
|
|
3063
3096
|
}
|
|
3064
|
-
layoutHero(element, x, y, width, gap) {
|
|
3097
|
+
layoutHero(element, x, y, width, gap, compact = false) {
|
|
3065
3098
|
let curY = y;
|
|
3066
3099
|
if (element.badge || element.tagline) {
|
|
3067
|
-
curY +=
|
|
3100
|
+
curY += compact ? 44 : 56;
|
|
3068
3101
|
}
|
|
3069
|
-
const charsPerLineTitle = Math.max(
|
|
3102
|
+
const charsPerLineTitle = Math.max(10, Math.floor(width / (compact ? 36 : 30)));
|
|
3070
3103
|
const titleLines = Math.max(1, Math.ceil(element.title.length / charsPerLineTitle));
|
|
3071
|
-
const titleHeight = Math.max(
|
|
3104
|
+
const titleHeight = compact ? Math.max(72, titleLines * 52 + 16) : Math.max(110, titleLines * 76 + 28);
|
|
3072
3105
|
curY += titleHeight;
|
|
3073
3106
|
if (element.subtitle) {
|
|
3074
|
-
const charsPerLineSub = Math.max(
|
|
3107
|
+
const charsPerLineSub = Math.max(18, Math.floor(width / (compact ? 22 : 18)));
|
|
3075
3108
|
const subLines = Math.max(1, Math.ceil(element.subtitle.length / charsPerLineSub));
|
|
3076
|
-
const subHeight = Math.max(
|
|
3109
|
+
const subHeight = compact ? Math.max(44, subLines * 34 + 12) : Math.max(64, subLines * 40 + 18);
|
|
3077
3110
|
curY += subHeight;
|
|
3078
3111
|
}
|
|
3079
|
-
curY +=
|
|
3112
|
+
curY += compact ? 14 : 20;
|
|
3080
3113
|
const children = [];
|
|
3081
3114
|
if (element.elements) {
|
|
3082
3115
|
for (const child of element.elements) {
|
|
3083
|
-
const node = this.layoutSingleElement(child, x, curY, width, gap);
|
|
3116
|
+
const node = this.layoutSingleElement(child, x, curY, width, gap, false);
|
|
3084
3117
|
children.push(node);
|
|
3085
3118
|
curY += node.bounds.height + gap;
|
|
3086
3119
|
}
|
|
3087
3120
|
}
|
|
3088
|
-
return {
|
|
3121
|
+
return {
|
|
3122
|
+
element,
|
|
3123
|
+
bounds: { x, y, width, height: Math.max(curY - y, compact ? 120 : 160) },
|
|
3124
|
+
children
|
|
3125
|
+
};
|
|
3089
3126
|
}
|
|
3090
3127
|
layoutGrid(element, x, y, width, gap) {
|
|
3091
3128
|
const colCount = typeof element.columns === "number" ? element.columns : parseInt(String(element.columns), 10) || 2;
|
|
3092
|
-
const
|
|
3129
|
+
const rawGap = element.gap !== void 0 ? Number(element.gap) : gap;
|
|
3130
|
+
const gridGap = Number.isFinite(rawGap) && rawGap >= 0 ? rawGap : gap;
|
|
3131
|
+
const totalGap = gridGap * (colCount - 1);
|
|
3093
3132
|
const colWidth = Math.max(10, (width - totalGap) / colCount);
|
|
3094
3133
|
const children = [];
|
|
3095
3134
|
const colYs = Array(colCount).fill(y);
|
|
3096
3135
|
for (let i = 0; i < element.elements.length; i++) {
|
|
3097
3136
|
const colIdx = i % colCount;
|
|
3098
|
-
const colX = x + colIdx * (colWidth +
|
|
3137
|
+
const colX = x + colIdx * (colWidth + gridGap);
|
|
3099
3138
|
const childEl = element.elements[i];
|
|
3100
3139
|
const childNode = this.layoutSingleElement(childEl, colX, colYs[colIdx], colWidth, gap);
|
|
3101
3140
|
children.push(childNode);
|
|
3102
|
-
colYs[colIdx] += childNode.bounds.height +
|
|
3141
|
+
colYs[colIdx] += childNode.bounds.height + gridGap;
|
|
3142
|
+
}
|
|
3143
|
+
const rowCount = Math.ceil(children.length / colCount);
|
|
3144
|
+
for (let row = 0; row < rowCount; row++) {
|
|
3145
|
+
const rowNodes = children.slice(row * colCount, row * colCount + colCount);
|
|
3146
|
+
const rowMax = Math.max(...rowNodes.map((n) => n.bounds.height), 0);
|
|
3147
|
+
for (const node of rowNodes) {
|
|
3148
|
+
node.bounds.height = rowMax;
|
|
3149
|
+
}
|
|
3103
3150
|
}
|
|
3104
|
-
const maxGridHeight = Math.max(...
|
|
3151
|
+
const maxGridHeight = Math.max(...children.map((n) => n.bounds.y + n.bounds.height - y), 100);
|
|
3105
3152
|
return {
|
|
3106
3153
|
element,
|
|
3107
3154
|
bounds: { x, y, width, height: maxGridHeight },
|
|
@@ -3109,12 +3156,13 @@ var DefaultLayoutEngine = class {
|
|
|
3109
3156
|
};
|
|
3110
3157
|
}
|
|
3111
3158
|
layoutCompare(element, x, y, width, gap) {
|
|
3112
|
-
const
|
|
3113
|
-
const
|
|
3114
|
-
const
|
|
3159
|
+
const vsGap = Math.max(gap, 56);
|
|
3160
|
+
const colW = (width - vsGap) / 2;
|
|
3161
|
+
const titleH = 56;
|
|
3162
|
+
const pad = 28;
|
|
3115
3163
|
const leftStartY = y + pad + (element.leftTitle ? titleH : 0);
|
|
3116
3164
|
const { nodes: leftChildren, totalHeight: leftInnerH } = this.layoutElementList(element.left, x + pad, leftStartY, colW - pad * 2, gap / 2);
|
|
3117
|
-
const rightX = x + colW +
|
|
3165
|
+
const rightX = x + colW + vsGap;
|
|
3118
3166
|
const rightStartY = y + pad + (element.rightTitle ? titleH : 0);
|
|
3119
3167
|
const { nodes: rightChildren, totalHeight: rightInnerH } = this.layoutElementList(element.right, rightX + pad, rightStartY, colW - pad * 2, gap / 2);
|
|
3120
3168
|
const totalHeight = Math.max(leftInnerH, rightInnerH, 120) + (element.leftTitle || element.rightTitle ? titleH : 0) + pad * 2;
|
|
@@ -3144,11 +3192,12 @@ var DefaultLayoutEngine = class {
|
|
|
3144
3192
|
}
|
|
3145
3193
|
}
|
|
3146
3194
|
layoutCard(element, x, y, width, gap) {
|
|
3147
|
-
const cardPadding =
|
|
3195
|
+
const cardPadding = 28;
|
|
3148
3196
|
const innerWidth = Math.max(10, width - cardPadding * 2);
|
|
3149
|
-
const titleHeight = element.title ?
|
|
3197
|
+
const titleHeight = element.title ? 56 : 0;
|
|
3150
3198
|
const innerStartY = y + cardPadding + titleHeight;
|
|
3151
|
-
const
|
|
3199
|
+
const innerGap = Math.min(12, Math.max(6, Math.round(gap * 0.4)));
|
|
3200
|
+
const { nodes: children, totalHeight: innerHeight } = this.layoutElementList(element.elements, x + cardPadding, innerStartY, innerWidth, innerGap);
|
|
3152
3201
|
const cardHeight = titleHeight + innerHeight + cardPadding * 2 + 12;
|
|
3153
3202
|
const bounds = { x, y, width, height: Math.max(120, cardHeight) };
|
|
3154
3203
|
return {
|
|
@@ -3200,30 +3249,36 @@ var DefaultLayoutEngine = class {
|
|
|
3200
3249
|
}
|
|
3201
3250
|
estimateHeadingHeight(heading, width = 1600) {
|
|
3202
3251
|
const fontSize = heading.level === 1 ? 46 : heading.level === 2 ? 36 : 28;
|
|
3203
|
-
const charWidth = fontSize * 0.
|
|
3204
|
-
const charsPerLine = Math.max(
|
|
3252
|
+
const charWidth = fontSize * 0.62;
|
|
3253
|
+
const charsPerLine = Math.max(12, Math.floor(width / charWidth));
|
|
3205
3254
|
const lines = Math.ceil(heading.text.length / charsPerLine) || 1;
|
|
3206
|
-
const lineHeight = fontSize * 1.
|
|
3207
|
-
|
|
3255
|
+
const lineHeight = fontSize * 1.4;
|
|
3256
|
+
const minH = heading.level === 1 ? 110 : heading.level === 2 ? 88 : 72;
|
|
3257
|
+
return Math.max(minH, Math.round(lines * lineHeight + 28));
|
|
3208
3258
|
}
|
|
3209
3259
|
estimateParagraphHeight(paragraph, width) {
|
|
3210
|
-
const charsPerLine = Math.max(
|
|
3260
|
+
const charsPerLine = Math.max(18, Math.floor(width / 9.5));
|
|
3211
3261
|
const lines = Math.ceil(paragraph.text.length / charsPerLine) || 1;
|
|
3212
|
-
return Math.max(
|
|
3262
|
+
return Math.max(36, lines * 34 + 8);
|
|
3213
3263
|
}
|
|
3214
3264
|
estimateListHeight(list, width = 800) {
|
|
3215
|
-
const charsPerLine = Math.max(
|
|
3265
|
+
const charsPerLine = Math.max(18, Math.floor(width / 9.5));
|
|
3216
3266
|
let totalHeight = 0;
|
|
3217
3267
|
for (const item of list.items) {
|
|
3218
3268
|
const cleanLen = item.text.replace(/\*\*/g, "").replace(/\*/g, "").length;
|
|
3219
3269
|
const lines = Math.ceil(cleanLen / charsPerLine) || 1;
|
|
3220
|
-
totalHeight += lines *
|
|
3270
|
+
totalHeight += lines * 32 + 10;
|
|
3221
3271
|
}
|
|
3222
3272
|
return Math.max(40, totalHeight);
|
|
3223
3273
|
}
|
|
3224
|
-
estimateCodeHeight(code) {
|
|
3225
|
-
const lines = code.code.split("\n")
|
|
3226
|
-
|
|
3274
|
+
estimateCodeHeight(code, width = 800) {
|
|
3275
|
+
const lines = code.code.split("\n");
|
|
3276
|
+
const charsPerLine = Math.max(18, Math.floor((width - 48) / 9.5));
|
|
3277
|
+
let visualLines = 0;
|
|
3278
|
+
for (const line of lines) {
|
|
3279
|
+
visualLines += Math.max(1, Math.ceil((line.length || 1) / charsPerLine));
|
|
3280
|
+
}
|
|
3281
|
+
return Math.max(120, visualLines * 34 + 84);
|
|
3227
3282
|
}
|
|
3228
3283
|
estimateQuoteHeight(quote, width) {
|
|
3229
3284
|
const charsPerLine = Math.max(20, Math.floor(width / 14));
|
|
@@ -6234,7 +6289,9 @@ var PptxRenderer = class {
|
|
|
6234
6289
|
h: rect.h,
|
|
6235
6290
|
align: paragraph.align || "left",
|
|
6236
6291
|
valign: "top",
|
|
6237
|
-
margin: 0
|
|
6292
|
+
margin: 0,
|
|
6293
|
+
// Keep glyphs inside the layout box; wrapping is fine, overflow into neighbors is not.
|
|
6294
|
+
shrinkText: rect.h < 0.32
|
|
6238
6295
|
});
|
|
6239
6296
|
}
|
|
6240
6297
|
renderList(pptxSlide, list, rect, theme) {
|
|
@@ -6349,7 +6406,8 @@ var PptxRenderer = class {
|
|
|
6349
6406
|
x: rect.x,
|
|
6350
6407
|
y: rect.y,
|
|
6351
6408
|
w: rect.w,
|
|
6352
|
-
h: rect.h
|
|
6409
|
+
h: rect.h,
|
|
6410
|
+
sizing: { type: "contain", w: rect.w, h: rect.h }
|
|
6353
6411
|
});
|
|
6354
6412
|
} catch {
|
|
6355
6413
|
drawPlaceholder();
|
|
@@ -6573,14 +6631,15 @@ var PptxRenderer = class {
|
|
|
6573
6631
|
});
|
|
6574
6632
|
} else {
|
|
6575
6633
|
pptxSlide.addText(code.code, {
|
|
6576
|
-
x: rect.x + 0.
|
|
6577
|
-
y: rect.y + 0.
|
|
6578
|
-
w: rect.w - 0.
|
|
6579
|
-
h: rect.h - 0.
|
|
6580
|
-
fontSize: 11.5,
|
|
6634
|
+
x: rect.x + 0.22,
|
|
6635
|
+
y: rect.y + 0.36,
|
|
6636
|
+
w: Math.max(0.2, rect.w - 0.44),
|
|
6637
|
+
h: Math.max(0.2, rect.h - 0.48),
|
|
6638
|
+
fontSize: rect.h < 2.2 ? 10 : 11.5,
|
|
6581
6639
|
fontFace: "Consolas",
|
|
6582
6640
|
color: textColor,
|
|
6583
|
-
valign: "top"
|
|
6641
|
+
valign: "top",
|
|
6642
|
+
margin: 0
|
|
6584
6643
|
});
|
|
6585
6644
|
}
|
|
6586
6645
|
}
|
|
@@ -6646,12 +6705,12 @@ var PptxRenderer = class {
|
|
|
6646
6705
|
line: { color: sevColor, width: 2 },
|
|
6647
6706
|
rectRadius: 0.08
|
|
6648
6707
|
});
|
|
6649
|
-
const titleH = callout.title ? 0.
|
|
6708
|
+
const titleH = callout.title ? 0.38 : 0;
|
|
6650
6709
|
if (callout.title) {
|
|
6651
6710
|
pptxSlide.addText(callout.title, {
|
|
6652
|
-
x: rect.x + 0.
|
|
6653
|
-
y: rect.y + 0.
|
|
6654
|
-
w: rect.w - 0.
|
|
6711
|
+
x: rect.x + 0.2,
|
|
6712
|
+
y: rect.y + 0.16,
|
|
6713
|
+
w: rect.w - 0.4,
|
|
6655
6714
|
h: 0.3,
|
|
6656
6715
|
fontSize: 13,
|
|
6657
6716
|
bold: true,
|
|
@@ -6660,10 +6719,10 @@ var PptxRenderer = class {
|
|
|
6660
6719
|
});
|
|
6661
6720
|
}
|
|
6662
6721
|
pptxSlide.addText(callout.text, {
|
|
6663
|
-
x: rect.x + 0.
|
|
6664
|
-
y: rect.y + titleH + 0.
|
|
6665
|
-
w: rect.w - 0.
|
|
6666
|
-
h: rect.h - titleH - 0.
|
|
6722
|
+
x: rect.x + 0.2,
|
|
6723
|
+
y: rect.y + titleH + 0.14,
|
|
6724
|
+
w: rect.w - 0.4,
|
|
6725
|
+
h: Math.max(0.2, rect.h - titleH - 0.28),
|
|
6667
6726
|
fontSize: 12,
|
|
6668
6727
|
color: this.cleanHexColor(theme.colors.text),
|
|
6669
6728
|
fontFace: cleanFontFace(theme.typography.bodyFont),
|
|
@@ -6679,15 +6738,18 @@ var PptxRenderer = class {
|
|
|
6679
6738
|
h: node.bounds.height * scaleY
|
|
6680
6739
|
};
|
|
6681
6740
|
const align = hero.align || "center";
|
|
6682
|
-
|
|
6683
|
-
|
|
6741
|
+
const compact = rect.h < 2.4;
|
|
6742
|
+
const maxY = rect.y + rect.h - 0.04;
|
|
6743
|
+
let curY = rect.y + (compact ? 0.08 : 0.24);
|
|
6744
|
+
if (hero.badge && curY < maxY) {
|
|
6684
6745
|
const badgeW = Math.min(3.2, Math.max(1.4, hero.badge.length * 0.11 + 0.6));
|
|
6685
6746
|
const badgeX = align === "left" ? rect.x : align === "right" ? rect.x + rect.w - badgeW : rect.x + (rect.w - badgeW) / 2;
|
|
6747
|
+
const badgeH = Math.min(compact ? 0.26 : 0.32, maxY - curY);
|
|
6686
6748
|
pptxSlide.addShape(pptx.ShapeType.roundRect, {
|
|
6687
6749
|
x: badgeX,
|
|
6688
6750
|
y: curY,
|
|
6689
6751
|
w: badgeW,
|
|
6690
|
-
h:
|
|
6752
|
+
h: badgeH,
|
|
6691
6753
|
fill: { color: this.cleanHexColor(theme.colors.surface) },
|
|
6692
6754
|
line: { color: this.cleanHexColor(theme.colors.primary), width: 1.5 },
|
|
6693
6755
|
rectRadius: 0.16
|
|
@@ -6696,50 +6758,55 @@ var PptxRenderer = class {
|
|
|
6696
6758
|
x: badgeX,
|
|
6697
6759
|
y: curY,
|
|
6698
6760
|
w: badgeW,
|
|
6699
|
-
h:
|
|
6700
|
-
fontSize: 10,
|
|
6761
|
+
h: badgeH,
|
|
6762
|
+
fontSize: compact ? 9 : 10,
|
|
6701
6763
|
bold: true,
|
|
6702
6764
|
color: this.cleanHexColor(theme.colors.primary),
|
|
6703
6765
|
fontFace: cleanFontFace(theme.typography.headingFont),
|
|
6704
6766
|
align: "center",
|
|
6705
6767
|
valign: "middle"
|
|
6706
6768
|
});
|
|
6707
|
-
curY += 0.48;
|
|
6708
|
-
} else if (hero.tagline) {
|
|
6769
|
+
curY += compact ? 0.36 : 0.48;
|
|
6770
|
+
} else if (hero.tagline && curY < maxY) {
|
|
6771
|
+
const tagH = Math.min(0.32, maxY - curY);
|
|
6709
6772
|
pptxSlide.addText(hero.tagline.toUpperCase(), {
|
|
6710
6773
|
x: rect.x,
|
|
6711
6774
|
y: curY,
|
|
6712
6775
|
w: rect.w,
|
|
6713
|
-
h:
|
|
6714
|
-
fontSize: 11,
|
|
6776
|
+
h: tagH,
|
|
6777
|
+
fontSize: compact ? 10 : 11,
|
|
6715
6778
|
bold: true,
|
|
6716
6779
|
color: this.cleanHexColor(theme.colors.primary),
|
|
6717
6780
|
fontFace: cleanFontFace(theme.typography.headingFont),
|
|
6718
6781
|
align
|
|
6719
6782
|
});
|
|
6720
|
-
curY += 0.42;
|
|
6783
|
+
curY += compact ? 0.34 : 0.42;
|
|
6721
6784
|
}
|
|
6722
|
-
const titleLines = Math.max(1, Math.ceil(hero.title.length / 38));
|
|
6723
|
-
const
|
|
6785
|
+
const titleLines = Math.max(1, Math.ceil(hero.title.length / (compact ? 48 : 38)));
|
|
6786
|
+
const titleBudget = Math.max(0.24, maxY - curY - (hero.subtitle ? 0.3 : 0.02));
|
|
6787
|
+
const titleH = Math.min(Math.max(compact ? 0.42 : 0.7, titleLines * (compact ? 0.36 : 0.55) + 0.08), titleBudget);
|
|
6724
6788
|
const displaySize = themeSizeToPptxPoints(theme.typography.sizes?.display, 56);
|
|
6725
|
-
const titleFontSize = titleLines > 2 ? displaySize - 10 : titleLines > 1 ? displaySize - 6 : displaySize;
|
|
6726
|
-
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6789
|
+
const titleFontSize = compact ? titleLines > 1 ? Math.min(20, displaySize - 16) : Math.min(24, displaySize - 12) : titleLines > 2 ? displaySize - 10 : titleLines > 1 ? displaySize - 6 : displaySize;
|
|
6790
|
+
if (titleH >= 0.24) {
|
|
6791
|
+
pptxSlide.addText(hero.title, {
|
|
6792
|
+
x: rect.x,
|
|
6793
|
+
y: curY,
|
|
6794
|
+
w: rect.w,
|
|
6795
|
+
h: titleH,
|
|
6796
|
+
fontSize: titleFontSize,
|
|
6797
|
+
bold: true,
|
|
6798
|
+
color: this.cleanHexColor(theme.colors.text),
|
|
6799
|
+
fontFace: cleanFontFace(theme.typography.headingFont),
|
|
6800
|
+
align,
|
|
6801
|
+
valign: "top"
|
|
6802
|
+
});
|
|
6803
|
+
}
|
|
6804
|
+
curY += titleH + (compact ? 0.04 : 0.08);
|
|
6805
|
+
if (hero.subtitle && curY < maxY - 0.14) {
|
|
6806
|
+
const subLines = Math.max(1, Math.ceil(hero.subtitle.length / (compact ? 64 : 56)));
|
|
6807
|
+
const subH = Math.min(Math.max(compact ? 0.28 : 0.38, subLines * 0.28 + 0.06), maxY - curY);
|
|
6741
6808
|
const bodySize = themeSizeToPptxPoints(theme.typography.sizes?.body, 18);
|
|
6742
|
-
const subFontSize = subLines > 2 ? bodySize - 1 : bodySize + 1;
|
|
6809
|
+
const subFontSize = compact ? bodySize - 1 : subLines > 2 ? bodySize - 1 : bodySize + 1;
|
|
6743
6810
|
pptxSlide.addText(hero.subtitle, {
|
|
6744
6811
|
x: rect.x,
|
|
6745
6812
|
y: curY,
|
|
@@ -6748,22 +6815,22 @@ var PptxRenderer = class {
|
|
|
6748
6815
|
fontSize: subFontSize,
|
|
6749
6816
|
color: this.cleanHexColor(theme.colors.muted || theme.colors.text),
|
|
6750
6817
|
fontFace: cleanFontFace(theme.typography.bodyFont),
|
|
6751
|
-
align
|
|
6818
|
+
align,
|
|
6819
|
+
valign: "top"
|
|
6752
6820
|
});
|
|
6753
|
-
curY += subH + 0.12;
|
|
6821
|
+
curY += subH + (compact ? 0.06 : 0.12);
|
|
6754
6822
|
}
|
|
6755
|
-
if (hero.tagline && hero.badge) {
|
|
6823
|
+
if (hero.tagline && hero.badge && curY + 0.28 <= maxY) {
|
|
6756
6824
|
pptxSlide.addText(hero.tagline, {
|
|
6757
6825
|
x: rect.x,
|
|
6758
6826
|
y: curY,
|
|
6759
6827
|
w: rect.w,
|
|
6760
|
-
h: 0.
|
|
6828
|
+
h: 0.28,
|
|
6761
6829
|
fontSize: 12,
|
|
6762
6830
|
color: this.cleanHexColor(theme.colors.muted || theme.colors.text),
|
|
6763
6831
|
fontFace: cleanFontFace(theme.typography.bodyFont),
|
|
6764
6832
|
align
|
|
6765
6833
|
});
|
|
6766
|
-
curY += 0.35;
|
|
6767
6834
|
}
|
|
6768
6835
|
if (node.children) {
|
|
6769
6836
|
for (const childNode of node.children) {
|
|
@@ -6995,7 +7062,7 @@ ${item.description}` : "";
|
|
|
6995
7062
|
const { element, bounds } = node;
|
|
6996
7063
|
const compare = element;
|
|
6997
7064
|
const rect = this.toInches(bounds, scaleX, scaleY);
|
|
6998
|
-
const colW = (rect.w - 0.
|
|
7065
|
+
const colW = (rect.w - 0.5) / 2;
|
|
6999
7066
|
pptxSlide.addShape(pptx.ShapeType.roundRect, {
|
|
7000
7067
|
x: rect.x,
|
|
7001
7068
|
y: rect.y,
|
|
@@ -7017,7 +7084,7 @@ ${item.description}` : "";
|
|
|
7017
7084
|
fontFace: cleanFontFace(theme.typography.headingFont)
|
|
7018
7085
|
});
|
|
7019
7086
|
}
|
|
7020
|
-
const rightX = rect.x + colW + 0.
|
|
7087
|
+
const rightX = rect.x + colW + 0.5;
|
|
7021
7088
|
pptxSlide.addShape(pptx.ShapeType.roundRect, {
|
|
7022
7089
|
x: rightX,
|
|
7023
7090
|
y: rect.y,
|
|
@@ -7039,26 +7106,30 @@ ${item.description}` : "";
|
|
|
7039
7106
|
fontFace: cleanFontFace(theme.typography.headingFont)
|
|
7040
7107
|
});
|
|
7041
7108
|
}
|
|
7042
|
-
const
|
|
7043
|
-
|
|
7109
|
+
const vsW = 0.42;
|
|
7110
|
+
const vsH = 0.42;
|
|
7111
|
+
const vsX = rect.x + colW + (0.5 - vsW) / 2;
|
|
7112
|
+
const vsY = rect.y + rect.h / 2 - vsH / 2;
|
|
7113
|
+
pptxSlide.addShape(pptx.ShapeType.ellipse, {
|
|
7044
7114
|
x: vsX,
|
|
7045
|
-
y:
|
|
7046
|
-
w:
|
|
7047
|
-
h:
|
|
7048
|
-
fill: { color: this.cleanHexColor(theme.colors.
|
|
7049
|
-
|
|
7115
|
+
y: vsY,
|
|
7116
|
+
w: vsW,
|
|
7117
|
+
h: vsH,
|
|
7118
|
+
fill: { color: this.cleanHexColor(theme.colors.surface || theme.colors.background) },
|
|
7119
|
+
line: { color: this.cleanHexColor(theme.colors.primary), width: 1.5 }
|
|
7050
7120
|
});
|
|
7051
7121
|
pptxSlide.addText("VS", {
|
|
7052
7122
|
x: vsX,
|
|
7053
|
-
y:
|
|
7054
|
-
w:
|
|
7055
|
-
h:
|
|
7056
|
-
fontSize:
|
|
7123
|
+
y: vsY,
|
|
7124
|
+
w: vsW,
|
|
7125
|
+
h: vsH,
|
|
7126
|
+
fontSize: 11,
|
|
7057
7127
|
bold: true,
|
|
7058
|
-
color: this.cleanHexColor(theme.colors.
|
|
7128
|
+
color: this.cleanHexColor(theme.colors.text),
|
|
7059
7129
|
fontFace: cleanFontFace(theme.typography.headingFont),
|
|
7060
7130
|
align: "center",
|
|
7061
|
-
valign: "middle"
|
|
7131
|
+
valign: "middle",
|
|
7132
|
+
margin: 0
|
|
7062
7133
|
});
|
|
7063
7134
|
if (node.children) {
|
|
7064
7135
|
for (const childNode of node.children) {
|
|
@@ -7399,33 +7470,36 @@ ${mermaid.code}`, {
|
|
|
7399
7470
|
const p2 = positions[e.to];
|
|
7400
7471
|
if (!p1 || !p2)
|
|
7401
7472
|
return;
|
|
7402
|
-
const
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7473
|
+
const pts = orthogonalEdgePoints(isLR, p1, p2, nodeW, nodeH);
|
|
7474
|
+
if (pts.length < 2)
|
|
7475
|
+
return;
|
|
7476
|
+
for (let i = 0; i < pts.length - 1; i++) {
|
|
7477
|
+
const a = pts[i];
|
|
7478
|
+
const b = pts[i + 1];
|
|
7479
|
+
const segMinX = Math.min(a.x, b.x);
|
|
7480
|
+
const segMinY = Math.min(a.y, b.y);
|
|
7481
|
+
const lineW = Math.max(0.01, Math.abs(b.x - a.x));
|
|
7482
|
+
const lineH = Math.max(0.01, Math.abs(b.y - a.y));
|
|
7483
|
+
const isLast = i === pts.length - 2;
|
|
7484
|
+
pptxSlide.addShape(pptx.ShapeType.line, {
|
|
7485
|
+
x: segMinX,
|
|
7486
|
+
y: segMinY,
|
|
7487
|
+
w: lineW,
|
|
7488
|
+
h: lineH,
|
|
7489
|
+
flipH: b.x < a.x,
|
|
7490
|
+
flipV: b.y < a.y,
|
|
7491
|
+
line: {
|
|
7492
|
+
color: arrowColor,
|
|
7493
|
+
width: 2,
|
|
7494
|
+
endArrowType: isLast ? "triangle" : void 0,
|
|
7495
|
+
dashType: e.style === "dashed" ? "dash" : "solid"
|
|
7496
|
+
}
|
|
7497
|
+
});
|
|
7498
|
+
}
|
|
7426
7499
|
if (e.label) {
|
|
7427
|
-
const
|
|
7428
|
-
const
|
|
7500
|
+
const mid = pts[Math.floor(pts.length / 2)];
|
|
7501
|
+
const midX = mid.x;
|
|
7502
|
+
const midY = mid.y;
|
|
7429
7503
|
const pillW = Math.min(1.4, Math.max(0.7, e.label.length * 0.08 + 0.25));
|
|
7430
7504
|
pptxSlide.addShape(pptx.ShapeType.roundRect, {
|
|
7431
7505
|
x: midX - pillW / 2,
|
|
@@ -7490,17 +7564,18 @@ ${mermaid.code}`, {
|
|
|
7490
7564
|
line: { color: nodeBorderColor, width: 1 }
|
|
7491
7565
|
});
|
|
7492
7566
|
}
|
|
7493
|
-
pptxSlide.addText(fitDiagramLabel(n.label, Math.max(
|
|
7494
|
-
x: p.x + 0.
|
|
7567
|
+
pptxSlide.addText(fitDiagramLabel(n.label, Math.max(10, Math.floor(nodeW * 72 / 6.8))), {
|
|
7568
|
+
x: p.x + 0.08,
|
|
7495
7569
|
y: p.y + 0.06,
|
|
7496
|
-
w: Math.max(0.1, nodeW - 0.
|
|
7570
|
+
w: Math.max(0.1, nodeW - 0.16),
|
|
7497
7571
|
h: Math.max(0.1, nodeH - 0.12),
|
|
7498
7572
|
align: "center",
|
|
7499
7573
|
valign: "middle",
|
|
7500
|
-
fontSize: n.label.length >
|
|
7574
|
+
fontSize: nodeW < 1.1 ? 10 : n.label.length > 22 ? 11 : 12,
|
|
7501
7575
|
bold: true,
|
|
7502
7576
|
color: this.cleanHexColor(theme.colors.text || "ffffff"),
|
|
7503
|
-
fontFace: cleanFontFace(theme.typography.headingFont)
|
|
7577
|
+
fontFace: cleanFontFace(theme.typography.headingFont),
|
|
7578
|
+
margin: 0
|
|
7504
7579
|
});
|
|
7505
7580
|
});
|
|
7506
7581
|
}
|
|
@@ -8124,10 +8199,12 @@ var HtmlRenderer = class {
|
|
|
8124
8199
|
.yumia-grid {
|
|
8125
8200
|
display: grid;
|
|
8126
8201
|
width: 100%;
|
|
8127
|
-
flex: 1;
|
|
8202
|
+
flex: 1 1 auto;
|
|
8128
8203
|
min-height: 0;
|
|
8204
|
+
max-height: 100%;
|
|
8129
8205
|
gap: clamp(1rem, 1.8vw, 1.6rem);
|
|
8130
8206
|
align-items: stretch;
|
|
8207
|
+
align-content: start;
|
|
8131
8208
|
margin-top: 0.4rem;
|
|
8132
8209
|
}
|
|
8133
8210
|
|
|
@@ -8171,14 +8248,16 @@ var HtmlRenderer = class {
|
|
|
8171
8248
|
background: var(--yumia-surface);
|
|
8172
8249
|
border: 1.5px solid var(--yumia-border);
|
|
8173
8250
|
border-radius: 14px;
|
|
8174
|
-
padding: clamp(1.
|
|
8251
|
+
padding: clamp(1.1rem, 1.8vw, 1.5rem);
|
|
8175
8252
|
display: flex;
|
|
8176
8253
|
flex-direction: column;
|
|
8177
8254
|
justify-content: flex-start;
|
|
8178
|
-
gap: 0.
|
|
8255
|
+
gap: 0.45rem;
|
|
8179
8256
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
|
|
8180
8257
|
height: 100%;
|
|
8258
|
+
max-height: 100%;
|
|
8181
8259
|
min-height: 0;
|
|
8260
|
+
overflow: hidden;
|
|
8182
8261
|
box-sizing: border-box;
|
|
8183
8262
|
transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
|
|
8184
8263
|
}
|
|
@@ -9824,7 +9903,8 @@ var HtmlRenderer = class {
|
|
|
9824
9903
|
case "grid": {
|
|
9825
9904
|
const g = element;
|
|
9826
9905
|
const cols = typeof g.columns === "number" ? `repeat(${g.columns}, minmax(0, 1fr))` : g.columns;
|
|
9827
|
-
const
|
|
9906
|
+
const gapRaw = g.gap !== void 0 ? g.gap : "1.5rem";
|
|
9907
|
+
const gap = typeof gapRaw === "number" ? `${gapRaw}px` : /^\d+(\.\d+)?$/.test(String(gapRaw).trim()) ? `${String(gapRaw).trim()}px` : String(gapRaw);
|
|
9828
9908
|
const inner = g.elements.map((child) => this.renderElement(child, theme, presentation)).join("\n");
|
|
9829
9909
|
return `<div class="yumia-grid" style="grid-template-columns:${cols}; gap:${gap};">${inner}</div>`;
|
|
9830
9910
|
}
|
|
@@ -10646,12 +10726,7 @@ var PdfRenderer = class {
|
|
|
10646
10726
|
gap: 24
|
|
10647
10727
|
});
|
|
10648
10728
|
for (const node of slideLayout.nodes) {
|
|
10649
|
-
|
|
10650
|
-
const y = node.bounds.y * scaleY;
|
|
10651
|
-
const w = node.bounds.width * scaleX;
|
|
10652
|
-
if (y >= contentBottom - 8)
|
|
10653
|
-
continue;
|
|
10654
|
-
this.renderElement(doc, node.element, x, y, w, theme, presentation);
|
|
10729
|
+
this.paintLayoutNode(doc, node, scaleX, scaleY, theme, presentation, contentBottom);
|
|
10655
10730
|
}
|
|
10656
10731
|
const progressWidth = slideNum / totalSlides * pageWidth;
|
|
10657
10732
|
doc.rect(0, pageHeight - 4, progressWidth, 4).fill(theme.colors.primary);
|
|
@@ -10667,6 +10742,132 @@ var PdfRenderer = class {
|
|
|
10667
10742
|
align: "right"
|
|
10668
10743
|
});
|
|
10669
10744
|
}
|
|
10745
|
+
paintLayoutNode(doc, node, scaleX, scaleY, theme, presentation, contentBottom) {
|
|
10746
|
+
const el = node.element;
|
|
10747
|
+
const x = node.bounds.x * scaleX;
|
|
10748
|
+
const y = node.bounds.y * scaleY;
|
|
10749
|
+
const w = node.bounds.width * scaleX;
|
|
10750
|
+
const h = node.bounds.height * scaleY;
|
|
10751
|
+
if (y >= contentBottom - 8)
|
|
10752
|
+
return;
|
|
10753
|
+
const hasChildren = !!(node.children && node.children.length > 0);
|
|
10754
|
+
if (hasChildren && (el.type === "grid" || el.type === "stack" || el.type === "columns" || el.type === "column")) {
|
|
10755
|
+
for (const child of node.children) {
|
|
10756
|
+
this.paintLayoutNode(doc, child, scaleX, scaleY, theme, presentation, contentBottom);
|
|
10757
|
+
}
|
|
10758
|
+
return;
|
|
10759
|
+
}
|
|
10760
|
+
if (hasChildren && el.type === "card") {
|
|
10761
|
+
this.paintCardFrame(doc, el, x, y, w, h, theme);
|
|
10762
|
+
for (const child of node.children) {
|
|
10763
|
+
this.paintLayoutNode(doc, child, scaleX, scaleY, theme, presentation, contentBottom);
|
|
10764
|
+
}
|
|
10765
|
+
return;
|
|
10766
|
+
}
|
|
10767
|
+
if (hasChildren && el.type === "compare") {
|
|
10768
|
+
this.paintCompareFrame(doc, el, x, y, w, h, theme);
|
|
10769
|
+
for (const child of node.children) {
|
|
10770
|
+
this.paintLayoutNode(doc, child, scaleX, scaleY, theme, presentation, contentBottom);
|
|
10771
|
+
}
|
|
10772
|
+
return;
|
|
10773
|
+
}
|
|
10774
|
+
if (el.type === "hero") {
|
|
10775
|
+
this.paintHeroInBounds(doc, el, x, y, w, h, theme);
|
|
10776
|
+
if (hasChildren) {
|
|
10777
|
+
for (const child of node.children) {
|
|
10778
|
+
this.paintLayoutNode(doc, child, scaleX, scaleY, theme, presentation, contentBottom);
|
|
10779
|
+
}
|
|
10780
|
+
}
|
|
10781
|
+
return;
|
|
10782
|
+
}
|
|
10783
|
+
this.renderElement(doc, el, x, y, w, theme, presentation);
|
|
10784
|
+
}
|
|
10785
|
+
paintCardFrame(doc, card, x, y, width, height, theme) {
|
|
10786
|
+
const variantColor = this.getVariantColor(card.variant, theme);
|
|
10787
|
+
doc.save();
|
|
10788
|
+
doc.roundedRect(x, y, width, height, 8).fill(theme.colors.surface || "rgba(255,255,255,0.06)");
|
|
10789
|
+
doc.roundedRect(x, y, width, height, 8).lineWidth(1.5).strokeColor(variantColor).stroke();
|
|
10790
|
+
doc.restore();
|
|
10791
|
+
if (card.title) {
|
|
10792
|
+
doc.font(this.getPdfFont(theme, "bold")).fontSize(13).fillColor(variantColor).text(this.stripFormatting(card.title), x + 12, y + 10, {
|
|
10793
|
+
width: width - 24,
|
|
10794
|
+
height: 22,
|
|
10795
|
+
ellipsis: true
|
|
10796
|
+
});
|
|
10797
|
+
}
|
|
10798
|
+
}
|
|
10799
|
+
paintCompareFrame(doc, compare, x, y, width, height, theme) {
|
|
10800
|
+
const gap = 16;
|
|
10801
|
+
const colW = (width - gap) / 2;
|
|
10802
|
+
const leftColor = theme.colors.primary;
|
|
10803
|
+
const rightColor = theme.colors.accent || theme.colors.secondary || theme.colors.primary;
|
|
10804
|
+
doc.save();
|
|
10805
|
+
doc.roundedRect(x, y, colW, height, 8).fill(theme.colors.surface || "#151522");
|
|
10806
|
+
doc.roundedRect(x, y, colW, height, 8).lineWidth(1.4).strokeColor(theme.colors.border || "rgba(255,255,255,0.15)").stroke();
|
|
10807
|
+
doc.roundedRect(x + colW + gap, y, colW, height, 8).fill(theme.colors.surface || "#151522");
|
|
10808
|
+
doc.roundedRect(x + colW + gap, y, colW, height, 8).lineWidth(1.4).strokeColor(theme.colors.border || "rgba(255,255,255,0.15)").stroke();
|
|
10809
|
+
doc.restore();
|
|
10810
|
+
const midX = x + colW + gap / 2;
|
|
10811
|
+
const midY = y + height / 2;
|
|
10812
|
+
doc.circle(midX, midY, 16).fill(theme.colors.surface || "#151522");
|
|
10813
|
+
doc.circle(midX, midY, 16).lineWidth(1.4).strokeColor(theme.colors.primary).stroke();
|
|
10814
|
+
doc.font(this.getPdfFont(theme, "bold")).fontSize(10).fillColor(theme.colors.text).text("VS", midX - 14, midY - 5, { width: 28, align: "center" });
|
|
10815
|
+
if (compare.leftTitle) {
|
|
10816
|
+
doc.font(this.getPdfFont(theme, "bold")).fontSize(11).fillColor(leftColor).text(this.stripFormatting(compare.leftTitle), x + 10, y + 10, {
|
|
10817
|
+
width: colW - 20,
|
|
10818
|
+
height: 28,
|
|
10819
|
+
ellipsis: true
|
|
10820
|
+
});
|
|
10821
|
+
}
|
|
10822
|
+
if (compare.rightTitle) {
|
|
10823
|
+
doc.font(this.getPdfFont(theme, "bold")).fontSize(11).fillColor(rightColor).text(this.stripFormatting(compare.rightTitle), x + colW + gap + 10, y + 10, {
|
|
10824
|
+
width: colW - 20,
|
|
10825
|
+
height: 28,
|
|
10826
|
+
ellipsis: true
|
|
10827
|
+
});
|
|
10828
|
+
}
|
|
10829
|
+
}
|
|
10830
|
+
paintHeroInBounds(doc, hero, x, y, width, height, theme) {
|
|
10831
|
+
const align = hero.align || "center";
|
|
10832
|
+
const compact = height < 140;
|
|
10833
|
+
let curY = y;
|
|
10834
|
+
const maxY = y + height - 4;
|
|
10835
|
+
if (hero.badge && curY < maxY) {
|
|
10836
|
+
const label = this.stripFormatting(hero.badge).toUpperCase();
|
|
10837
|
+
doc.font(this.getPdfFont(theme, "bold")).fontSize(compact ? 8 : 9);
|
|
10838
|
+
const labelW = Math.min(width, Math.max(70, doc.widthOfString(label) + 24));
|
|
10839
|
+
const badgeX = align === "left" ? x : align === "right" ? x + width - labelW : x + (width - labelW) / 2;
|
|
10840
|
+
doc.roundedRect(badgeX, curY, labelW, compact ? 16 : 18, 9).lineWidth(1.2).strokeColor(theme.colors.primary).fillColor(theme.colors.surface || "#f8fafc").fillAndStroke();
|
|
10841
|
+
doc.font(this.getPdfFont(theme, "bold")).fontSize(compact ? 8 : 9).fillColor(theme.colors.primary).text(label, badgeX, curY + 3, { width: labelW, align: "center" });
|
|
10842
|
+
curY += compact ? 22 : 28;
|
|
10843
|
+
} else if (hero.tagline && curY < maxY) {
|
|
10844
|
+
doc.font(this.getPdfFont(theme, "bold")).fontSize(compact ? 10 : 11).fillColor(theme.colors.primary);
|
|
10845
|
+
doc.text(this.stripFormatting(hero.tagline).toUpperCase(), x, curY, { width, align });
|
|
10846
|
+
curY += 20;
|
|
10847
|
+
}
|
|
10848
|
+
if (curY < maxY) {
|
|
10849
|
+
const titleSize = compact ? themeSizeToPdfPoints(theme.typography.sizes?.h1, 44) : themeSizeToPdfPoints(theme.typography.sizes?.display, 56);
|
|
10850
|
+
doc.font(this.getPdfFont(theme, "bold")).fontSize(titleSize).fillColor(theme.colors.text);
|
|
10851
|
+
doc.text(this.stripFormatting(hero.title), x, curY, {
|
|
10852
|
+
width,
|
|
10853
|
+
height: Math.max(20, maxY - curY - (hero.subtitle ? 28 : 4)),
|
|
10854
|
+
lineGap: 4,
|
|
10855
|
+
align,
|
|
10856
|
+
ellipsis: true
|
|
10857
|
+
});
|
|
10858
|
+
curY += Math.min(maxY - curY, doc.heightOfString(this.stripFormatting(hero.title), { width }) + 8);
|
|
10859
|
+
}
|
|
10860
|
+
if (hero.subtitle && curY < maxY) {
|
|
10861
|
+
const subSize = themeSizeToPdfPoints(theme.typography.sizes?.body, 18);
|
|
10862
|
+
doc.font(this.getPdfFont(theme, "regular")).fontSize(compact ? subSize - 1 : subSize + 1).fillColor(theme.colors.muted || "#888888");
|
|
10863
|
+
doc.text(this.stripFormatting(hero.subtitle), x, curY, {
|
|
10864
|
+
width,
|
|
10865
|
+
height: Math.max(16, maxY - curY),
|
|
10866
|
+
align,
|
|
10867
|
+
ellipsis: true
|
|
10868
|
+
});
|
|
10869
|
+
}
|
|
10870
|
+
}
|
|
10670
10871
|
renderElement(doc, element, x, y, width, theme, presentation) {
|
|
10671
10872
|
switch (element.type) {
|
|
10672
10873
|
case "hero": {
|
|
@@ -11114,7 +11315,10 @@ var PdfRenderer = class {
|
|
|
11114
11315
|
doc.roundedRect(x, y, width, boxH2, 8).strokeColor(theme.colors.border || "rgba(255,255,255,0.1)").stroke();
|
|
11115
11316
|
let topY2 = y + 8;
|
|
11116
11317
|
if (ch.title) {
|
|
11117
|
-
doc.font(this.getPdfFont(theme, "bold")).fontSize(13).fillColor(theme.colors.text).text(this.stripFormatting(ch.title), x + 14, topY2, {
|
|
11318
|
+
doc.font(this.getPdfFont(theme, "bold")).fontSize(13).fillColor(theme.colors.text).text(this.stripFormatting(ch.title), x + 14, topY2, {
|
|
11319
|
+
width: width - 28,
|
|
11320
|
+
align: "center"
|
|
11321
|
+
});
|
|
11118
11322
|
topY2 += 18;
|
|
11119
11323
|
}
|
|
11120
11324
|
const values2 = ch.series[0]?.values || [];
|
|
@@ -11192,7 +11396,10 @@ var PdfRenderer = class {
|
|
|
11192
11396
|
doc.roundedRect(x, y, width, boxH2, 8).strokeColor(theme.colors.border || "rgba(255,255,255,0.1)").stroke();
|
|
11193
11397
|
let topY2 = y + 8;
|
|
11194
11398
|
if (ch.title) {
|
|
11195
|
-
doc.font(this.getPdfFont(theme, "bold")).fontSize(13).fillColor(theme.colors.text).text(this.stripFormatting(ch.title), x + 14, topY2, {
|
|
11399
|
+
doc.font(this.getPdfFont(theme, "bold")).fontSize(13).fillColor(theme.colors.text).text(this.stripFormatting(ch.title), x + 14, topY2, {
|
|
11400
|
+
width: width - 28,
|
|
11401
|
+
align: "center"
|
|
11402
|
+
});
|
|
11196
11403
|
topY2 += 18;
|
|
11197
11404
|
}
|
|
11198
11405
|
const val = ch.series[0]?.values[0] || 0;
|
|
@@ -11232,7 +11439,10 @@ var PdfRenderer = class {
|
|
|
11232
11439
|
}
|
|
11233
11440
|
doc.font(this.getPdfFont(theme, "bold")).fontSize(20).fillColor(theme.colors.text).text(`${val}%`, cx - 40, cy - 16, { width: 80, align: "center" });
|
|
11234
11441
|
if (ch.labels?.[0]) {
|
|
11235
|
-
doc.font(this.getPdfFont(theme, "regular")).fontSize(9).fillColor(theme.colors.muted || "#888888").text(this.stripFormatting(ch.labels[0]), cx - 60, cy + 6, {
|
|
11442
|
+
doc.font(this.getPdfFont(theme, "regular")).fontSize(9).fillColor(theme.colors.muted || "#888888").text(this.stripFormatting(ch.labels[0]), cx - 60, cy + 6, {
|
|
11443
|
+
width: 120,
|
|
11444
|
+
align: "center"
|
|
11445
|
+
});
|
|
11236
11446
|
}
|
|
11237
11447
|
return y + boxH2 + 8;
|
|
11238
11448
|
}
|
|
@@ -11492,25 +11702,30 @@ var PdfRenderer = class {
|
|
|
11492
11702
|
const p2 = positions[e.to];
|
|
11493
11703
|
if (!p1 || !p2)
|
|
11494
11704
|
return;
|
|
11495
|
-
const
|
|
11496
|
-
|
|
11497
|
-
|
|
11498
|
-
const
|
|
11705
|
+
const pts = orthogonalEdgePoints(isLR, p1, p2, nodeW, nodeH);
|
|
11706
|
+
if (pts.length < 2)
|
|
11707
|
+
return;
|
|
11708
|
+
const last = pts[pts.length - 1];
|
|
11709
|
+
const prev = pts[pts.length - 2];
|
|
11499
11710
|
doc.save();
|
|
11500
11711
|
doc.lineWidth(1.5).strokeColor(arrowColor);
|
|
11501
11712
|
if (e.style === "dashed")
|
|
11502
11713
|
doc.dash(4, { space: 3 });
|
|
11503
|
-
doc.moveTo(
|
|
11714
|
+
doc.moveTo(pts[0].x, pts[0].y);
|
|
11715
|
+
for (let i = 1; i < pts.length; i++)
|
|
11716
|
+
doc.lineTo(pts[i].x, pts[i].y);
|
|
11717
|
+
doc.stroke();
|
|
11504
11718
|
doc.restore();
|
|
11505
|
-
const angle = Math.atan2(
|
|
11719
|
+
const angle = Math.atan2(last.y - prev.y, last.x - prev.x);
|
|
11506
11720
|
const headLen = 6;
|
|
11507
11721
|
doc.save();
|
|
11508
11722
|
doc.fillColor(arrowColor);
|
|
11509
|
-
doc.moveTo(
|
|
11723
|
+
doc.moveTo(last.x, last.y).lineTo(last.x - headLen * Math.cos(angle - Math.PI / 6), last.y - headLen * Math.sin(angle - Math.PI / 6)).lineTo(last.x - headLen * Math.cos(angle + Math.PI / 6), last.y - headLen * Math.sin(angle + Math.PI / 6)).fill();
|
|
11510
11724
|
doc.restore();
|
|
11511
11725
|
if (e.label) {
|
|
11512
|
-
const
|
|
11513
|
-
const
|
|
11726
|
+
const mid = pts[Math.floor(pts.length / 2)];
|
|
11727
|
+
const midX = mid.x;
|
|
11728
|
+
const midY = mid.y;
|
|
11514
11729
|
const labelText = this.stripFormatting(e.label);
|
|
11515
11730
|
const labelW = Math.min(90, Math.max(45, labelText.length * 5.5 + 16));
|
|
11516
11731
|
doc.save();
|
|
@@ -11584,7 +11799,10 @@ var PdfRenderer = class {
|
|
|
11584
11799
|
doc.restore();
|
|
11585
11800
|
doc.roundedRect(boxX, topY, partW, 26, 5).fill(theme.colors.surface || "rgba(255,255,255,0.06)");
|
|
11586
11801
|
doc.roundedRect(boxX, topY, partW, 26, 5).lineWidth(1.2).strokeColor(primaryColor).stroke();
|
|
11587
|
-
doc.font(this.getPdfFont(theme, "bold")).fontSize(9).fillColor(theme.colors.text).text(this.stripFormatting(p.name), boxX + 2, topY + 8, {
|
|
11802
|
+
doc.font(this.getPdfFont(theme, "bold")).fontSize(9).fillColor(theme.colors.text).text(this.stripFormatting(p.name), boxX + 2, topY + 8, {
|
|
11803
|
+
width: partW - 4,
|
|
11804
|
+
align: "center"
|
|
11805
|
+
});
|
|
11588
11806
|
});
|
|
11589
11807
|
messages.forEach((msg, idx) => {
|
|
11590
11808
|
const x1 = positions[msg.from] || x + 20;
|
|
@@ -11799,7 +12017,7 @@ function startDevServer(filePath, options = {}) {
|
|
|
11799
12017
|
// src/cli.ts
|
|
11800
12018
|
import { mkdirSync, readFileSync as readFileSync3, watch as fsWatch, writeFileSync } from "fs";
|
|
11801
12019
|
import { basename, dirname, extname, join, resolve as resolve3 } from "path";
|
|
11802
|
-
var VERSION = "0.1.
|
|
12020
|
+
var VERSION = "0.1.32";
|
|
11803
12021
|
function printHelp() {
|
|
11804
12022
|
return `
|
|
11805
12023
|
YumiaMD \u2014 Markdown-based presentation compiler (v${VERSION})
|
|
@@ -12443,6 +12661,7 @@ export {
|
|
|
12443
12661
|
parseYumia,
|
|
12444
12662
|
migrateMarkdownToNative,
|
|
12445
12663
|
computeDiagramLayout,
|
|
12664
|
+
orthogonalEdgePoints,
|
|
12446
12665
|
fitDiagramLabel,
|
|
12447
12666
|
estimateDiagramHeight,
|
|
12448
12667
|
longestDiagramLabel,
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export * from '@yumiamd/renderer-pptx';
|
|
|
9
9
|
export * from '@yumiamd/renderer-html';
|
|
10
10
|
export * from '@yumiamd/renderer-pdf';
|
|
11
11
|
|
|
12
|
-
declare const VERSION = "0.1.
|
|
12
|
+
declare const VERSION = "0.1.32";
|
|
13
13
|
declare function printHelp(): string;
|
|
14
14
|
declare function runCli(argv: string[]): Promise<{
|
|
15
15
|
exitCode: number;
|
package/dist/index.js
CHANGED
|
@@ -71,6 +71,7 @@ import {
|
|
|
71
71
|
nebulaTheme,
|
|
72
72
|
neoBrutalistTheme,
|
|
73
73
|
nordTheme,
|
|
74
|
+
orthogonalEdgePoints,
|
|
74
75
|
parse,
|
|
75
76
|
parseDataString,
|
|
76
77
|
parseHighlightLines,
|
|
@@ -91,7 +92,7 @@ import {
|
|
|
91
92
|
themeSizeToPptxPoints,
|
|
92
93
|
tokyoNightTheme,
|
|
93
94
|
validate
|
|
94
|
-
} from "./chunk-
|
|
95
|
+
} from "./chunk-Y2OWK5OP.js";
|
|
95
96
|
export {
|
|
96
97
|
DEFAULT_VIEWPORT,
|
|
97
98
|
DefaultLayoutEngine,
|
|
@@ -165,6 +166,7 @@ export {
|
|
|
165
166
|
nebulaTheme,
|
|
166
167
|
neoBrutalistTheme,
|
|
167
168
|
nordTheme,
|
|
169
|
+
orthogonalEdgePoints,
|
|
168
170
|
parse,
|
|
169
171
|
parseDataString,
|
|
170
172
|
parseHighlightLines,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yumiamd",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.32",
|
|
4
4
|
"description": "Command line interface and compiler for YumiaMD presentations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,15 +22,15 @@
|
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"tsup": "^8.5.1",
|
|
25
|
-
"@yumiamd/
|
|
26
|
-
"@yumiamd/
|
|
27
|
-
"@yumiamd/renderer": "0.1.
|
|
28
|
-
"@yumiamd/
|
|
29
|
-
"@yumiamd/renderer
|
|
30
|
-
"@yumiamd/
|
|
31
|
-
"@yumiamd/
|
|
32
|
-
"@yumiamd/
|
|
33
|
-
"@yumiamd/
|
|
25
|
+
"@yumiamd/layout": "0.1.32",
|
|
26
|
+
"@yumiamd/ast": "0.1.32",
|
|
27
|
+
"@yumiamd/renderer-pdf": "0.1.32",
|
|
28
|
+
"@yumiamd/parser": "0.1.32",
|
|
29
|
+
"@yumiamd/renderer": "0.1.32",
|
|
30
|
+
"@yumiamd/theme": "0.1.32",
|
|
31
|
+
"@yumiamd/renderer-html": "0.1.32",
|
|
32
|
+
"@yumiamd/renderer-pptx": "0.1.32",
|
|
33
|
+
"@yumiamd/core": "0.1.32"
|
|
34
34
|
},
|
|
35
35
|
"keywords": [
|
|
36
36
|
"yumia",
|