@hirokisakabe/pom 9.1.2 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/buildContext.js +2 -2
  2. package/dist/buildContext.js.map +1 -1
  3. package/dist/buildPptx.d.ts +2 -1
  4. package/dist/buildPptx.d.ts.map +1 -1
  5. package/dist/buildPptx.js +4 -3
  6. package/dist/buildPptx.js.map +1 -1
  7. package/dist/calcYogaLayout/calcYogaLayout.js +1 -1
  8. package/dist/calcYogaLayout/calcYogaLayout.js.map +1 -1
  9. package/dist/index.d.ts +2 -1
  10. package/dist/registry/definitions/icon.js +1 -1
  11. package/dist/registry/definitions/list.js.map +1 -1
  12. package/dist/renderPptx/nodes/chart.js +172 -47
  13. package/dist/renderPptx/nodes/chart.js.map +1 -1
  14. package/dist/renderPptx/nodes/flow.js +4 -1
  15. package/dist/renderPptx/nodes/flow.js.map +1 -1
  16. package/dist/renderPptx/nodes/icon.js +5 -2
  17. package/dist/renderPptx/nodes/icon.js.map +1 -1
  18. package/dist/renderPptx/nodes/list.js +7 -9
  19. package/dist/renderPptx/nodes/list.js.map +1 -1
  20. package/dist/renderPptx/nodes/matrix.js +4 -1
  21. package/dist/renderPptx/nodes/matrix.js.map +1 -1
  22. package/dist/renderPptx/nodes/processArrow.js +8 -2
  23. package/dist/renderPptx/nodes/processArrow.js.map +1 -1
  24. package/dist/renderPptx/nodes/pyramid.js +4 -1
  25. package/dist/renderPptx/nodes/pyramid.js.map +1 -1
  26. package/dist/renderPptx/nodes/shape.js +5 -2
  27. package/dist/renderPptx/nodes/shape.js.map +1 -1
  28. package/dist/renderPptx/nodes/table.js +89 -59
  29. package/dist/renderPptx/nodes/table.js.map +1 -1
  30. package/dist/renderPptx/nodes/text.js +1 -18
  31. package/dist/renderPptx/nodes/text.js.map +1 -1
  32. package/dist/renderPptx/nodes/timeline.js +9 -3
  33. package/dist/renderPptx/nodes/timeline.js.map +1 -1
  34. package/dist/renderPptx/nodes/tree.js +4 -1
  35. package/dist/renderPptx/nodes/tree.js.map +1 -1
  36. package/dist/renderPptx/pptxAuthoring.js +381 -0
  37. package/dist/renderPptx/pptxAuthoring.js.map +1 -0
  38. package/dist/renderPptx/renderPptx.js +157 -126
  39. package/dist/renderPptx/renderPptx.js.map +1 -1
  40. package/dist/renderPptx/textOptions.js +7 -8
  41. package/dist/renderPptx/textOptions.js.map +1 -1
  42. package/dist/renderPptx/units.js +3 -3
  43. package/dist/renderPptx/units.js.map +1 -1
  44. package/dist/renderPptx/utils/backgroundBorder.js +30 -44
  45. package/dist/renderPptx/utils/backgroundBorder.js.map +1 -1
  46. package/dist/renderPptx/utils/contentArea.js +1 -1
  47. package/dist/renderPptx/utils/contentArea.js.map +1 -1
  48. package/dist/renderPptx/utils/glimpsePicture.js +3 -22
  49. package/dist/renderPptx/utils/glimpsePicture.js.map +1 -1
  50. package/dist/renderPptx/utils/glimpseShape.js +6 -25
  51. package/dist/renderPptx/utils/glimpseShape.js.map +1 -1
  52. package/dist/renderPptx/utils/glimpseTextBox.js +41 -60
  53. package/dist/renderPptx/utils/glimpseTextBox.js.map +1 -1
  54. package/dist/renderPptx/utils/straightLine.js +5 -2
  55. package/dist/renderPptx/utils/straightLine.js.map +1 -1
  56. package/dist/renderPptx/utils/visualStyle.js +3 -33
  57. package/dist/renderPptx/utils/visualStyle.js.map +1 -1
  58. package/dist/renderPptx/writablePptx.d.ts +23 -0
  59. package/dist/renderPptx/writablePptx.d.ts.map +1 -0
  60. package/dist/renderPptx/writablePptx.js +74 -0
  61. package/dist/renderPptx/writablePptx.js.map +1 -0
  62. package/dist/shared/measureImage.js.map +1 -1
  63. package/package.json +4 -5
  64. package/dist/renderPptx/glimpseTextBoxes.js +0 -646
  65. package/dist/renderPptx/glimpseTextBoxes.js.map +0 -1
