pptx-viewer-core 1.2.5 → 1.2.6

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/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to this project are documented here.
4
4
  This file is generated from [Conventional Commits](https://www.conventionalcommits.org)
5
5
  by [git-cliff](https://git-cliff.org); do not edit it by hand.
6
6
 
7
+ ## [1.2.5](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-viewer-core@1.2.5) - 2026-07-09
8
+
9
+ ### Other
10
+
11
+ - Reconcile with origin/main before push (by @ChristopherVR) ([b8c46bc](https://github.com/ChristopherVR/pptx-viewer/commit/b8c46bc3622e301d3365f5c489144e5aa5401782))
12
+
7
13
  ## [1.2.4](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-viewer-core@1.2.4) - 2026-07-09
8
14
 
9
15
  ## [1.2.3](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-viewer-core@1.2.3) - 2026-07-08
package/dist/cli/index.js CHANGED
Binary file
Binary file
Binary file
Binary file
package/dist/index.d.mts CHANGED
@@ -10950,7 +10950,8 @@ interface TemplateData {
10950
10950
  *
10951
10951
  * This file is the public API facade. Implementation is split across:
10952
10952
  * - `template-engine-types.ts` -- shared types
10953
- * - `template-engine-helpers.ts` -- token replacement, conditionals, element processing
10953
+ * - `template-engine-helpers.ts` -- token replacement, conditionals
10954
+ * - `template-engine-segments.ts` -- cross-segment replacement, element processing
10954
10955
  * - `template-engine-loops.ts` -- `{{#each}}` loop expansion
10955
10956
  *
10956
10957
  * @module sdk/template-engine
package/dist/index.d.ts CHANGED
@@ -10950,7 +10950,8 @@ interface TemplateData {
10950
10950
  *
10951
10951
  * This file is the public API facade. Implementation is split across:
10952
10952
  * - `template-engine-types.ts` -- shared types
10953
- * - `template-engine-helpers.ts` -- token replacement, conditionals, element processing
10953
+ * - `template-engine-helpers.ts` -- token replacement, conditionals
10954
+ * - `template-engine-segments.ts` -- cross-segment replacement, element processing
10954
10955
  * - `template-engine-loops.ts` -- `{{#each}}` loop expansion
10955
10956
  *
10956
10957
  * @module sdk/template-engine
package/dist/index.js CHANGED
@@ -42078,7 +42078,7 @@ var PptxHandlerRuntime57 = class extends PptxHandlerRuntime56 {
42078
42078
  for (const [, target] of layoutRels.entries()) {
42079
42079
  if (target.includes("slideMaster")) {
42080
42080
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
42081
- const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace("../", "")}`;
42081
+ const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace(/\.\.\//g, "")}`;
42082
42082
  try {
42083
42083
  const masterXmlStr = await this.zip.file(masterPath)?.async("string");
42084
42084
  if (masterXmlStr) {
@@ -42102,7 +42102,7 @@ var PptxHandlerRuntime57 = class extends PptxHandlerRuntime56 {
42102
42102
  for (const [, target] of slideRels.entries()) {
42103
42103
  if (target.includes("slideLayout")) {
42104
42104
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
42105
- const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${target.replace("../", "")}`;
42105
+ const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${target.replace(/\.\.\//g, "")}`;
42106
42106
  try {
42107
42107
  const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
42108
42108
  if (layoutXmlStr) {
@@ -42130,7 +42130,7 @@ var PptxHandlerRuntime57 = class extends PptxHandlerRuntime56 {
42130
42130
  for (const [, target] of slideRels.entries()) {
42131
42131
  if (target.includes("slideLayout")) {
42132
42132
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
42133
- const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${target.replace("../", "")}`;
42133
+ const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${target.replace(/\.\.\//g, "")}`;
42134
42134
  try {
42135
42135
  const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
42136
42136
  if (layoutXmlStr) {
@@ -42159,7 +42159,7 @@ var PptxHandlerRuntime57 = class extends PptxHandlerRuntime56 {
42159
42159
  for (const [, target] of layoutRels.entries()) {
42160
42160
  if (target.includes("slideMaster")) {
42161
42161
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
42162
- const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace("../", "")}`;
42162
+ const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace(/\.\.\//g, "")}`;
42163
42163
  try {
42164
42164
  const masterXmlStr = await this.zip.file(masterPath)?.async("string");
42165
42165
  if (masterXmlStr) {
@@ -42188,7 +42188,7 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
42188
42188
  for (const [, target] of slideRels.entries()) {
42189
42189
  if (target.includes("slideLayout")) {
42190
42190
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
42191
- const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${target.replace("../", "")}`;
42191
+ const layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${target.replace(/\.\.\//g, "")}`;
42192
42192
  try {
42193
42193
  const layoutXmlStr = await this.zip.file(layoutPath)?.async("string");
42194
42194
  if (layoutXmlStr) {
@@ -42217,7 +42217,7 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
42217
42217
  for (const [, target] of layoutRels.entries()) {
42218
42218
  if (target.includes("slideMaster")) {
42219
42219
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
42220
- const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace("../", "")}`;
42220
+ const masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace(/\.\.\//g, "")}`;
42221
42221
  try {
42222
42222
  const masterXmlStr = await this.zip.file(masterPath)?.async("string");
42223
42223
  if (masterXmlStr) {
@@ -42242,7 +42242,7 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
42242
42242
  for (const [, target] of slideRels.entries()) {
42243
42243
  if (target.includes("slideLayout")) {
42244
42244
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
42245
- return target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${target.replace("../", "")}`;
42245
+ return target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${target.replace(/\.\.\//g, "")}`;
42246
42246
  }
42247
42247
  }
42248
42248
  return void 0;
@@ -42258,7 +42258,7 @@ var PptxHandlerRuntime58 = class extends PptxHandlerRuntime57 {
42258
42258
  for (const [, target] of layoutRels.entries()) {
42259
42259
  if (target.includes("slideMaster")) {
42260
42260
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
42261
- return target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace("../", "")}`;
42261
+ return target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace(/\.\.\//g, "")}`;
42262
42262
  }
42263
42263
  }
42264
42264
  return void 0;
@@ -42902,7 +42902,7 @@ var PptxHandlerRuntime61 = class extends PptxHandlerRuntime60 {
42902
42902
  for (const [, target] of layoutRels.entries()) {
42903
42903
  if (target.includes("slideMaster")) {
42904
42904
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
42905
- masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace("../", "")}`;
42905
+ masterPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace(/\.\.\//g, "")}`;
42906
42906
  break;
42907
42907
  }
42908
42908
  }
@@ -43036,7 +43036,7 @@ var PptxHandlerRuntime62 = class extends PptxHandlerRuntime61 {
43036
43036
  for (const [, target] of slideRels.entries()) {
43037
43037
  if (target.includes("slideLayout")) {
43038
43038
  const slideDir = slidePath.substring(0, slidePath.lastIndexOf("/") + 1);
43039
- layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${target.replace("../", "")}`;
43039
+ layoutPath = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(slideDir, target) : `ppt/${target.replace(/\.\.\//g, "")}`;
43040
43040
  break;
43041
43041
  }
43042
43042
  }
@@ -46788,7 +46788,7 @@ var PptxHandlerRuntime78 = class extends PptxHandlerRuntime77 {
46788
46788
  }
46789
46789
  return stack.join("/");
46790
46790
  }
46791
- return `ppt/${target.replace("../", "")}`;
46791
+ return `ppt/${target.replace(/\.\.\//g, "")}`;
46792
46792
  }
46793
46793
  }
46794
46794
  return void 0;
@@ -47348,7 +47348,7 @@ var PptxHandlerRuntime80 = class extends PptxHandlerRuntime79 {
47348
47348
  for (const [, target] of layoutRels.entries()) {
47349
47349
  if (target.includes("slideMaster")) {
47350
47350
  const layoutDir = layoutPath.substring(0, layoutPath.lastIndexOf("/") + 1);
47351
- return target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace("../", "")}`;
47351
+ return target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(layoutDir, target) : `ppt/${target.replace(/\.\.\//g, "")}`;
47352
47352
  }
47353
47353
  }
47354
47354
  return void 0;
@@ -47417,7 +47417,7 @@ var PptxHandlerRuntime80 = class extends PptxHandlerRuntime79 {
47417
47417
  for (const [, target] of masterRels.entries()) {
47418
47418
  if (target.includes("slideLayout")) {
47419
47419
  const masterDir = masterPath.substring(0, masterPath.lastIndexOf("/") + 1);
47420
- const resolved = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(masterDir, target) : `ppt/${target.replace("../", "")}`;
47420
+ const resolved = target.startsWith("/") ? target.substring(1) : target.startsWith("..") ? this.resolvePath(masterDir, target) : `ppt/${target.replace(/\.\.\//g, "")}`;
47421
47421
  masterLayoutPaths.add(resolved);
47422
47422
  }
47423
47423
  }
@@ -56304,7 +56304,7 @@ function getShapeClipPathFromPreset(shapeType, width, height, adjustments) {
56304
56304
  if (!result || result.svgPath === "") {
56305
56305
  return void 0;
56306
56306
  }
56307
- const escaped = result.svgPath.replace(/'/g, "\\'");
56307
+ const escaped = result.svgPath.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
56308
56308
  return `path('${escaped}')`;
56309
56309
  }
56310
56310
  function getRoundRectRadiusPx(element) {
@@ -58235,7 +58235,7 @@ function moveSlidesToSection(data, slideIndices, targetSectionId) {
58235
58235
  }
58236
58236
 
58237
58237
  // src/core/builders/sdk/template-engine-helpers.ts
58238
- var PLACEHOLDER_RE = /\{\{([^}]+)\}\}/g;
58238
+ var PLACEHOLDER_RE = /\{\{([^{}]+)\}\}/g;
58239
58239
  var EACH_OPEN_RE = /^\s*#each\s+([\w.]+)\s*$/;
58240
58240
  var EACH_CLOSE_RE = /^\s*\/each\s*$/;
58241
58241
  var IF_OPEN_RE = /^\s*#if\s+(!?[\w.]+)\s*$/;
@@ -58299,7 +58299,7 @@ function processInlineConditionals(text, data) {
58299
58299
  let safety = 0;
58300
58300
  const MAX_ITERATIONS = 100;
58301
58301
  while (safety++ < MAX_ITERATIONS) {
58302
- const ifOpenPattern = /\{\{\s*#if\s+([^}]+)\s*\}\}((?:(?!\{\{\s*#if\s)(?!\{\{\s*\/if\s*\}\}).)*?)\{\{\s*\/if\s*\}\}/s;
58302
+ const ifOpenPattern = /\{\{\s*#if\s+(!?[\w.]+)\s*\}\}((?:(?!\{\{\s*#if\s)(?!\{\{\s*\/if\s*\}\}).)*?)\{\{\s*\/if\s*\}\}/s;
58303
58303
  const match = ifOpenPattern.exec(result);
58304
58304
  if (!match) {
58305
58305
  break;
@@ -58311,6 +58311,8 @@ function processInlineConditionals(text, data) {
58311
58311
  }
58312
58312
  return result;
58313
58313
  }
58314
+
58315
+ // src/core/builders/sdk/template-engine-segments.ts
58314
58316
  function replaceTokensAcrossSegments(segments, data) {
58315
58317
  if (segments.length === 0) {
58316
58318
  return;
@@ -58331,7 +58333,7 @@ function replaceTokensAcrossSegments(segments, data) {
58331
58333
  const fullText = textParts.join("");
58332
58334
  const afterConditionals = processInlineConditionals(fullText, data);
58333
58335
  if (afterConditionals !== fullText) {
58334
- redistributeText(segments, segmentMap, fullText, afterConditionals);
58336
+ redistributeText(segments, fullText, afterConditionals);
58335
58337
  replaceTokensAcrossSegments(segments, data);
58336
58338
  return;
58337
58339
  }
@@ -58389,7 +58391,7 @@ function replaceTokensAcrossSegments(segments, data) {
58389
58391
  }
58390
58392
  }
58391
58393
  }
58392
- function redistributeText(segments, _segmentMap, _originalFull, newFull, _data) {
58394
+ function redistributeText(segments, _originalFull, newFull) {
58393
58395
  let placed = false;
58394
58396
  for (const seg of segments) {
58395
58397
  if (seg.isParagraphBreak) {
@@ -58631,15 +58633,81 @@ async function mailMerge(handler, data, records) {
58631
58633
  }
58632
58634
 
58633
58635
  // src/core/builders/sdk/text-operations.ts
58634
- function toGlobalRegex(search) {
58636
+ function toSearchRegex(search) {
58635
58637
  if (typeof search === "string") {
58636
58638
  const escaped = search.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
58637
58639
  return new RegExp(escaped, "g");
58638
58640
  }
58639
- if (search.global) {
58640
- return search;
58641
+ return search;
58642
+ }
58643
+ function execAll(regex, text) {
58644
+ const results = [];
58645
+ if (regex.global || regex.sticky) {
58646
+ regex.lastIndex = 0;
58647
+ let match;
58648
+ while ((match = regex.exec(text)) !== null) {
58649
+ results.push(match);
58650
+ if (match[0].length === 0) {
58651
+ regex.lastIndex += 1;
58652
+ }
58653
+ }
58654
+ return results;
58641
58655
  }
58642
- return new RegExp(search.source, `${search.flags}g`);
58656
+ let offset = 0;
58657
+ let remaining = text;
58658
+ while (remaining.length > 0) {
58659
+ const match = regex.exec(remaining);
58660
+ if (!match) {
58661
+ break;
58662
+ }
58663
+ const adjusted = [...match];
58664
+ adjusted.index = offset + match.index;
58665
+ adjusted.input = text;
58666
+ adjusted.groups = match.groups;
58667
+ results.push(adjusted);
58668
+ const advance = match.index + (match[0].length || 1);
58669
+ offset += advance;
58670
+ remaining = remaining.slice(advance);
58671
+ }
58672
+ return results;
58673
+ }
58674
+ function expandReplacement(replacement, match, fullText) {
58675
+ return replacement.replace(
58676
+ /\$(\$|&|`|'|<([^>]+)>|\d{1,2})/g,
58677
+ (whole, token, groupName) => {
58678
+ if (token === "$") {
58679
+ return "$";
58680
+ }
58681
+ if (token === "&") {
58682
+ return match[0];
58683
+ }
58684
+ if (token === "`") {
58685
+ return fullText.slice(0, match.index);
58686
+ }
58687
+ if (token === "'") {
58688
+ return fullText.slice(match.index + match[0].length);
58689
+ }
58690
+ if (groupName !== void 0) {
58691
+ return match.groups?.[groupName] ?? "";
58692
+ }
58693
+ const groupIndex = Number(token);
58694
+ return groupIndex >= 1 && groupIndex < match.length ? match[groupIndex] ?? "" : whole;
58695
+ }
58696
+ );
58697
+ }
58698
+ function applyReplacements(text, matches, replacement) {
58699
+ if (matches.length === 0) {
58700
+ return text;
58701
+ }
58702
+ let result = "";
58703
+ let cursor = 0;
58704
+ for (const match of matches) {
58705
+ result += text.slice(cursor, match.index);
58706
+ result += expandReplacement(replacement, match, text);
58707
+ cursor = match.index + match[0].length;
58708
+ }
58709
+ result += text.slice(cursor);
58710
+ return result;
58643
58711
  }
58644
58712
  function collectElements(elements) {
58645
58713
  const result = [];
@@ -58655,7 +58723,7 @@ function findText(slides, search) {
58655
58723
  if (typeof search === "string" && search === "") {
58656
58724
  return [];
58657
58725
  }
58658
- const regex = toGlobalRegex(search);
58726
+ const regex = toSearchRegex(search);
58659
58727
  const results = [];
58660
58728
  slides.forEach((slide, slideIndex) => {
58661
58729
  const allElements = collectElements(slide.elements ?? []);
@@ -58666,9 +58734,7 @@ function findText(slides, search) {
58666
58734
  const segments = element.textSegments ?? [];
58667
58735
  segments.forEach((seg, segIndex) => {
58668
58736
  const text = seg.text ?? "";
58669
- regex.lastIndex = 0;
58670
- let match;
58671
- while ((match = regex.exec(text)) !== null) {
58737
+ for (const match of execAll(regex, text)) {
58672
58738
  results.push({
58673
58739
  slideIndex,
58674
58740
  elementId: element.id,
@@ -58676,9 +58742,6 @@ function findText(slides, search) {
58676
58742
  text: match[0],
58677
58743
  matchIndex: match.index
58678
58744
  });
58679
- if (match[0].length === 0) {
58680
- regex.lastIndex += 1;
58681
- }
58682
58745
  }
58683
58746
  });
58684
58747
  }
@@ -58689,7 +58752,7 @@ function replaceTextInSlide(slide, search, replacement) {
58689
58752
  if (typeof search === "string" && search === "") {
58690
58753
  return 0;
58691
58754
  }
58692
- const regex = toGlobalRegex(search);
58755
+ const regex = toSearchRegex(search);
58693
58756
  let totalReplacements = 0;
58694
58757
  function processElements2(elements) {
58695
58758
  for (const element of elements) {
@@ -58701,23 +58764,12 @@ function replaceTextInSlide(slide, search, replacement) {
58701
58764
  }
58702
58765
  const segments = element.textSegments ?? [];
58703
58766
  let elementTextChanged = false;
58704
- for (let segIdx = 0; segIdx < segments.length; segIdx++) {
58705
- const seg = segments[segIdx];
58767
+ for (const seg of segments) {
58706
58768
  const originalText = seg.text ?? "";
58707
- regex.lastIndex = 0;
58708
- let matchCount = 0;
58709
- let m;
58710
- const countRegex = toGlobalRegex(search);
58711
- while ((m = countRegex.exec(originalText)) !== null) {
58712
- matchCount++;
58713
- if (m[0].length === 0) {
58714
- countRegex.lastIndex += 1;
58715
- }
58716
- }
58717
- if (matchCount > 0) {
58718
- const newText = originalText.replace(toGlobalRegex(search), replacement);
58719
- seg.text = newText;
58720
- totalReplacements += matchCount;
58769
+ const matches = execAll(regex, originalText);
58770
+ if (matches.length > 0) {
58771
+ seg.text = applyReplacements(originalText, matches, replacement);
58772
+ totalReplacements += matches.length;
58721
58773
  elementTextChanged = true;
58722
58774
  }
58723
58775
  }
@@ -62681,7 +62733,7 @@ ${htmlRows.join("\n")}
62681
62733
  return parts.join("").trim();
62682
62734
  }
62683
62735
  escapeMarkdownTableCell(text) {
62684
- return text.replace(/\|/g, "\\|").replace(/\n+/g, " ").trim();
62736
+ return text.replace(/\\/g, "\\\\").replace(/\|/g, "\\|").replace(/\n+/g, " ").trim();
62685
62737
  }
62686
62738
  };
62687
62739