@hirokisakabe/pom 8.7.0 → 8.9.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 +15 -3
- package/dist/buildContext.js +4 -2
- package/dist/buildContext.js.map +1 -1
- package/dist/buildPptx.d.ts.map +1 -1
- package/dist/buildPptx.js +3 -1
- package/dist/buildPptx.js.map +1 -1
- package/dist/parseXml/coercionRules.js +12 -2
- package/dist/parseXml/coercionRules.js.map +1 -1
- package/dist/parseXml/parseXml.d.ts.map +1 -1
- package/dist/parseXml/parseXml.js +3 -3
- package/dist/parseXml/parseXml.js.map +1 -1
- package/dist/renderPptx/glowEffects.js +147 -0
- package/dist/renderPptx/glowEffects.js.map +1 -0
- package/dist/renderPptx/gradientFills.js +36 -8
- package/dist/renderPptx/gradientFills.js.map +1 -1
- package/dist/renderPptx/nodes/icon.js +13 -6
- package/dist/renderPptx/nodes/icon.js.map +1 -1
- package/dist/renderPptx/nodes/shape.js +24 -2
- package/dist/renderPptx/nodes/shape.js.map +1 -1
- package/dist/renderPptx/nodes/text.js +7 -2
- package/dist/renderPptx/nodes/text.js.map +1 -1
- package/dist/renderPptx/nodes/timeline.js +41 -14
- package/dist/renderPptx/nodes/timeline.js.map +1 -1
- package/dist/renderPptx/renderPptx.js +1 -1
- package/dist/renderPptx/units.js +8 -1
- package/dist/renderPptx/units.js.map +1 -1
- package/dist/renderPptx/utils/backgroundBorder.js +1 -1
- package/dist/shared/gradient.js +185 -19
- package/dist/shared/gradient.js.map +1 -1
- package/dist/types.d.ts +24 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +15 -4
- package/dist/types.js.map +1 -1
- package/package.json +5 -5
package/dist/shared/gradient.js
CHANGED
|
@@ -54,6 +54,28 @@ function resolveStopPositions(stops) {
|
|
|
54
54
|
};
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
|
+
/** カラーストップ群 (`<color> [<pos>%]`) を parse する。失敗時 null */
|
|
58
|
+
function parseColorStops(stopArgs) {
|
|
59
|
+
if (stopArgs.length < 2) return null;
|
|
60
|
+
const stops = [];
|
|
61
|
+
for (const stopArg of stopArgs) {
|
|
62
|
+
const parts = stopArg.split(/\s+/);
|
|
63
|
+
if (parts.length === 0 || parts.length > 2) return null;
|
|
64
|
+
const color = normalizeColor(parts[0]);
|
|
65
|
+
if (color === null) return null;
|
|
66
|
+
let position;
|
|
67
|
+
if (parts.length === 2) {
|
|
68
|
+
const posMatch = /^(-?\d+(?:\.\d+)?)%$/.exec(parts[1]);
|
|
69
|
+
if (!posMatch) return null;
|
|
70
|
+
position = Number(posMatch[1]);
|
|
71
|
+
}
|
|
72
|
+
stops.push({
|
|
73
|
+
color,
|
|
74
|
+
position
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return resolveStopPositions(stops);
|
|
78
|
+
}
|
|
57
79
|
/**
|
|
58
80
|
* linear-gradient() 構文をパースする。不正な構文の場合は null を返す。
|
|
59
81
|
*/
|
|
@@ -74,30 +96,174 @@ function parseLinearGradient(value) {
|
|
|
74
96
|
angle = directionAngle;
|
|
75
97
|
stopArgs = args.slice(1);
|
|
76
98
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
99
|
+
const stops = parseColorStops(stopArgs);
|
|
100
|
+
if (!stops) return null;
|
|
101
|
+
return {
|
|
102
|
+
angle,
|
|
103
|
+
stops
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const SHAPE_KEYWORDS = new Set(["circle", "ellipse"]);
|
|
107
|
+
const SIZE_KEYWORDS = new Set([
|
|
108
|
+
"closest-side",
|
|
109
|
+
"closest-corner",
|
|
110
|
+
"farthest-side",
|
|
111
|
+
"farthest-corner"
|
|
112
|
+
]);
|
|
113
|
+
const POSITION_X_KEYWORDS = {
|
|
114
|
+
left: 0,
|
|
115
|
+
center: 50,
|
|
116
|
+
right: 100
|
|
117
|
+
};
|
|
118
|
+
const POSITION_Y_KEYWORDS = {
|
|
119
|
+
top: 0,
|
|
120
|
+
center: 50,
|
|
121
|
+
bottom: 100
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* `at <position>` の <position> 部分を parse する。
|
|
125
|
+
* 1〜2 トークンの組み合わせを受け取り、{ x, y } (各 0-100 %) を返す。
|
|
126
|
+
*
|
|
127
|
+
* 受け付ける形:
|
|
128
|
+
* center / left / right / top / bottom
|
|
129
|
+
* top right / left bottom / center top など (2 トークン)
|
|
130
|
+
* 50% / 25% 75% (% 値)
|
|
131
|
+
*
|
|
132
|
+
* 不正な組み合わせは null。
|
|
133
|
+
*/
|
|
134
|
+
function parsePosition(tokens) {
|
|
135
|
+
if (tokens.length === 0 || tokens.length > 2) return null;
|
|
136
|
+
if (tokens.length === 1) {
|
|
137
|
+
const t = tokens[0].toLowerCase();
|
|
138
|
+
if (t === "center") return {
|
|
139
|
+
x: 50,
|
|
140
|
+
y: 50
|
|
141
|
+
};
|
|
142
|
+
if (t in POSITION_X_KEYWORDS) return {
|
|
143
|
+
x: POSITION_X_KEYWORDS[t],
|
|
144
|
+
y: 50
|
|
145
|
+
};
|
|
146
|
+
if (t in POSITION_Y_KEYWORDS) return {
|
|
147
|
+
x: 50,
|
|
148
|
+
y: POSITION_Y_KEYWORDS[t]
|
|
149
|
+
};
|
|
150
|
+
const pct = /^(-?\d+(?:\.\d+)?)%$/.exec(t);
|
|
151
|
+
if (pct) return {
|
|
152
|
+
x: Number(pct[1]),
|
|
153
|
+
y: 50
|
|
154
|
+
};
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
let x = null;
|
|
158
|
+
let y = null;
|
|
159
|
+
let centerCount = 0;
|
|
160
|
+
for (const raw of tokens) {
|
|
161
|
+
const t = raw.toLowerCase();
|
|
162
|
+
const pct = /^(-?\d+(?:\.\d+)?)%$/.exec(t);
|
|
163
|
+
if (pct) {
|
|
164
|
+
const v = Number(pct[1]);
|
|
165
|
+
if (x === null) x = v;
|
|
166
|
+
else if (y === null) y = v;
|
|
167
|
+
else return null;
|
|
168
|
+
continue;
|
|
89
169
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
170
|
+
if (t === "left" || t === "right") {
|
|
171
|
+
if (x !== null) return null;
|
|
172
|
+
x = POSITION_X_KEYWORDS[t];
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (t === "top" || t === "bottom") {
|
|
176
|
+
if (y !== null) return null;
|
|
177
|
+
y = POSITION_Y_KEYWORDS[t];
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (t === "center") {
|
|
181
|
+
centerCount++;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
return null;
|
|
94
185
|
}
|
|
186
|
+
for (let i = 0; i < centerCount; i++) if (x === null) x = 50;
|
|
187
|
+
else if (y === null) y = 50;
|
|
188
|
+
else return null;
|
|
95
189
|
return {
|
|
96
|
-
|
|
97
|
-
|
|
190
|
+
x: x ?? 50,
|
|
191
|
+
y: y ?? 50
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* radial-gradient() 構文をパースする。不正な構文の場合は null を返す。
|
|
196
|
+
*
|
|
197
|
+
* 受け付ける構文:
|
|
198
|
+
* radial-gradient(<color stops>)
|
|
199
|
+
* radial-gradient(<shape>?, <color stops>) // 例: radial-gradient(circle, #FF0000, #0000FF)
|
|
200
|
+
* radial-gradient(<shape>? <size>?, <color stops>) // 例: radial-gradient(circle farthest-side, ...)
|
|
201
|
+
* radial-gradient(<shape>? <size>? at <position>, <color stops>) // 例: radial-gradient(ellipse at top right, ...)
|
|
202
|
+
* radial-gradient(at <position>, <color stops>) // 例: radial-gradient(at 25% 75%, ...)
|
|
203
|
+
*/
|
|
204
|
+
function parseRadialGradient(value) {
|
|
205
|
+
const match = /^\s*radial-gradient\s*\(\s*(.+?)\s*\)\s*$/.exec(value);
|
|
206
|
+
if (!match) return null;
|
|
207
|
+
const args = match[1].split(",").map((s) => s.trim());
|
|
208
|
+
if (args.length === 0) return null;
|
|
209
|
+
let shape = "ellipse";
|
|
210
|
+
let size = "farthest-corner";
|
|
211
|
+
let centerX = 50;
|
|
212
|
+
let centerY = 50;
|
|
213
|
+
let stopArgs = args;
|
|
214
|
+
const firstTokens = args[0].split(/\s+/).filter((t) => t.length > 0);
|
|
215
|
+
const firstLowerTokens = firstTokens.map((t) => t.toLowerCase());
|
|
216
|
+
if (firstLowerTokens.some((t) => SHAPE_KEYWORDS.has(t) || SIZE_KEYWORDS.has(t) || t === "at")) {
|
|
217
|
+
const atIdx = firstLowerTokens.indexOf("at");
|
|
218
|
+
const shapeSizeTokens = atIdx >= 0 ? firstLowerTokens.slice(0, atIdx) : firstLowerTokens;
|
|
219
|
+
const positionTokens = atIdx >= 0 ? firstTokens.slice(atIdx + 1) : [];
|
|
220
|
+
let shapeSeen = false;
|
|
221
|
+
let sizeSeen = false;
|
|
222
|
+
for (const token of shapeSizeTokens) if (SHAPE_KEYWORDS.has(token)) {
|
|
223
|
+
if (shapeSeen) return null;
|
|
224
|
+
shape = token;
|
|
225
|
+
shapeSeen = true;
|
|
226
|
+
} else if (SIZE_KEYWORDS.has(token)) {
|
|
227
|
+
if (sizeSeen) return null;
|
|
228
|
+
size = token;
|
|
229
|
+
sizeSeen = true;
|
|
230
|
+
} else return null;
|
|
231
|
+
if (atIdx >= 0) {
|
|
232
|
+
if (positionTokens.length === 0) return null;
|
|
233
|
+
const pos = parsePosition(positionTokens);
|
|
234
|
+
if (!pos) return null;
|
|
235
|
+
centerX = pos.x;
|
|
236
|
+
centerY = pos.y;
|
|
237
|
+
}
|
|
238
|
+
stopArgs = args.slice(1);
|
|
239
|
+
}
|
|
240
|
+
const stops = parseColorStops(stopArgs);
|
|
241
|
+
if (!stops) return null;
|
|
242
|
+
return {
|
|
243
|
+
shape,
|
|
244
|
+
size,
|
|
245
|
+
centerX,
|
|
246
|
+
centerY,
|
|
247
|
+
stops
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* linear-gradient / radial-gradient のいずれかを parse する。
|
|
252
|
+
*/
|
|
253
|
+
function parseGradient(value) {
|
|
254
|
+
const linear = parseLinearGradient(value);
|
|
255
|
+
if (linear) return {
|
|
256
|
+
kind: "linear",
|
|
257
|
+
value: linear
|
|
258
|
+
};
|
|
259
|
+
const radial = parseRadialGradient(value);
|
|
260
|
+
if (radial) return {
|
|
261
|
+
kind: "radial",
|
|
262
|
+
value: radial
|
|
98
263
|
};
|
|
264
|
+
return null;
|
|
99
265
|
}
|
|
100
266
|
//#endregion
|
|
101
|
-
export { parseLinearGradient };
|
|
267
|
+
export { parseGradient, parseLinearGradient };
|
|
102
268
|
|
|
103
269
|
//# sourceMappingURL=gradient.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gradient.js","names":[],"sources":["../../src/shared/gradient.ts"],"sourcesContent":["/**\n * リニアグラデーション文字列のパース\n *\n * CSS の linear-gradient() 風の構文を受け付ける:\n * linear-gradient(135deg, #FF0000 0%, #0000FF 100%)\n * linear-gradient(to right, #FF0000, #00FF00, #0000FF)\n * linear-gradient(#FF0000, #0000FF) ← 角度省略時は 180deg (上→下)\n *\n * - 角度: `<数値>deg` または `to <方向>` キーワード。省略時は 180deg。\n * - カラーストップ: 16進カラー (#RGB / #RRGGBB / RRGGBB) + 任意の位置 (%)。\n * 位置省略時は CSS と同様に補間する (先頭 0% / 末尾 100% / 中間は線形補間)。\n * - ストップは 2 つ以上必須。\n */\n\nexport interface GradientStop {\n /** 6桁大文字 HEX (# なし) */\n color: string;\n /** 0-100 (%) */\n position: number;\n}\n\nexport interface LinearGradient {\n /** CSS 基準の角度 (deg)。0 = 上向き、時計回り。0-360 に正規化済み */\n angle: number;\n stops: GradientStop[];\n}\n\n/** `to <方向>` キーワード → CSS 角度 (deg)。コーナーは 45 度刻みの近似 */\nconst DIRECTION_KEYWORDS: Record<string, number> = {\n \"to top\": 0,\n \"to right\": 90,\n \"to bottom\": 180,\n \"to left\": 270,\n \"to top right\": 45,\n \"to right top\": 45,\n \"to bottom right\": 135,\n \"to right bottom\": 135,\n \"to bottom left\": 225,\n \"to left bottom\": 225,\n \"to top left\": 315,\n \"to left top\": 315,\n};\n\nconst COLOR_PATTERN = /^#?([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/;\n\nfunction normalizeColor(raw: string): string | null {\n const match = COLOR_PATTERN.exec(raw);\n if (!match) return null;\n const hex = match[1];\n if (hex.length === 3) {\n return hex\n .split(\"\")\n .map((c) => c + c)\n .join(\"\")\n .toUpperCase();\n }\n return hex.toUpperCase();\n}\n\n/**\n * 位置省略されたストップに CSS 互換のルールで位置を割り当てる。\n * - 先頭が省略なら 0、末尾が省略なら 100\n * - 中間の省略は前後の明示位置の間で均等配置\n * - 位置が前のストップより小さい場合は前の値に切り上げ (非減少を保証)\n */\nfunction resolveStopPositions(\n stops: { color: string; position: number | undefined }[],\n): GradientStop[] {\n const positions: (number | undefined)[] = stops.map((s) => s.position);\n if (positions[0] === undefined) positions[0] = 0;\n if (positions[positions.length - 1] === undefined) {\n positions[positions.length - 1] = 100;\n }\n\n let prevIndex = 0;\n for (let i = 1; i < positions.length; i++) {\n if (positions[i] === undefined) continue;\n const gap = i - prevIndex;\n if (gap > 1) {\n const start = positions[prevIndex]!;\n const end = positions[i]!;\n for (let j = 1; j < gap; j++) {\n positions[prevIndex + j] = start + ((end - start) * j) / gap;\n }\n }\n prevIndex = i;\n }\n\n let prev = 0;\n return stops.map((stop, i) => {\n const clamped = Math.min(Math.max(positions[i]!, 0), 100);\n const position = Math.max(clamped, prev);\n prev = position;\n return { color: stop.color, position };\n });\n}\n\n/**\n * linear-gradient() 構文をパースする。不正な構文の場合は null を返す。\n */\nexport function parseLinearGradient(value: string): LinearGradient | null {\n const match = /^\\s*linear-gradient\\s*\\(\\s*(.+?)\\s*\\)\\s*$/.exec(value);\n if (!match) return null;\n\n const args = match[1].split(\",\").map((s) => s.trim());\n if (args.length === 0) return null;\n\n let angle = 180;\n let stopArgs = args;\n\n const first = args[0];\n const angleMatch = /^(-?\\d+(?:\\.\\d+)?)deg$/.exec(first);\n const directionAngle =\n DIRECTION_KEYWORDS[first.toLowerCase().replace(/\\s+/g, \" \")];\n if (angleMatch) {\n angle = ((Number(angleMatch[1]) % 360) + 360) % 360;\n stopArgs = args.slice(1);\n } else if (directionAngle !== undefined) {\n angle = directionAngle;\n stopArgs = args.slice(1);\n }\n\n if (stopArgs.length < 2) return null;\n\n const stops: { color: string; position: number | undefined }[] = [];\n for (const stopArg of stopArgs) {\n const parts = stopArg.split(/\\s+/);\n if (parts.length === 0 || parts.length > 2) return null;\n const color = normalizeColor(parts[0]);\n if (color === null) return null;\n\n let position: number | undefined;\n if (parts.length === 2) {\n const posMatch = /^(-?\\d+(?:\\.\\d+)?)%$/.exec(parts[1]);\n if (!posMatch) return null;\n position = Number(posMatch[1]);\n }\n stops.push({ color, position });\n }\n\n return { angle, stops: resolveStopPositions(stops) };\n}\n"],"mappings":";;AA4BA,MAAM,qBAA6C;CACjD,UAAU;CACV,YAAY;CACZ,aAAa;CACb,WAAW;CACX,gBAAgB;CAChB,gBAAgB;CAChB,mBAAmB;CACnB,mBAAmB;CACnB,kBAAkB;CAClB,kBAAkB;CAClB,eAAe;CACf,eAAe;AACjB;AAEA,MAAM,gBAAgB;AAEtB,SAAS,eAAe,KAA4B;CAClD,MAAM,QAAQ,cAAc,KAAK,GAAG;CACpC,IAAI,CAAC,OAAO,OAAO;CACnB,MAAM,MAAM,MAAM;CAClB,IAAI,IAAI,WAAW,GACjB,OAAO,IACJ,MAAM,EAAE,CAAC,CACT,KAAK,MAAM,IAAI,CAAC,CAAC,CACjB,KAAK,EAAE,CAAC,CACR,YAAY;CAEjB,OAAO,IAAI,YAAY;AACzB;;;;;;;AAQA,SAAS,qBACP,OACgB;CAChB,MAAM,YAAoC,MAAM,KAAK,MAAM,EAAE,QAAQ;CACrE,IAAI,UAAU,OAAO,KAAA,GAAW,UAAU,KAAK;CAC/C,IAAI,UAAU,UAAU,SAAS,OAAO,KAAA,GACtC,UAAU,UAAU,SAAS,KAAK;CAGpC,IAAI,YAAY;CAChB,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;EACzC,IAAI,UAAU,OAAO,KAAA,GAAW;EAChC,MAAM,MAAM,IAAI;EAChB,IAAI,MAAM,GAAG;GACX,MAAM,QAAQ,UAAU;GACxB,MAAM,MAAM,UAAU;GACtB,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KACvB,UAAU,YAAY,KAAK,SAAU,MAAM,SAAS,IAAK;EAE7D;EACA,YAAY;CACd;CAEA,IAAI,OAAO;CACX,OAAO,MAAM,KAAK,MAAM,MAAM;EAC5B,MAAM,UAAU,KAAK,IAAI,KAAK,IAAI,UAAU,IAAK,CAAC,GAAG,GAAG;EACxD,MAAM,WAAW,KAAK,IAAI,SAAS,IAAI;EACvC,OAAO;EACP,OAAO;GAAE,OAAO,KAAK;GAAO;EAAS;CACvC,CAAC;AACH;;;;AAKA,SAAgB,oBAAoB,OAAsC;CACxE,MAAM,QAAQ,4CAA4C,KAAK,KAAK;CACpE,IAAI,CAAC,OAAO,OAAO;CAEnB,MAAM,OAAO,MAAM,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,MAAM,EAAE,KAAK,CAAC;CACpD,IAAI,KAAK,WAAW,GAAG,OAAO;CAE9B,IAAI,QAAQ;CACZ,IAAI,WAAW;CAEf,MAAM,QAAQ,KAAK;CACnB,MAAM,aAAa,yBAAyB,KAAK,KAAK;CACtD,MAAM,iBACJ,mBAAmB,MAAM,YAAY,CAAC,CAAC,QAAQ,QAAQ,GAAG;CAC5D,IAAI,YAAY;EACd,SAAU,OAAO,WAAW,EAAE,IAAI,MAAO,OAAO;EAChD,WAAW,KAAK,MAAM,CAAC;CACzB,OAAO,IAAI,mBAAmB,KAAA,GAAW;EACvC,QAAQ;EACR,WAAW,KAAK,MAAM,CAAC;CACzB;CAEA,IAAI,SAAS,SAAS,GAAG,OAAO;CAEhC,MAAM,QAA2D,CAAC;CAClE,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,QAAQ,QAAQ,MAAM,KAAK;EACjC,IAAI,MAAM,WAAW,KAAK,MAAM,SAAS,GAAG,OAAO;EACnD,MAAM,QAAQ,eAAe,MAAM,EAAE;EACrC,IAAI,UAAU,MAAM,OAAO;EAE3B,IAAI;EACJ,IAAI,MAAM,WAAW,GAAG;GACtB,MAAM,WAAW,uBAAuB,KAAK,MAAM,EAAE;GACrD,IAAI,CAAC,UAAU,OAAO;GACtB,WAAW,OAAO,SAAS,EAAE;EAC/B;EACA,MAAM,KAAK;GAAE;GAAO;EAAS,CAAC;CAChC;CAEA,OAAO;EAAE;EAAO,OAAO,qBAAqB,KAAK;CAAE;AACrD"}
|
|
1
|
+
{"version":3,"file":"gradient.js","names":[],"sources":["../../src/shared/gradient.ts"],"sourcesContent":["/**\n * CSS 風グラデーション文字列のパース\n *\n * linear-gradient と radial-gradient の 2 種類を扱う:\n * linear-gradient(135deg, #FF0000 0%, #0000FF 100%)\n * linear-gradient(to right, #FF0000, #00FF00, #0000FF)\n * linear-gradient(#FF0000, #0000FF)\n * radial-gradient(circle at center, #FF0000, #0000FF)\n * radial-gradient(ellipse farthest-corner at 50% 50%, #FF0000 0%, #0000FF 100%)\n * radial-gradient(#FF0000, #0000FF)\n *\n * - 角度 (linear): `<数値>deg` または `to <方向>` キーワード。省略時は 180deg。\n * - 形状 (radial): `circle` / `ellipse`。省略時は `ellipse`。\n * PowerPoint の DrawingML radial fill は shape を区別しないため、出力上は同一になる。\n * - サイズキーワード (radial): `closest-side` / `closest-corner` / `farthest-side` /\n * `farthest-corner`。省略時は `farthest-corner`。MVP では構文として受け付けるのみで\n * 出力は farthest-corner 相当 (PPT 標準) に固定。\n * - 中心位置 (radial): `at <position>` で指定。`center` / `top right` / `25% 75%` 等。\n * 省略時は `center` (50% 50%)。\n * - カラーストップ: 16進カラー (#RGB / #RRGGBB / RRGGBB) + 任意の位置 (%)。\n * 位置省略時は CSS と同様に補間する (先頭 0% / 末尾 100% / 中間は線形補間)。\n * - ストップは 2 つ以上必須。\n */\n\nexport interface GradientStop {\n /** 6桁大文字 HEX (# なし) */\n color: string;\n /** 0-100 (%) */\n position: number;\n}\n\nexport interface LinearGradient {\n /** CSS 基準の角度 (deg)。0 = 上向き、時計回り。0-360 に正規化済み */\n angle: number;\n stops: GradientStop[];\n}\n\nexport type RadialGradientShape = \"circle\" | \"ellipse\";\nexport type RadialGradientSize =\n | \"closest-side\"\n | \"closest-corner\"\n | \"farthest-side\"\n | \"farthest-corner\";\n\nexport interface RadialGradient {\n shape: RadialGradientShape;\n size: RadialGradientSize;\n /** 中心位置 X (%、0=左 / 100=右) */\n centerX: number;\n /** 中心位置 Y (%、0=上 / 100=下) */\n centerY: number;\n stops: GradientStop[];\n}\n\nexport type Gradient =\n | { kind: \"linear\"; value: LinearGradient }\n | { kind: \"radial\"; value: RadialGradient };\n\n/** `to <方向>` キーワード → CSS 角度 (deg)。コーナーは 45 度刻みの近似 */\nconst DIRECTION_KEYWORDS: Record<string, number> = {\n \"to top\": 0,\n \"to right\": 90,\n \"to bottom\": 180,\n \"to left\": 270,\n \"to top right\": 45,\n \"to right top\": 45,\n \"to bottom right\": 135,\n \"to right bottom\": 135,\n \"to bottom left\": 225,\n \"to left bottom\": 225,\n \"to top left\": 315,\n \"to left top\": 315,\n};\n\nconst COLOR_PATTERN = /^#?([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/;\n\nfunction normalizeColor(raw: string): string | null {\n const match = COLOR_PATTERN.exec(raw);\n if (!match) return null;\n const hex = match[1];\n if (hex.length === 3) {\n return hex\n .split(\"\")\n .map((c) => c + c)\n .join(\"\")\n .toUpperCase();\n }\n return hex.toUpperCase();\n}\n\n/**\n * 位置省略されたストップに CSS 互換のルールで位置を割り当てる。\n * - 先頭が省略なら 0、末尾が省略なら 100\n * - 中間の省略は前後の明示位置の間で均等配置\n * - 位置が前のストップより小さい場合は前の値に切り上げ (非減少を保証)\n */\nfunction resolveStopPositions(\n stops: { color: string; position: number | undefined }[],\n): GradientStop[] {\n const positions: (number | undefined)[] = stops.map((s) => s.position);\n if (positions[0] === undefined) positions[0] = 0;\n if (positions[positions.length - 1] === undefined) {\n positions[positions.length - 1] = 100;\n }\n\n let prevIndex = 0;\n for (let i = 1; i < positions.length; i++) {\n if (positions[i] === undefined) continue;\n const gap = i - prevIndex;\n if (gap > 1) {\n const start = positions[prevIndex]!;\n const end = positions[i]!;\n for (let j = 1; j < gap; j++) {\n positions[prevIndex + j] = start + ((end - start) * j) / gap;\n }\n }\n prevIndex = i;\n }\n\n let prev = 0;\n return stops.map((stop, i) => {\n const clamped = Math.min(Math.max(positions[i]!, 0), 100);\n const position = Math.max(clamped, prev);\n prev = position;\n return { color: stop.color, position };\n });\n}\n\n/** カラーストップ群 (`<color> [<pos>%]`) を parse する。失敗時 null */\nfunction parseColorStops(stopArgs: string[]): GradientStop[] | null {\n if (stopArgs.length < 2) return null;\n const stops: { color: string; position: number | undefined }[] = [];\n for (const stopArg of stopArgs) {\n const parts = stopArg.split(/\\s+/);\n if (parts.length === 0 || parts.length > 2) return null;\n const color = normalizeColor(parts[0]);\n if (color === null) return null;\n\n let position: number | undefined;\n if (parts.length === 2) {\n const posMatch = /^(-?\\d+(?:\\.\\d+)?)%$/.exec(parts[1]);\n if (!posMatch) return null;\n position = Number(posMatch[1]);\n }\n stops.push({ color, position });\n }\n return resolveStopPositions(stops);\n}\n\n/**\n * linear-gradient() 構文をパースする。不正な構文の場合は null を返す。\n */\nexport function parseLinearGradient(value: string): LinearGradient | null {\n const match = /^\\s*linear-gradient\\s*\\(\\s*(.+?)\\s*\\)\\s*$/.exec(value);\n if (!match) return null;\n\n const args = match[1].split(\",\").map((s) => s.trim());\n if (args.length === 0) return null;\n\n let angle = 180;\n let stopArgs = args;\n\n const first = args[0];\n const angleMatch = /^(-?\\d+(?:\\.\\d+)?)deg$/.exec(first);\n const directionAngle =\n DIRECTION_KEYWORDS[first.toLowerCase().replace(/\\s+/g, \" \")];\n if (angleMatch) {\n angle = ((Number(angleMatch[1]) % 360) + 360) % 360;\n stopArgs = args.slice(1);\n } else if (directionAngle !== undefined) {\n angle = directionAngle;\n stopArgs = args.slice(1);\n }\n\n const stops = parseColorStops(stopArgs);\n if (!stops) return null;\n\n return { angle, stops };\n}\n\nconst SHAPE_KEYWORDS: ReadonlySet<string> = new Set([\"circle\", \"ellipse\"]);\nconst SIZE_KEYWORDS: ReadonlySet<string> = new Set([\n \"closest-side\",\n \"closest-corner\",\n \"farthest-side\",\n \"farthest-corner\",\n]);\nconst POSITION_X_KEYWORDS: Record<string, number> = {\n left: 0,\n center: 50,\n right: 100,\n};\nconst POSITION_Y_KEYWORDS: Record<string, number> = {\n top: 0,\n center: 50,\n bottom: 100,\n};\n\n/**\n * `at <position>` の <position> 部分を parse する。\n * 1〜2 トークンの組み合わせを受け取り、{ x, y } (各 0-100 %) を返す。\n *\n * 受け付ける形:\n * center / left / right / top / bottom\n * top right / left bottom / center top など (2 トークン)\n * 50% / 25% 75% (% 値)\n *\n * 不正な組み合わせは null。\n */\nfunction parsePosition(tokens: string[]): { x: number; y: number } | null {\n if (tokens.length === 0 || tokens.length > 2) return null;\n if (tokens.length === 1) {\n const t = tokens[0].toLowerCase();\n if (t === \"center\") return { x: 50, y: 50 };\n if (t in POSITION_X_KEYWORDS) {\n return { x: POSITION_X_KEYWORDS[t], y: 50 };\n }\n if (t in POSITION_Y_KEYWORDS) {\n return { x: 50, y: POSITION_Y_KEYWORDS[t] };\n }\n const pct = /^(-?\\d+(?:\\.\\d+)?)%$/.exec(t);\n if (pct) return { x: Number(pct[1]), y: 50 };\n return null;\n }\n // 2 tokens. center は X/Y どちらにも割り当て可能なため一旦保留し、\n // 残りトークン処理後に未確定の軸へ振り分ける (CSS の `<position>` 2-value 構文に従う)。\n let x: number | null = null;\n let y: number | null = null;\n let centerCount = 0;\n for (const raw of tokens) {\n const t = raw.toLowerCase();\n const pct = /^(-?\\d+(?:\\.\\d+)?)%$/.exec(t);\n if (pct) {\n const v = Number(pct[1]);\n if (x === null) x = v;\n else if (y === null) y = v;\n else return null;\n continue;\n }\n if (t === \"left\" || t === \"right\") {\n if (x !== null) return null;\n x = POSITION_X_KEYWORDS[t];\n continue;\n }\n if (t === \"top\" || t === \"bottom\") {\n if (y !== null) return null;\n y = POSITION_Y_KEYWORDS[t];\n continue;\n }\n if (t === \"center\") {\n centerCount++;\n continue;\n }\n return null;\n }\n // center を未確定軸に割り当てる。両方未確定なら 1 つ目 center で X=50、\n // 2 つ目 center で Y=50 になる。\n for (let i = 0; i < centerCount; i++) {\n if (x === null) x = 50;\n else if (y === null) y = 50;\n else return null;\n }\n return { x: x ?? 50, y: y ?? 50 };\n}\n\n/**\n * radial-gradient() 構文をパースする。不正な構文の場合は null を返す。\n *\n * 受け付ける構文:\n * radial-gradient(<color stops>)\n * radial-gradient(<shape>?, <color stops>) // 例: radial-gradient(circle, #FF0000, #0000FF)\n * radial-gradient(<shape>? <size>?, <color stops>) // 例: radial-gradient(circle farthest-side, ...)\n * radial-gradient(<shape>? <size>? at <position>, <color stops>) // 例: radial-gradient(ellipse at top right, ...)\n * radial-gradient(at <position>, <color stops>) // 例: radial-gradient(at 25% 75%, ...)\n */\nexport function parseRadialGradient(value: string): RadialGradient | null {\n const match = /^\\s*radial-gradient\\s*\\(\\s*(.+?)\\s*\\)\\s*$/.exec(value);\n if (!match) return null;\n\n const args = match[1].split(\",\").map((s) => s.trim());\n if (args.length === 0) return null;\n\n let shape: RadialGradientShape = \"ellipse\";\n let size: RadialGradientSize = \"farthest-corner\";\n let centerX = 50;\n let centerY = 50;\n let stopArgs = args;\n\n const first = args[0];\n const firstTokens = first.split(/\\s+/).filter((t) => t.length > 0);\n const firstLowerTokens = firstTokens.map((t) => t.toLowerCase());\n\n // prelude 判定: shape / size / \"at\" のいずれかキーワードが含まれていれば prelude として扱う。\n const hasPreludeKeyword = firstLowerTokens.some(\n (t) => SHAPE_KEYWORDS.has(t) || SIZE_KEYWORDS.has(t) || t === \"at\",\n );\n\n if (hasPreludeKeyword) {\n const atIdx = firstLowerTokens.indexOf(\"at\");\n const shapeSizeTokens =\n atIdx >= 0 ? firstLowerTokens.slice(0, atIdx) : firstLowerTokens;\n const positionTokens = atIdx >= 0 ? firstTokens.slice(atIdx + 1) : [];\n\n let shapeSeen = false;\n let sizeSeen = false;\n for (const token of shapeSizeTokens) {\n if (SHAPE_KEYWORDS.has(token)) {\n if (shapeSeen) return null;\n shape = token as RadialGradientShape;\n shapeSeen = true;\n } else if (SIZE_KEYWORDS.has(token)) {\n if (sizeSeen) return null;\n size = token as RadialGradientSize;\n sizeSeen = true;\n } else {\n return null;\n }\n }\n\n if (atIdx >= 0) {\n if (positionTokens.length === 0) return null;\n const pos = parsePosition(positionTokens);\n if (!pos) return null;\n centerX = pos.x;\n centerY = pos.y;\n }\n\n stopArgs = args.slice(1);\n }\n\n const stops = parseColorStops(stopArgs);\n if (!stops) return null;\n\n return { shape, size, centerX, centerY, stops };\n}\n\n/**\n * linear-gradient / radial-gradient のいずれかを parse する。\n */\nexport function parseGradient(value: string): Gradient | null {\n const linear = parseLinearGradient(value);\n if (linear) return { kind: \"linear\", value: linear };\n const radial = parseRadialGradient(value);\n if (radial) return { kind: \"radial\", value: radial };\n return null;\n}\n"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -303,6 +303,7 @@ declare const textNodeSchema: z.ZodObject<{
|
|
|
303
303
|
rotate: z.ZodOptional<z.ZodNumber>;
|
|
304
304
|
fontSize: z.ZodOptional<z.ZodNumber>;
|
|
305
305
|
color: z.ZodOptional<z.ZodString>;
|
|
306
|
+
textGradient: z.ZodOptional<z.ZodString>;
|
|
306
307
|
textAlign: z.ZodOptional<z.ZodEnum<{
|
|
307
308
|
right: "right";
|
|
308
309
|
left: "left";
|
|
@@ -1078,6 +1079,15 @@ declare const iconNodeSchema: z.ZodObject<{
|
|
|
1078
1079
|
"square-outlined": "square-outlined";
|
|
1079
1080
|
}>>;
|
|
1080
1081
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
1082
|
+
glow: z.ZodOptional<z.ZodObject<{
|
|
1083
|
+
size: z.ZodOptional<z.ZodNumber>;
|
|
1084
|
+
opacity: z.ZodOptional<z.ZodNumber>;
|
|
1085
|
+
color: z.ZodOptional<z.ZodString>;
|
|
1086
|
+
}, z.core.$strip>>;
|
|
1087
|
+
outline: z.ZodOptional<z.ZodObject<{
|
|
1088
|
+
size: z.ZodOptional<z.ZodNumber>;
|
|
1089
|
+
color: z.ZodOptional<z.ZodString>;
|
|
1090
|
+
}, z.core.$strip>>;
|
|
1081
1091
|
rotate: z.ZodOptional<z.ZodNumber>;
|
|
1082
1092
|
}, z.core.$strip>;
|
|
1083
1093
|
type IconNode = z.infer<typeof iconNodeSchema>;
|
|
@@ -1752,6 +1762,15 @@ declare const shapeNodeSchema: z.ZodObject<{
|
|
|
1752
1762
|
sysDot: "sysDot";
|
|
1753
1763
|
}>>;
|
|
1754
1764
|
}, z.core.$strip>>;
|
|
1765
|
+
glow: z.ZodOptional<z.ZodObject<{
|
|
1766
|
+
size: z.ZodOptional<z.ZodNumber>;
|
|
1767
|
+
opacity: z.ZodOptional<z.ZodNumber>;
|
|
1768
|
+
color: z.ZodOptional<z.ZodString>;
|
|
1769
|
+
}, z.core.$strip>>;
|
|
1770
|
+
outline: z.ZodOptional<z.ZodObject<{
|
|
1771
|
+
size: z.ZodOptional<z.ZodNumber>;
|
|
1772
|
+
color: z.ZodOptional<z.ZodString>;
|
|
1773
|
+
}, z.core.$strip>>;
|
|
1755
1774
|
fontSize: z.ZodOptional<z.ZodNumber>;
|
|
1756
1775
|
color: z.ZodOptional<z.ZodString>;
|
|
1757
1776
|
textAlign: z.ZodOptional<z.ZodEnum<{
|
|
@@ -2088,10 +2107,15 @@ declare const timelineNodeSchema: z.ZodObject<{
|
|
|
2088
2107
|
title: z.ZodString;
|
|
2089
2108
|
description: z.ZodOptional<z.ZodString>;
|
|
2090
2109
|
color: z.ZodOptional<z.ZodString>;
|
|
2110
|
+
dateColor: z.ZodOptional<z.ZodString>;
|
|
2091
2111
|
}, z.core.$strip>>;
|
|
2092
2112
|
dateColor: z.ZodOptional<z.ZodString>;
|
|
2093
2113
|
titleColor: z.ZodOptional<z.ZodString>;
|
|
2094
2114
|
descriptionColor: z.ZodOptional<z.ZodString>;
|
|
2115
|
+
connectorColor: z.ZodOptional<z.ZodString>;
|
|
2116
|
+
connectorGradient: z.ZodOptional<z.ZodString>;
|
|
2117
|
+
useColorForDate: z.ZodOptional<z.ZodBoolean>;
|
|
2118
|
+
fontFamily: z.ZodOptional<z.ZodString>;
|
|
2095
2119
|
}, z.core.$strip>;
|
|
2096
2120
|
type TimelineNode = z.infer<typeof timelineNodeSchema>;
|
|
2097
2121
|
declare const matrixNodeSchema: z.ZodObject<{
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;cA4GM,gBAAA,EAAgB,CAAA,CAAA,OAAA;;;;;;cAMhB,cAAA,EAAc,CAAA,CAAA,OAAA;;;;;cAEd,oBAAA,EAAoB,CAAA,CAAA,OAAA;;;;;;;;KAiMd,UAAA,GAAa,CAAA,CAAE,KAAK,QAAQ,gBAAA;AAAA,KAC5B,QAAA,GAAW,CAAA,CAAE,KAAK,QAAQ,cAAA;AAAA,KAC1B,cAAA,GAAiB,CAAA,CAAE,KAAK,QAAQ,oBAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":"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"}
|
package/dist/types.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { parseGradient, parseLinearGradient } from "./shared/gradient.js";
|
|
1
2
|
import { ICON_DATA } from "./icons/iconData.js";
|
|
2
|
-
import { parseLinearGradient } from "./shared/gradient.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
//#region src/types.ts
|
|
5
5
|
const lengthSchema = z.union([
|
|
@@ -300,7 +300,8 @@ const backgroundImageSchema = z.object({
|
|
|
300
300
|
src: z.string(),
|
|
301
301
|
sizing: backgroundImageSizingSchema.optional()
|
|
302
302
|
});
|
|
303
|
-
const backgroundGradientSchema = z.string().refine((value) =>
|
|
303
|
+
const backgroundGradientSchema = z.string().refine((value) => parseGradient(value) !== null, { message: "Invalid gradient syntax. Expected: linear-gradient(<angle>deg, <color> <position>%, ...) or radial-gradient(<shape>? <size>? at <position>?, <color> <position>%, ...) e.g. \"linear-gradient(135deg, #FF0000 0%, #0000FF 100%)\" or \"radial-gradient(circle at center, #FF0000 0%, #0000FF 100%)\"" });
|
|
304
|
+
const textGradientSchema = z.string().refine((value) => parseLinearGradient(value) !== null, { message: "Invalid textGradient syntax. Expected: linear-gradient(<angle>deg, <color> <position>%, ...). radial-gradient is not supported on textGradient." });
|
|
304
305
|
const basePOMNodeSchema = z.object({
|
|
305
306
|
id: z.string().optional(),
|
|
306
307
|
w: lengthSchema.optional(),
|
|
@@ -353,6 +354,7 @@ const textNodeSchema = basePOMNodeSchema.extend({
|
|
|
353
354
|
rotate: z.number().optional(),
|
|
354
355
|
fontSize: z.number().optional(),
|
|
355
356
|
color: z.string().optional(),
|
|
357
|
+
textGradient: textGradientSchema.optional(),
|
|
356
358
|
textAlign: z.enum([
|
|
357
359
|
"left",
|
|
358
360
|
"center",
|
|
@@ -459,6 +461,8 @@ const iconNodeSchema = basePOMNodeSchema.extend({
|
|
|
459
461
|
color: iconColorSchema,
|
|
460
462
|
variant: iconVariantSchema,
|
|
461
463
|
bgColor: iconColorSchema,
|
|
464
|
+
glow: textGlowSchema.optional(),
|
|
465
|
+
outline: textOutlineSchema.optional(),
|
|
462
466
|
rotate: z.number().optional()
|
|
463
467
|
});
|
|
464
468
|
const svgNodeSchema = basePOMNodeSchema.extend({
|
|
@@ -509,6 +513,8 @@ const shapeNodeSchema = basePOMNodeSchema.extend({
|
|
|
509
513
|
rotate: z.number().optional(),
|
|
510
514
|
fill: fillStyleSchema.optional(),
|
|
511
515
|
line: borderStyleSchema.optional(),
|
|
516
|
+
glow: textGlowSchema.optional(),
|
|
517
|
+
outline: textOutlineSchema.optional(),
|
|
512
518
|
fontSize: z.number().optional(),
|
|
513
519
|
color: z.string().optional(),
|
|
514
520
|
textAlign: z.enum([
|
|
@@ -560,7 +566,8 @@ const timelineItemSchema = z.object({
|
|
|
560
566
|
date: z.string(),
|
|
561
567
|
title: z.string(),
|
|
562
568
|
description: z.string().optional(),
|
|
563
|
-
color: z.string().optional()
|
|
569
|
+
color: z.string().optional(),
|
|
570
|
+
dateColor: z.string().optional()
|
|
564
571
|
});
|
|
565
572
|
const timelineNodeSchema = basePOMNodeSchema.extend({
|
|
566
573
|
type: z.literal("timeline"),
|
|
@@ -568,7 +575,11 @@ const timelineNodeSchema = basePOMNodeSchema.extend({
|
|
|
568
575
|
items: z.array(timelineItemSchema),
|
|
569
576
|
dateColor: z.string().optional(),
|
|
570
577
|
titleColor: z.string().optional(),
|
|
571
|
-
descriptionColor: z.string().optional()
|
|
578
|
+
descriptionColor: z.string().optional(),
|
|
579
|
+
connectorColor: z.string().optional(),
|
|
580
|
+
connectorGradient: backgroundGradientSchema.optional(),
|
|
581
|
+
useColorForDate: z.boolean().optional(),
|
|
582
|
+
fontFamily: z.string().optional()
|
|
572
583
|
});
|
|
573
584
|
const matrixAxisSchema = z.object({
|
|
574
585
|
x: z.string(),
|