@@ -0,0 +1,74 @@
1
+ import { writePptx } from "@pptx-glimpse/document";
2
+ //#region src/renderPptx/writablePptx.ts
3
+ function toArrayBuffer(bytes) {
4
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
5
+ }
6
+ function toBinaryString(bytes) {
7
+ let result = "";
8
+ for (const byte of bytes) result += String.fromCharCode(byte);
9
+ return result;
10
+ }
11
+ function toBase64(bytes) {
12
+ if (typeof Buffer !== "undefined") return Buffer.from(bytes).toString("base64");
13
+ return btoa(toBinaryString(bytes));
14
+ }
15
+ function normalizeFileName(fileName) {
16
+ return fileName.toLowerCase().endsWith(".pptx") ? fileName : `${fileName}.pptx`;
17
+ }
18
+ function downloadInBrowser(fileName, bytes) {
19
+ const blob = new Blob([toArrayBuffer(bytes)], { type: "application/vnd.openxmlformats-officedocument.presentationml.presentation" });
20
+ const url = URL.createObjectURL(blob);
21
+ let anchor;
22
+ const cleanup = () => {
23
+ try {
24
+ anchor?.remove();
25
+ } finally {
26
+ URL.revokeObjectURL(url);
27
+ }
28
+ };
29
+ let cleanupScheduled = false;
30
+ try {
31
+ anchor = document.createElement("a");
32
+ anchor.href = url;
33
+ anchor.download = fileName;
34
+ document.body.append(anchor);
35
+ anchor.click();
36
+ setTimeout(cleanup, 0);
37
+ cleanupScheduled = true;
38
+ } finally {
39
+ if (!cleanupScheduled) cleanup();
40
+ }
41
+ }
42
+ function createWritablePptx(getSource) {
43
+ function write(options) {
44
+ return Promise.resolve().then(() => {
45
+ const bytes = writePptx(getSource());
46
+ switch (options?.outputType) {
47
+ case "arraybuffer": return toArrayBuffer(bytes);
48
+ case "base64": return toBase64(bytes);
49
+ case "binarystring": return toBinaryString(bytes);
50
+ case "nodebuffer": return Buffer.from(bytes);
51
+ case "uint8array": return bytes;
52
+ case "blob":
53
+ case void 0: return new Blob([toArrayBuffer(bytes)], { type: "application/vnd.openxmlformats-officedocument.presentationml.presentation" });
54
+ }
55
+ });
56
+ }
57
+ return {
58
+ write,
59
+ stream() {
60
+ return Promise.resolve().then(() => writePptx(getSource()));
61
+ },
62
+ async writeFile(options) {
63
+ const fileName = normalizeFileName(typeof options === "string" ? options : options?.fileName ?? "Presentation.pptx");
64
+ const bytes = writePptx(getSource());
65
+ if (typeof document !== "undefined") downloadInBrowser(fileName, bytes);
66
+ else await (await import("node:fs/promises")).writeFile(fileName, bytes);
67
+ return fileName;
68
+ }
69
+ };
70
+ }
71
+ //#endregion
72
+ export { createWritablePptx };
73
+
74
+ //# sourceMappingURL=writablePptx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writablePptx.js","names":[],"sources":["../../src/renderPptx/writablePptx.ts"],"sourcesContent":["import { writePptx, type PptxSourceModel } from \"@pptx-glimpse/document\";\nimport type { Buffer as NodeBuffer } from \"node:buffer\";\n\nexport type PptxOutputType =\n | \"arraybuffer\"\n | \"base64\"\n | \"binarystring\"\n | \"blob\"\n | \"nodebuffer\"\n | \"uint8array\";\n\nexport type PptxWriteOptions = {\n outputType?: PptxOutputType;\n};\n\nexport type PptxWriteFileOptions = {\n fileName?: string;\n};\n\nexport type PptxWriteOutput<T extends PptxOutputType | undefined> =\n T extends \"arraybuffer\"\n ? ArrayBuffer\n : T extends \"base64\" | \"binarystring\"\n ? string\n : T extends \"nodebuffer\"\n ? NodeBuffer\n : T extends \"uint8array\"\n ? Uint8Array\n : Blob;\n\nexport interface WritablePptx {\n write(): Promise<Blob>;\n write<T extends PptxOutputType>(\n options: PptxWriteOptions & { outputType: T },\n ): Promise<PptxWriteOutput<T>>;\n write(\n options: PptxWriteOptions,\n ): Promise<PptxWriteOutput<PptxOutputType | undefined>>;\n stream(): Promise<Uint8Array>;\n writeFile(options?: PptxWriteFileOptions | string): Promise<string>;\n}\n\nfunction toArrayBuffer(bytes: Uint8Array): ArrayBuffer {\n return bytes.buffer.slice(\n bytes.byteOffset,\n bytes.byteOffset + bytes.byteLength,\n ) as ArrayBuffer;\n}\n\nfunction toBinaryString(bytes: Uint8Array): string {\n let result = \"\";\n for (const byte of bytes) result += String.fromCharCode(byte);\n return result;\n}\n\nfunction toBase64(bytes: Uint8Array): string {\n if (typeof Buffer !== \"undefined\")\n return Buffer.from(bytes).toString(\"base64\");\n return btoa(toBinaryString(bytes));\n}\n\nfunction normalizeFileName(fileName: string): string {\n return fileName.toLowerCase().endsWith(\".pptx\")\n ? fileName\n : `${fileName}.pptx`;\n}\n\nfunction downloadInBrowser(fileName: string, bytes: Uint8Array): void {\n const blob = new Blob([toArrayBuffer(bytes)], {\n type: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n });\n const url = URL.createObjectURL(blob);\n let anchor: HTMLAnchorElement | undefined;\n const cleanup = () => {\n try {\n anchor?.remove();\n } finally {\n URL.revokeObjectURL(url);\n }\n };\n let cleanupScheduled = false;\n try {\n anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = fileName;\n document.body.append(anchor);\n anchor.click();\n setTimeout(cleanup, 0);\n cleanupScheduled = true;\n } finally {\n if (!cleanupScheduled) cleanup();\n }\n}\n\nexport function createWritablePptx(\n getSource: () => PptxSourceModel,\n): WritablePptx {\n function write(options?: PptxWriteOptions): Promise<unknown> {\n return Promise.resolve().then(() => {\n const bytes = writePptx(getSource());\n switch (options?.outputType) {\n case \"arraybuffer\":\n return toArrayBuffer(bytes);\n case \"base64\":\n return toBase64(bytes);\n case \"binarystring\":\n return toBinaryString(bytes);\n case \"nodebuffer\":\n return Buffer.from(bytes);\n case \"uint8array\":\n return bytes;\n case \"blob\":\n case undefined:\n return new Blob([toArrayBuffer(bytes)], {\n type: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n });\n }\n });\n }\n\n return {\n write: write as WritablePptx[\"write\"],\n stream() {\n return Promise.resolve().then(() => writePptx(getSource()));\n },\n async writeFile(options) {\n const fileName = normalizeFileName(\n typeof options === \"string\"\n ? options\n : (options?.fileName ?? \"Presentation.pptx\"),\n );\n const bytes = writePptx(getSource());\n if (typeof document !== \"undefined\") {\n downloadInBrowser(fileName, bytes);\n } else {\n const fs = await import(\"node:fs/promises\");\n await fs.writeFile(fileName, bytes);\n }\n return fileName;\n },\n };\n}\n"],"mappings":";;AA0CA,SAAS,cAAc,OAAgC;CACrD,OAAO,MAAM,OAAO,MAClB,MAAM,YACN,MAAM,aAAa,MAAM,UAC3B;AACF;AAEA,SAAS,eAAe,OAA2B;CACjD,IAAI,SAAS;CACb,KAAK,MAAM,QAAQ,OAAO,UAAU,OAAO,aAAa,IAAI;CAC5D,OAAO;AACT;AAEA,SAAS,SAAS,OAA2B;CAC3C,IAAI,OAAO,WAAW,aACpB,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,QAAQ;CAC7C,OAAO,KAAK,eAAe,KAAK,CAAC;AACnC;AAEA,SAAS,kBAAkB,UAA0B;CACnD,OAAO,SAAS,YAAY,CAAC,CAAC,SAAS,OAAO,IAC1C,WACA,GAAG,SAAS;AAClB;AAEA,SAAS,kBAAkB,UAAkB,OAAyB;CACpE,MAAM,OAAO,IAAI,KAAK,CAAC,cAAc,KAAK,CAAC,GAAG,EAC5C,MAAM,4EACR,CAAC;CACD,MAAM,MAAM,IAAI,gBAAgB,IAAI;CACpC,IAAI;CACJ,MAAM,gBAAgB;EACpB,IAAI;GACF,QAAQ,OAAO;EACjB,UAAU;GACR,IAAI,gBAAgB,GAAG;EACzB;CACF;CACA,IAAI,mBAAmB;CACvB,IAAI;EACF,SAAS,SAAS,cAAc,GAAG;EACnC,OAAO,OAAO;EACd,OAAO,WAAW;EAClB,SAAS,KAAK,OAAO,MAAM;EAC3B,OAAO,MAAM;EACb,WAAW,SAAS,CAAC;EACrB,mBAAmB;CACrB,UAAU;EACR,IAAI,CAAC,kBAAkB,QAAQ;CACjC;AACF;AAEA,SAAgB,mBACd,WACc;CACd,SAAS,MAAM,SAA8C;EAC3D,OAAO,QAAQ,QAAQ,CAAC,CAAC,WAAW;GAClC,MAAM,QAAQ,UAAU,UAAU,CAAC;GACnC,QAAQ,SAAS,YAAjB;IACE,KAAK,eACH,OAAO,cAAc,KAAK;IAC5B,KAAK,UACH,OAAO,SAAS,KAAK;IACvB,KAAK,gBACH,OAAO,eAAe,KAAK;IAC7B,KAAK,cACH,OAAO,OAAO,KAAK,KAAK;IAC1B,KAAK,cACH,OAAO;IACT,KAAK;IACL,KAAK,KAAA,GACH,OAAO,IAAI,KAAK,CAAC,cAAc,KAAK,CAAC,GAAG,EACtC,MAAM,4EACR,CAAC;GACL;EACF,CAAC;CACH;CAEA,OAAO;EACE;EACP,SAAS;GACP,OAAO,QAAQ,QAAQ,CAAC,CAAC,WAAW,UAAU,UAAU,CAAC,CAAC;EAC5D;EACA,MAAM,UAAU,SAAS;GACvB,MAAM,WAAW,kBACf,OAAO,YAAY,WACf,UACC,SAAS,YAAY,mBAC5B;GACA,MAAM,QAAQ,UAAU,UAAU,CAAC;GACnC,IAAI,OAAO,aAAa,aACtB,kBAAkB,UAAU,KAAK;QAGjC,OAAM,MADW,OAAO,oBAAA,CACf,UAAU,UAAU,KAAK;GAEpC,OAAO;EACT;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"measureImage.js","names":[],"sources":["../../src/shared/measureImage.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport { imageSize } from \"image-size\";\nimport type { DiagnosticCollector } from \"../diagnostics.ts\";\n\ntype ImageSizeCache = Map<string, { widthPx: number; heightPx: number }>;\ntype ImageDataCache = Map<string, string>;\n\n/**\n * キャッシュされた画像データ(Base64)を取得する\n * @param src 画像のパス\n * @param cache 画像データキャッシュ\n * @returns Base64形式の画像データ、またはキャッシュがない場合はundefined\n */\nexport function getImageData(\n src: string,\n cache: ImageDataCache,\n): string | undefined {\n return cache.get(src);\n}\n\n/**\n * 画像サイズを事前取得してキャッシュする(非同期)\n * HTTPS URLの画像を処理する際に使用\n * @param src 画像のパス(ローカルパス、base64データ、またはHTTPS URL)\n * @param sizeCache 画像サイズキャッシュ\n * @param dataCache 画像データキャッシュ\n * @returns 画像の幅と高さ(px)\n */\nexport async function prefetchImageSize(\n src: string,\n sizeCache: ImageSizeCache,\n dataCache: ImageDataCache,\n diagnostics: DiagnosticCollector,\n): Promise<{\n widthPx: number;\n heightPx: number;\n}> {\n // キャッシュにあればそれを返す\n const cached = sizeCache.get(src);\n if (cached) {\n return cached;\n }\n\n try {\n let buffer: Uint8Array;\n\n // base64データの場合\n if (src.startsWith(\"data:\")) {\n const base64Data = src.split(\",\")[1];\n buffer = new Uint8Array(Buffer.from(base64Data, \"base64\"));\n }\n // HTTPS/HTTP URLの場合\n else if (src.startsWith(\"https://\") || src.startsWith(\"http://\")) {\n const response = await fetch(src);\n if (!response.ok) {\n throw new Error(`Failed to fetch image: ${response.status}`);\n }\n const arrayBuffer = await response.arrayBuffer();\n buffer = new Uint8Array(arrayBuffer);\n\n // 画像データをBase64形式でキャッシュ(pptxgenjs用)\n const contentType = response.headers.get(\"content-type\") || \"image/png\";\n const base64 = Buffer.from(arrayBuffer).toString(\"base64\");\n dataCache.set(src, `${contentType};base64,${base64}`);\n }\n // ローカルファイルパスの場合\n else {\n buffer = new Uint8Array(fs.readFileSync(src));\n }\n\n const dimensions = imageSize(buffer);\n\n const width = dimensions.width ?? 100; // デフォルト100px\n const height = dimensions.height ?? 100; // デフォルト100px\n\n const result = {\n widthPx: width,\n heightPx: height,\n };\n\n // キャッシュに保存\n sizeCache.set(src, result);\n\n return result;\n } catch (error) {\n // エラーが発生した場合はデフォルトサイズを返す\n diagnostics.add(\n \"IMAGE_MEASURE_FAILED\",\n `Failed to measure image size for ${src}: ${String(error)}`,\n );\n const result = {\n widthPx: 100,\n heightPx: 100,\n };\n sizeCache.set(src, result);\n return result;\n }\n}\n\n/**\n * 画像ファイルのサイズを取得する(同期)\n * 事前にprefetchImageSizeでキャッシュしておくこと\n * @param src 画像のパス(ローカルパス、base64データ、またはHTTPS URL)\n * @param sizeCache 画像サイズキャッシュ\n * @returns 画像の幅と高さ(px)\n */\nexport function measureImage(\n src: string,\n sizeCache: ImageSizeCache,\n diagnostics: DiagnosticCollector,\n): {\n widthPx: number;\n heightPx: number;\n} {\n // キャッシュにあればそれを返す\n const cached = sizeCache.get(src);\n if (cached) {\n return cached;\n }\n\n // キャッシュにない場合(ローカルファイルやbase64のみ同期処理可能)\n try {\n let buffer: Uint8Array;\n\n // base64データの場合\n if (src.startsWith(\"data:\")) {\n const base64Data = src.split(\",\")[1];\n buffer = new Uint8Array(Buffer.from(base64Data, \"base64\"));\n }\n // HTTPS/HTTP URLの場合はキャッシュがないとデフォルト値を返す\n else if (src.startsWith(\"https://\") || src.startsWith(\"http://\")) {\n diagnostics.add(\n \"IMAGE_NOT_PREFETCHED\",\n `Image size for URL ${src} was not prefetched. Using default size.`,\n );\n return {\n widthPx: 100,\n heightPx: 100,\n };\n }\n // ローカルファイルパスの場合\n else {\n buffer = new Uint8Array(fs.readFileSync(src));\n }\n\n const dimensions = imageSize(buffer);\n\n const width = dimensions.width ?? 100; // デフォルト100px\n const height = dimensions.height ?? 100; // デフォルト100px\n\n const result = {\n widthPx: width,\n heightPx: height,\n };\n\n // キャッシュに保存\n sizeCache.set(src, result);\n\n return result;\n } catch (error) {\n // エラーが発生した場合はデフォルトサイズを返す\n diagnostics.add(\n \"IMAGE_MEASURE_FAILED\",\n `Failed to measure image size for ${src}: ${String(error)}`,\n );\n return {\n widthPx: 100,\n heightPx: 100,\n };\n }\n}\n"],"mappings":";;;;;;;;;AAaA,SAAgB,aACd,KACA,OACoB;CACpB,OAAO,MAAM,IAAI,GAAG;AACtB;;;;;;;;;AAUA,eAAsB,kBACpB,KACA,WACA,WACA,aAIC;CAED,MAAM,SAAS,UAAU,IAAI,GAAG;CAChC,IAAI,QACF,OAAO;CAGT,IAAI;EACF,IAAI;EAGJ,IAAI,IAAI,WAAW,OAAO,GAAG;GAC3B,MAAM,aAAa,IAAI,MAAM,GAAG,CAAC,CAAC;GAClC,SAAS,IAAI,WAAW,OAAO,KAAK,YAAY,QAAQ,CAAC;EAC3D,OAEK,IAAI,IAAI,WAAW,UAAU,KAAK,IAAI,WAAW,SAAS,GAAG;GAChE,MAAM,WAAW,MAAM,MAAM,GAAG;GAChC,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,0BAA0B,SAAS,QAAQ;GAE7D,MAAM,cAAc,MAAM,SAAS,YAAY;GAC/C,SAAS,IAAI,WAAW,WAAW;GAGnC,MAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;GAC5D,MAAM,SAAS,OAAO,KAAK,WAAW,CAAC,CAAC,SAAS,QAAQ;GACzD,UAAU,IAAI,KAAK,GAAG,YAAY,UAAU,QAAQ;EACtD,OAGE,SAAS,IAAI,WAAW,GAAG,aAAa,GAAG,CAAC;EAG9C,MAAM,aAAa,UAAU,MAAM;EAKnC,MAAM,SAAS;GACb,SAJY,WAAW,SAAS;GAKhC,UAJa,WAAW,UAAU;EAKpC;EAGA,UAAU,IAAI,KAAK,MAAM;EAEzB,OAAO;CACT,SAAS,OAAO;EAEd,YAAY,IACV,wBACA,oCAAoC,IAAI,IAAI,OAAO,KAAK,GAC1D;EACA,MAAM,SAAS;GACb,SAAS;GACT,UAAU;EACZ;EACA,UAAU,IAAI,KAAK,MAAM;EACzB,OAAO;CACT;AACF;;;;;;;;AASA,SAAgB,aACd,KACA,WACA,aAIA;CAEA,MAAM,SAAS,UAAU,IAAI,GAAG;CAChC,IAAI,QACF,OAAO;CAIT,IAAI;EACF,IAAI;EAGJ,IAAI,IAAI,WAAW,OAAO,GAAG;GAC3B,MAAM,aAAa,IAAI,MAAM,GAAG,CAAC,CAAC;GAClC,SAAS,IAAI,WAAW,OAAO,KAAK,YAAY,QAAQ,CAAC;EAC3D,OAEK,IAAI,IAAI,WAAW,UAAU,KAAK,IAAI,WAAW,SAAS,GAAG;GAChE,YAAY,IACV,wBACA,sBAAsB,IAAI,yCAC5B;GACA,OAAO;IACL,SAAS;IACT,UAAU;GACZ;EACF,OAGE,SAAS,IAAI,WAAW,GAAG,aAAa,GAAG,CAAC;EAG9C,MAAM,aAAa,UAAU,MAAM;EAKnC,MAAM,SAAS;GACb,SAJY,WAAW,SAAS;GAKhC,UAJa,WAAW,UAAU;EAKpC;EAGA,UAAU,IAAI,KAAK,MAAM;EAEzB,OAAO;CACT,SAAS,OAAO;EAEd,YAAY,IACV,wBACA,oCAAoC,IAAI,IAAI,OAAO,KAAK,GAC1D;EACA,OAAO;GACL,SAAS;GACT,UAAU;EACZ;CACF;AACF"}
1
+ {"version":3,"file":"measureImage.js","names":[],"sources":["../../src/shared/measureImage.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport { imageSize } from \"image-size\";\nimport type { DiagnosticCollector } from \"../diagnostics.ts\";\n\ntype ImageSizeCache = Map<string, { widthPx: number; heightPx: number }>;\ntype ImageDataCache = Map<string, string>;\n\n/**\n * キャッシュされた画像データ(Base64)を取得する\n * @param src 画像のパス\n * @param cache 画像データキャッシュ\n * @returns Base64形式の画像データ、またはキャッシュがない場合はundefined\n */\nexport function getImageData(\n src: string,\n cache: ImageDataCache,\n): string | undefined {\n return cache.get(src);\n}\n\n/**\n * 画像サイズを事前取得してキャッシュする(非同期)\n * HTTPS URLの画像を処理する際に使用\n * @param src 画像のパス(ローカルパス、base64データ、またはHTTPS URL)\n * @param sizeCache 画像サイズキャッシュ\n * @param dataCache 画像データキャッシュ\n * @returns 画像の幅と高さ(px)\n */\nexport async function prefetchImageSize(\n src: string,\n sizeCache: ImageSizeCache,\n dataCache: ImageDataCache,\n diagnostics: DiagnosticCollector,\n): Promise<{\n widthPx: number;\n heightPx: number;\n}> {\n // キャッシュにあればそれを返す\n const cached = sizeCache.get(src);\n if (cached) {\n return cached;\n }\n\n try {\n let buffer: Uint8Array;\n\n // base64データの場合\n if (src.startsWith(\"data:\")) {\n const base64Data = src.split(\",\")[1];\n buffer = new Uint8Array(Buffer.from(base64Data, \"base64\"));\n }\n // HTTPS/HTTP URLの場合\n else if (src.startsWith(\"https://\") || src.startsWith(\"http://\")) {\n const response = await fetch(src);\n if (!response.ok) {\n throw new Error(`Failed to fetch image: ${response.status}`);\n }\n const arrayBuffer = await response.arrayBuffer();\n buffer = new Uint8Array(arrayBuffer);\n\n // 画像データを Base64 形式でキャッシュ(PPTX authoring 用)\n const contentType = response.headers.get(\"content-type\") || \"image/png\";\n const base64 = Buffer.from(arrayBuffer).toString(\"base64\");\n dataCache.set(src, `${contentType};base64,${base64}`);\n }\n // ローカルファイルパスの場合\n else {\n buffer = new Uint8Array(fs.readFileSync(src));\n }\n\n const dimensions = imageSize(buffer);\n\n const width = dimensions.width ?? 100; // デフォルト100px\n const height = dimensions.height ?? 100; // デフォルト100px\n\n const result = {\n widthPx: width,\n heightPx: height,\n };\n\n // キャッシュに保存\n sizeCache.set(src, result);\n\n return result;\n } catch (error) {\n // エラーが発生した場合はデフォルトサイズを返す\n diagnostics.add(\n \"IMAGE_MEASURE_FAILED\",\n `Failed to measure image size for ${src}: ${String(error)}`,\n );\n const result = {\n widthPx: 100,\n heightPx: 100,\n };\n sizeCache.set(src, result);\n return result;\n }\n}\n\n/**\n * 画像ファイルのサイズを取得する(同期)\n * 事前にprefetchImageSizeでキャッシュしておくこと\n * @param src 画像のパス(ローカルパス、base64データ、またはHTTPS URL)\n * @param sizeCache 画像サイズキャッシュ\n * @returns 画像の幅と高さ(px)\n */\nexport function measureImage(\n src: string,\n sizeCache: ImageSizeCache,\n diagnostics: DiagnosticCollector,\n): {\n widthPx: number;\n heightPx: number;\n} {\n // キャッシュにあればそれを返す\n const cached = sizeCache.get(src);\n if (cached) {\n return cached;\n }\n\n // キャッシュにない場合(ローカルファイルやbase64のみ同期処理可能)\n try {\n let buffer: Uint8Array;\n\n // base64データの場合\n if (src.startsWith(\"data:\")) {\n const base64Data = src.split(\",\")[1];\n buffer = new Uint8Array(Buffer.from(base64Data, \"base64\"));\n }\n // HTTPS/HTTP URLの場合はキャッシュがないとデフォルト値を返す\n else if (src.startsWith(\"https://\") || src.startsWith(\"http://\")) {\n diagnostics.add(\n \"IMAGE_NOT_PREFETCHED\",\n `Image size for URL ${src} was not prefetched. Using default size.`,\n );\n return {\n widthPx: 100,\n heightPx: 100,\n };\n }\n // ローカルファイルパスの場合\n else {\n buffer = new Uint8Array(fs.readFileSync(src));\n }\n\n const dimensions = imageSize(buffer);\n\n const width = dimensions.width ?? 100; // デフォルト100px\n const height = dimensions.height ?? 100; // デフォルト100px\n\n const result = {\n widthPx: width,\n heightPx: height,\n };\n\n // キャッシュに保存\n sizeCache.set(src, result);\n\n return result;\n } catch (error) {\n // エラーが発生した場合はデフォルトサイズを返す\n diagnostics.add(\n \"IMAGE_MEASURE_FAILED\",\n `Failed to measure image size for ${src}: ${String(error)}`,\n );\n return {\n widthPx: 100,\n heightPx: 100,\n };\n }\n}\n"],"mappings":";;;;;;;;;AAaA,SAAgB,aACd,KACA,OACoB;CACpB,OAAO,MAAM,IAAI,GAAG;AACtB;;;;;;;;;AAUA,eAAsB,kBACpB,KACA,WACA,WACA,aAIC;CAED,MAAM,SAAS,UAAU,IAAI,GAAG;CAChC,IAAI,QACF,OAAO;CAGT,IAAI;EACF,IAAI;EAGJ,IAAI,IAAI,WAAW,OAAO,GAAG;GAC3B,MAAM,aAAa,IAAI,MAAM,GAAG,CAAC,CAAC;GAClC,SAAS,IAAI,WAAW,OAAO,KAAK,YAAY,QAAQ,CAAC;EAC3D,OAEK,IAAI,IAAI,WAAW,UAAU,KAAK,IAAI,WAAW,SAAS,GAAG;GAChE,MAAM,WAAW,MAAM,MAAM,GAAG;GAChC,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,0BAA0B,SAAS,QAAQ;GAE7D,MAAM,cAAc,MAAM,SAAS,YAAY;GAC/C,SAAS,IAAI,WAAW,WAAW;GAGnC,MAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;GAC5D,MAAM,SAAS,OAAO,KAAK,WAAW,CAAC,CAAC,SAAS,QAAQ;GACzD,UAAU,IAAI,KAAK,GAAG,YAAY,UAAU,QAAQ;EACtD,OAGE,SAAS,IAAI,WAAW,GAAG,aAAa,GAAG,CAAC;EAG9C,MAAM,aAAa,UAAU,MAAM;EAKnC,MAAM,SAAS;GACb,SAJY,WAAW,SAAS;GAKhC,UAJa,WAAW,UAAU;EAKpC;EAGA,UAAU,IAAI,KAAK,MAAM;EAEzB,OAAO;CACT,SAAS,OAAO;EAEd,YAAY,IACV,wBACA,oCAAoC,IAAI,IAAI,OAAO,KAAK,GAC1D;EACA,MAAM,SAAS;GACb,SAAS;GACT,UAAU;EACZ;EACA,UAAU,IAAI,KAAK,MAAM;EACzB,OAAO;CACT;AACF;;;;;;;;AASA,SAAgB,aACd,KACA,WACA,aAIA;CAEA,MAAM,SAAS,UAAU,IAAI,GAAG;CAChC,IAAI,QACF,OAAO;CAIT,IAAI;EACF,IAAI;EAGJ,IAAI,IAAI,WAAW,OAAO,GAAG;GAC3B,MAAM,aAAa,IAAI,MAAM,GAAG,CAAC,CAAC;GAClC,SAAS,IAAI,WAAW,OAAO,KAAK,YAAY,QAAQ,CAAC;EAC3D,OAEK,IAAI,IAAI,WAAW,UAAU,KAAK,IAAI,WAAW,SAAS,GAAG;GAChE,YAAY,IACV,wBACA,sBAAsB,IAAI,yCAC5B;GACA,OAAO;IACL,SAAS;IACT,UAAU;GACZ;EACF,OAGE,SAAS,IAAI,WAAW,GAAG,aAAa,GAAG,CAAC;EAG9C,MAAM,aAAa,UAAU,MAAM;EAKnC,MAAM,SAAS;GACb,SAJY,WAAW,SAAS;GAKhC,UAJa,WAAW,UAAU;EAKpC;EAGA,UAAU,IAAI,KAAK,MAAM;EAEzB,OAAO;CACT,SAAS,OAAO;EAEd,YAAY,IACV,wBACA,oCAAoC,IAAI,IAAI,OAAO,KAAK,GAC1D;EACA,OAAO;GACL,SAAS;GACT,UAAU;EACZ;CACF;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hirokisakabe/pom",
3
- "version": "9.1.2",
3
+ "version": "10.0.0",
4
4
  "description": "AI-friendly PowerPoint generation with a Flexbox layout engine.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -50,7 +50,6 @@
50
50
  },
51
51
  "devDependencies": {
52
52
  "@size-limit/file": "^12.1.0",
53
- "@types/node": "^26.1.0",
54
53
  "@types/opentype.js": "^1.3.10",
55
54
  "@types/pngjs": "6.0.5",
56
55
  "@vitest/coverage-v8": "^4.1.10",
@@ -64,13 +63,13 @@
64
63
  "tsx": "4.23.0"
65
64
  },
66
65
  "dependencies": {
67
- "@pptx-glimpse/document": "0.6.0",
66
+ "@pptx-glimpse/document": "0.9.1",
68
67
  "@resvg/resvg-wasm": "^2.6.2",
69
- "fast-xml-parser": "^5.9.3",
68
+ "@types/node": "^26.1.0",
69
+ "fast-xml-parser": "^5.10.0",
70
70
  "image-size": "2.0.2",
71
71
  "jszip": "^3.10.1",
72
72
  "opentype.js": "^2.0.0",
73
- "pptxgenjs": "4.0.1",
74
73
  "yoga-layout": "3.2.1",
75
74
  "zod": "^4.4.3"
76
75
  },