pptx-glimpse 0.6.1 → 0.7.1

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/index.cjs CHANGED
@@ -29,7 +29,8 @@ __export(index_exports, {
29
29
  createOpentypeTextMeasurerFromBuffers: () => createOpentypeTextMeasurerFromBuffers,
30
30
  getMappedFont: () => getMappedFont,
31
31
  getWarningEntries: () => getWarningEntries,
32
- getWarningSummary: () => getWarningSummary
32
+ getWarningSummary: () => getWarningSummary,
33
+ initResvgWasm: () => initResvgWasm
33
34
  });
34
35
  module.exports = __toCommonJS(index_exports);
35
36
 
@@ -42,15 +43,18 @@ var DEFAULT_FONT_MAPPING = {
42
43
  "Times New Roman": "Tinos",
43
44
  "Courier New": "Cousine",
44
45
  Cambria: "Caladea",
45
- // 日本語ゴシック系 → Noto Sans CJK JP
46
- \u30E1\u30A4\u30EA\u30AA: "Noto Sans CJK JP",
47
- Meiryo: "Noto Sans CJK JP",
48
- \u6E38\u30B4\u30B7\u30C3\u30AF: "Noto Sans CJK JP",
49
- "Yu Gothic": "Noto Sans CJK JP",
50
- "MS \u30B4\u30B7\u30C3\u30AF": "Noto Sans CJK JP",
51
- "MS Gothic": "Noto Sans CJK JP",
52
- "MS P\u30B4\u30B7\u30C3\u30AF": "Noto Sans CJK JP",
53
- "MS PGothic": "Noto Sans CJK JP",
46
+ // 日本語ゴシック系 → Noto Sans JP
47
+ // "Noto Sans CJK JP" ではなく "Noto Sans JP" を使用する。
48
+ // NotoSansCJK TTC は最初の1フォントのみ抽出するため JP バリアントが取れるとは限らず、
49
+ // Docker 環境でダウンロードする standalone NotoSansJP.ttf のフォント名に合わせている。
50
+ \u30E1\u30A4\u30EA\u30AA: "Noto Sans JP",
51
+ Meiryo: "Noto Sans JP",
52
+ \u6E38\u30B4\u30B7\u30C3\u30AF: "Noto Sans JP",
53
+ "Yu Gothic": "Noto Sans JP",
54
+ "MS \u30B4\u30B7\u30C3\u30AF": "Noto Sans JP",
55
+ "MS Gothic": "Noto Sans JP",
56
+ "MS P\u30B4\u30B7\u30C3\u30AF": "Noto Sans JP",
57
+ "MS PGothic": "Noto Sans JP",
54
58
  // 日本語明朝系 → Noto Serif CJK JP
55
59
  "MS \u660E\u671D": "Noto Serif CJK JP",
56
60
  "MS Mincho": "Noto Serif CJK JP",
@@ -1054,19 +1058,22 @@ var OpentypeTextMeasurer = class {
1054
1058
  this.defaultFont = defaultFont ?? null;
1055
1059
  }
1056
1060
  measureTextWidth(text, fontSizePt, bold, fontFamily, fontFamilyEa) {
1057
- const font = this.resolveFont(fontFamily) ?? this.resolveFont(fontFamilyEa) ?? this.defaultFont;
1058
- if (!font) {
1061
+ const latinFont = this.resolveFont(fontFamily);
1062
+ const eaFont = this.resolveFont(fontFamilyEa);
1063
+ const fallbackFont = latinFont ?? eaFont ?? this.defaultFont;
1064
+ if (!fallbackFont) {
1059
1065
  return measureTextWidth(text, fontSizePt, bold, fontFamily, fontFamilyEa);
1060
1066
  }
1061
1067
  const fontSizePx = fontSizePt * PX_PER_PT2;
1062
- const scale = fontSizePx / font.unitsPerEm;
1063
1068
  let totalWidth = 0;
1064
- const chars = [...text];
1065
- const glyphs = font.stringToGlyphs(text);
1066
- for (let i = 0; i < glyphs.length; i++) {
1067
- let charWidth = (glyphs[i].advanceWidth ?? font.unitsPerEm * 0.6) * scale;
1068
- const codePoint = chars[i]?.codePointAt(0);
1069
- if (bold && (codePoint === void 0 || !isCjkCodePoint(codePoint))) {
1069
+ for (const char of text) {
1070
+ const codePoint = char.codePointAt(0);
1071
+ const isEa = isCjkCodePoint(codePoint);
1072
+ const font = isEa ? eaFont ?? fallbackFont : latinFont ?? fallbackFont;
1073
+ const scale = fontSizePx / font.unitsPerEm;
1074
+ const glyphs = font.stringToGlyphs(char);
1075
+ let charWidth = (glyphs[0]?.advanceWidth ?? font.unitsPerEm * 0.6) * scale;
1076
+ if (bold && !isEa) {
1070
1077
  charWidth *= BOLD_FACTOR2;
1071
1078
  }
1072
1079
  totalWidth += charWidth;
@@ -1085,7 +1092,14 @@ var OpentypeTextMeasurer = class {
1085
1092
  }
1086
1093
  resolveFont(name) {
1087
1094
  if (!name) return null;
1088
- return this.fonts.get(name) ?? null;
1095
+ const direct = this.fonts.get(name);
1096
+ if (direct) return direct;
1097
+ const mapped = getCurrentMappedFont(name);
1098
+ if (mapped) {
1099
+ const mappedFont = this.fonts.get(mapped);
1100
+ if (mappedFont) return mappedFont;
1101
+ }
1102
+ return null;
1089
1103
  }
1090
1104
  };
1091
1105
 
@@ -1570,15 +1584,36 @@ function parseXmlOrdered(xml) {
1570
1584
  }
1571
1585
 
1572
1586
  // src/png/png-converter.ts
1573
- var import_resvg_js = require("@resvg/resvg-js");
1587
+ var import_resvg_wasm = require("@resvg/resvg-wasm");
1588
+ var import_promises2 = require("fs/promises");
1589
+ var import_module = require("module");
1590
+ var import_meta = {};
1591
+ var wasmInitPromise = null;
1592
+ function resolveWasmPath() {
1593
+ const baseUrl = import_meta.url || `file://${__filename}`;
1594
+ const require2 = (0, import_module.createRequire)(baseUrl);
1595
+ return require2.resolve("@resvg/resvg-wasm/index_bg.wasm");
1596
+ }
1597
+ async function initResvgWasm() {
1598
+ if (!wasmInitPromise) {
1599
+ wasmInitPromise = (async () => {
1600
+ const wasmPath = resolveWasmPath();
1601
+ const wasmBuffer = await (0, import_promises2.readFile)(wasmPath);
1602
+ await (0, import_resvg_wasm.initWasm)(wasmBuffer);
1603
+ })();
1604
+ }
1605
+ await wasmInitPromise;
1606
+ }
1574
1607
  async function svgToPng(svgString, options) {
1608
+ await initResvgWasm();
1575
1609
  const resvgOptions = {};
1576
1610
  if (options?.width) {
1577
1611
  resvgOptions.fitTo = { mode: "width", value: options.width };
1578
1612
  } else if (options?.height) {
1579
1613
  resvgOptions.fitTo = { mode: "height", value: options.height };
1580
1614
  }
1581
- const rendered = await (0, import_resvg_js.renderAsync)(svgString, resvgOptions);
1615
+ const resvg = new import_resvg_wasm.Resvg(svgString, resvgOptions);
1616
+ const rendered = resvg.render();
1582
1617
  return {
1583
1618
  png: Buffer.from(rendered.asPng()),
1584
1619
  width: rendered.width,
@@ -3895,7 +3930,7 @@ function parseParagraph(p, colorResolver, rels, fontScheme, lstStyle, orderedPCh
3895
3930
  const lnSpcSpcPct = lnSpc?.spcPct;
3896
3931
  const tabStops = parseTabStops(pPr);
3897
3932
  const properties = {
3898
- alignment: pPr?.["@_algn"] ?? lstLevelProps?.alignment ?? "l",
3933
+ alignment: pPr?.["@_algn"] ?? lstLevelProps?.alignment ?? null,
3899
3934
  lineSpacing: lnSpcSpcPct ? Number(lnSpcSpcPct["@_val"]) : null,
3900
3935
  spaceBefore: parseSpacing(pPr?.spcBef),
3901
3936
  spaceAfter: parseSpacing(pPr?.spcAft),
@@ -4579,6 +4614,19 @@ function resolveShapeTextInheritance(shape, context) {
4579
4614
  const chainSources = [layoutLstStyle, masterLstStyle, txStyle, context.defaultTextStyle];
4580
4615
  for (const paragraph of shape.textBody.paragraphs) {
4581
4616
  const level = paragraph.properties.level;
4617
+ if (paragraph.properties.alignment === null) {
4618
+ for (const source of chainSources) {
4619
+ if (!source) continue;
4620
+ const alignment = source.levels[level]?.alignment ?? source.defaultParagraph?.alignment;
4621
+ if (alignment) {
4622
+ paragraph.properties.alignment = alignment;
4623
+ break;
4624
+ }
4625
+ }
4626
+ if (paragraph.properties.alignment === null) {
4627
+ paragraph.properties.alignment = "l";
4628
+ }
4629
+ }
4582
4630
  for (const run of paragraph.runs) {
4583
4631
  const props = run.properties;
4584
4632
  for (const source of chainSources) {
@@ -8180,8 +8228,8 @@ function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, font
8180
8228
  segText,
8181
8229
  fontSize,
8182
8230
  props.bold,
8183
- fontFamily,
8184
- fontFamilyEa
8231
+ props.fontFamily,
8232
+ props.fontFamilyEa
8185
8233
  );
8186
8234
  if (font) {
8187
8235
  const path = font.getPath(segText, x + totalWidth, effectiveY, fontSizePx);
@@ -8205,8 +8253,8 @@ function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, font
8205
8253
  char,
8206
8254
  fontSize,
8207
8255
  props.bold,
8208
- fontFamily,
8209
- fontFamilyEa
8256
+ props.fontFamily,
8257
+ props.fontFamilyEa
8210
8258
  );
8211
8259
  if (font) {
8212
8260
  const charX = x + totalWidth;
@@ -8892,5 +8940,6 @@ function collectFontsFromTextBody(textBody, fonts) {
8892
8940
  createOpentypeTextMeasurerFromBuffers,
8893
8941
  getMappedFont,
8894
8942
  getWarningEntries,
8895
- getWarningSummary
8943
+ getWarningSummary,
8944
+ initResvgWasm
8896
8945
  });
package/dist/index.d.cts CHANGED
@@ -177,4 +177,11 @@ interface OpentypeSetup {
177
177
  */
178
178
  declare function createOpentypeSetupFromBuffers(fontBuffers: FontBuffer[], fontMapping?: FontMapping): Promise<OpentypeSetup | null>;
179
179
 
180
- export { type ConvertOptions, DEFAULT_FONT_MAPPING, type FontBuffer, type FontMapping, type LogLevel, type OpentypeSetup, type SlideImage, type SlideSvg, type UsedFonts, type WarningEntry, type WarningSummary, collectUsedFonts, convertPptxToPng, convertPptxToSvg, createFontMapping, createOpentypeSetupFromBuffers, createOpentypeTextMeasurerFromBuffers, getMappedFont, getWarningEntries, getWarningSummary };
180
+ /**
181
+ * resvg-wasm の WASM モジュールを初期化する。
182
+ * 明示的に呼び出さなくても、初回の PNG 変換時に自動的に初期化される。
183
+ * アプリケーション起動時に初期化しておきたい場合に使用する。
184
+ */
185
+ declare function initResvgWasm(): Promise<void>;
186
+
187
+ export { type ConvertOptions, DEFAULT_FONT_MAPPING, type FontBuffer, type FontMapping, type LogLevel, type OpentypeSetup, type SlideImage, type SlideSvg, type UsedFonts, type WarningEntry, type WarningSummary, collectUsedFonts, convertPptxToPng, convertPptxToSvg, createFontMapping, createOpentypeSetupFromBuffers, createOpentypeTextMeasurerFromBuffers, getMappedFont, getWarningEntries, getWarningSummary, initResvgWasm };
package/dist/index.d.ts CHANGED
@@ -177,4 +177,11 @@ interface OpentypeSetup {
177
177
  */
178
178
  declare function createOpentypeSetupFromBuffers(fontBuffers: FontBuffer[], fontMapping?: FontMapping): Promise<OpentypeSetup | null>;
179
179
 
180
- export { type ConvertOptions, DEFAULT_FONT_MAPPING, type FontBuffer, type FontMapping, type LogLevel, type OpentypeSetup, type SlideImage, type SlideSvg, type UsedFonts, type WarningEntry, type WarningSummary, collectUsedFonts, convertPptxToPng, convertPptxToSvg, createFontMapping, createOpentypeSetupFromBuffers, createOpentypeTextMeasurerFromBuffers, getMappedFont, getWarningEntries, getWarningSummary };
180
+ /**
181
+ * resvg-wasm の WASM モジュールを初期化する。
182
+ * 明示的に呼び出さなくても、初回の PNG 変換時に自動的に初期化される。
183
+ * アプリケーション起動時に初期化しておきたい場合に使用する。
184
+ */
185
+ declare function initResvgWasm(): Promise<void>;
186
+
187
+ export { type ConvertOptions, DEFAULT_FONT_MAPPING, type FontBuffer, type FontMapping, type LogLevel, type OpentypeSetup, type SlideImage, type SlideSvg, type UsedFonts, type WarningEntry, type WarningSummary, collectUsedFonts, convertPptxToPng, convertPptxToSvg, createFontMapping, createOpentypeSetupFromBuffers, createOpentypeTextMeasurerFromBuffers, getMappedFont, getWarningEntries, getWarningSummary, initResvgWasm };
package/dist/index.js CHANGED
@@ -7,15 +7,18 @@ var DEFAULT_FONT_MAPPING = {
7
7
  "Times New Roman": "Tinos",
8
8
  "Courier New": "Cousine",
9
9
  Cambria: "Caladea",
10
- // 日本語ゴシック系 → Noto Sans CJK JP
11
- \u30E1\u30A4\u30EA\u30AA: "Noto Sans CJK JP",
12
- Meiryo: "Noto Sans CJK JP",
13
- \u6E38\u30B4\u30B7\u30C3\u30AF: "Noto Sans CJK JP",
14
- "Yu Gothic": "Noto Sans CJK JP",
15
- "MS \u30B4\u30B7\u30C3\u30AF": "Noto Sans CJK JP",
16
- "MS Gothic": "Noto Sans CJK JP",
17
- "MS P\u30B4\u30B7\u30C3\u30AF": "Noto Sans CJK JP",
18
- "MS PGothic": "Noto Sans CJK JP",
10
+ // 日本語ゴシック系 → Noto Sans JP
11
+ // "Noto Sans CJK JP" ではなく "Noto Sans JP" を使用する。
12
+ // NotoSansCJK TTC は最初の1フォントのみ抽出するため JP バリアントが取れるとは限らず、
13
+ // Docker 環境でダウンロードする standalone NotoSansJP.ttf のフォント名に合わせている。
14
+ \u30E1\u30A4\u30EA\u30AA: "Noto Sans JP",
15
+ Meiryo: "Noto Sans JP",
16
+ \u6E38\u30B4\u30B7\u30C3\u30AF: "Noto Sans JP",
17
+ "Yu Gothic": "Noto Sans JP",
18
+ "MS \u30B4\u30B7\u30C3\u30AF": "Noto Sans JP",
19
+ "MS Gothic": "Noto Sans JP",
20
+ "MS P\u30B4\u30B7\u30C3\u30AF": "Noto Sans JP",
21
+ "MS PGothic": "Noto Sans JP",
19
22
  // 日本語明朝系 → Noto Serif CJK JP
20
23
  "MS \u660E\u671D": "Noto Serif CJK JP",
21
24
  "MS Mincho": "Noto Serif CJK JP",
@@ -1019,19 +1022,22 @@ var OpentypeTextMeasurer = class {
1019
1022
  this.defaultFont = defaultFont ?? null;
1020
1023
  }
1021
1024
  measureTextWidth(text, fontSizePt, bold, fontFamily, fontFamilyEa) {
1022
- const font = this.resolveFont(fontFamily) ?? this.resolveFont(fontFamilyEa) ?? this.defaultFont;
1023
- if (!font) {
1025
+ const latinFont = this.resolveFont(fontFamily);
1026
+ const eaFont = this.resolveFont(fontFamilyEa);
1027
+ const fallbackFont = latinFont ?? eaFont ?? this.defaultFont;
1028
+ if (!fallbackFont) {
1024
1029
  return measureTextWidth(text, fontSizePt, bold, fontFamily, fontFamilyEa);
1025
1030
  }
1026
1031
  const fontSizePx = fontSizePt * PX_PER_PT2;
1027
- const scale = fontSizePx / font.unitsPerEm;
1028
1032
  let totalWidth = 0;
1029
- const chars = [...text];
1030
- const glyphs = font.stringToGlyphs(text);
1031
- for (let i = 0; i < glyphs.length; i++) {
1032
- let charWidth = (glyphs[i].advanceWidth ?? font.unitsPerEm * 0.6) * scale;
1033
- const codePoint = chars[i]?.codePointAt(0);
1034
- if (bold && (codePoint === void 0 || !isCjkCodePoint(codePoint))) {
1033
+ for (const char of text) {
1034
+ const codePoint = char.codePointAt(0);
1035
+ const isEa = isCjkCodePoint(codePoint);
1036
+ const font = isEa ? eaFont ?? fallbackFont : latinFont ?? fallbackFont;
1037
+ const scale = fontSizePx / font.unitsPerEm;
1038
+ const glyphs = font.stringToGlyphs(char);
1039
+ let charWidth = (glyphs[0]?.advanceWidth ?? font.unitsPerEm * 0.6) * scale;
1040
+ if (bold && !isEa) {
1035
1041
  charWidth *= BOLD_FACTOR2;
1036
1042
  }
1037
1043
  totalWidth += charWidth;
@@ -1050,7 +1056,14 @@ var OpentypeTextMeasurer = class {
1050
1056
  }
1051
1057
  resolveFont(name) {
1052
1058
  if (!name) return null;
1053
- return this.fonts.get(name) ?? null;
1059
+ const direct = this.fonts.get(name);
1060
+ if (direct) return direct;
1061
+ const mapped = getCurrentMappedFont(name);
1062
+ if (mapped) {
1063
+ const mappedFont = this.fonts.get(mapped);
1064
+ if (mappedFont) return mappedFont;
1065
+ }
1066
+ return null;
1054
1067
  }
1055
1068
  };
1056
1069
 
@@ -1535,15 +1548,35 @@ function parseXmlOrdered(xml) {
1535
1548
  }
1536
1549
 
1537
1550
  // src/png/png-converter.ts
1538
- import { renderAsync } from "@resvg/resvg-js";
1551
+ import { initWasm, Resvg } from "@resvg/resvg-wasm";
1552
+ import { readFile as readFile2 } from "fs/promises";
1553
+ import { createRequire } from "module";
1554
+ var wasmInitPromise = null;
1555
+ function resolveWasmPath() {
1556
+ const baseUrl = import.meta.url || `file://${__filename}`;
1557
+ const require2 = createRequire(baseUrl);
1558
+ return require2.resolve("@resvg/resvg-wasm/index_bg.wasm");
1559
+ }
1560
+ async function initResvgWasm() {
1561
+ if (!wasmInitPromise) {
1562
+ wasmInitPromise = (async () => {
1563
+ const wasmPath = resolveWasmPath();
1564
+ const wasmBuffer = await readFile2(wasmPath);
1565
+ await initWasm(wasmBuffer);
1566
+ })();
1567
+ }
1568
+ await wasmInitPromise;
1569
+ }
1539
1570
  async function svgToPng(svgString, options) {
1571
+ await initResvgWasm();
1540
1572
  const resvgOptions = {};
1541
1573
  if (options?.width) {
1542
1574
  resvgOptions.fitTo = { mode: "width", value: options.width };
1543
1575
  } else if (options?.height) {
1544
1576
  resvgOptions.fitTo = { mode: "height", value: options.height };
1545
1577
  }
1546
- const rendered = await renderAsync(svgString, resvgOptions);
1578
+ const resvg = new Resvg(svgString, resvgOptions);
1579
+ const rendered = resvg.render();
1547
1580
  return {
1548
1581
  png: Buffer.from(rendered.asPng()),
1549
1582
  width: rendered.width,
@@ -3860,7 +3893,7 @@ function parseParagraph(p, colorResolver, rels, fontScheme, lstStyle, orderedPCh
3860
3893
  const lnSpcSpcPct = lnSpc?.spcPct;
3861
3894
  const tabStops = parseTabStops(pPr);
3862
3895
  const properties = {
3863
- alignment: pPr?.["@_algn"] ?? lstLevelProps?.alignment ?? "l",
3896
+ alignment: pPr?.["@_algn"] ?? lstLevelProps?.alignment ?? null,
3864
3897
  lineSpacing: lnSpcSpcPct ? Number(lnSpcSpcPct["@_val"]) : null,
3865
3898
  spaceBefore: parseSpacing(pPr?.spcBef),
3866
3899
  spaceAfter: parseSpacing(pPr?.spcAft),
@@ -4544,6 +4577,19 @@ function resolveShapeTextInheritance(shape, context) {
4544
4577
  const chainSources = [layoutLstStyle, masterLstStyle, txStyle, context.defaultTextStyle];
4545
4578
  for (const paragraph of shape.textBody.paragraphs) {
4546
4579
  const level = paragraph.properties.level;
4580
+ if (paragraph.properties.alignment === null) {
4581
+ for (const source of chainSources) {
4582
+ if (!source) continue;
4583
+ const alignment = source.levels[level]?.alignment ?? source.defaultParagraph?.alignment;
4584
+ if (alignment) {
4585
+ paragraph.properties.alignment = alignment;
4586
+ break;
4587
+ }
4588
+ }
4589
+ if (paragraph.properties.alignment === null) {
4590
+ paragraph.properties.alignment = "l";
4591
+ }
4592
+ }
4547
4593
  for (const run of paragraph.runs) {
4548
4594
  const props = run.properties;
4549
4595
  for (const source of chainSources) {
@@ -8145,8 +8191,8 @@ function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, font
8145
8191
  segText,
8146
8192
  fontSize,
8147
8193
  props.bold,
8148
- fontFamily,
8149
- fontFamilyEa
8194
+ props.fontFamily,
8195
+ props.fontFamilyEa
8150
8196
  );
8151
8197
  if (font) {
8152
8198
  const path = font.getPath(segText, x + totalWidth, effectiveY, fontSizePx);
@@ -8170,8 +8216,8 @@ function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, font
8170
8216
  char,
8171
8217
  fontSize,
8172
8218
  props.bold,
8173
- fontFamily,
8174
- fontFamilyEa
8219
+ props.fontFamily,
8220
+ props.fontFamilyEa
8175
8221
  );
8176
8222
  if (font) {
8177
8223
  const charX = x + totalWidth;
@@ -8856,5 +8902,6 @@ export {
8856
8902
  createOpentypeTextMeasurerFromBuffers,
8857
8903
  getMappedFont,
8858
8904
  getWarningEntries,
8859
- getWarningSummary
8905
+ getWarningSummary,
8906
+ initResvgWasm
8860
8907
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pptx-glimpse",
3
- "version": "0.6.1",
3
+ "version": "0.7.1",
4
4
  "description": "A lightweight JavaScript library for rendering PowerPoint (.pptx) files as SVG or PNG in Node.js. No LibreOffice required.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -30,7 +30,7 @@
30
30
  "inspect": "tsx scripts/inspect-pptx.ts",
31
31
  "vrt:snapshot:docker-build": "docker build -t pptx-glimpse-snapshot-vrt docker/snapshot-vrt",
32
32
  "vrt:snapshot:fixtures": "tsx vrt/snapshot/create-fixtures.ts",
33
- "vrt:snapshot:update": "docker run --rm -v \"$(pwd)\":/workspace -v pptx-glimpse-snapshot-vrt-nm:/workspace/node_modules pptx-glimpse-snapshot-vrt bash /workspace/vrt/snapshot/docker-run.sh npx tsx vrt/snapshot/create-fixtures.ts && docker run --rm -v \"$(pwd)\":/workspace -v pptx-glimpse-snapshot-vrt-nm:/workspace/node_modules pptx-glimpse-snapshot-vrt bash /workspace/vrt/snapshot/docker-run.sh npx tsx vrt/snapshot/update-snapshots.ts",
33
+ "vrt:snapshot:update": "docker run --rm -v \"$(pwd)\":/workspace -v pptx-glimpse-snapshot-vrt-nm:/workspace/node_modules pptx-glimpse-snapshot-vrt bash /workspace/vrt/snapshot/docker-run.sh bash -c \"npx tsx vrt/snapshot/create-fixtures.ts && npx tsx vrt/snapshot/update-snapshots.ts\"",
34
34
  "vrt:lo:docker-build": "docker build -t pptx-glimpse-vrt docker/libreoffice-vrt",
35
35
  "vrt:lo:fixtures": "docker run --rm -v \"$(pwd)\":/workspace pptx-glimpse-vrt python3 /workspace/vrt/libreoffice/create_fixtures.py",
36
36
  "vrt:lo:update": "npm run vrt:lo:docker-build && npm run vrt:lo:fixtures && docker run --rm -v \"$(pwd)\":/workspace pptx-glimpse-vrt bash /workspace/vrt/libreoffice/update_snapshots.sh",
@@ -64,7 +64,7 @@
64
64
  "author": "hirokisakabe",
65
65
  "license": "MIT",
66
66
  "dependencies": {
67
- "@resvg/resvg-js": "^2.6.2",
67
+ "@resvg/resvg-wasm": "^2.6.2",
68
68
  "fast-xml-parser": "^5.3.6",
69
69
  "fflate": "^0.8.2",
70
70
  "opentype.js": "^1.3.4"