pptx-custom 0.1.2 → 0.2.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/dist/index.js CHANGED
@@ -27,6 +27,9 @@ __export(index_exports, {
27
27
  });
28
28
  module.exports = __toCommonJS(index_exports);
29
29
 
30
+ // src/custom-content/index.ts
31
+ var import_json2pptx_schema = require("json2pptx-schema");
32
+
30
33
  // src/custom-content/parser.ts
31
34
  var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
32
35
  var asString = (value) => typeof value === "string" ? value : null;
@@ -142,6 +145,20 @@ var setElementText = (element, text) => {
142
145
  };
143
146
 
144
147
  // src/custom-content/slide-appliers.ts
148
+ function setShapeTextByType(slide, textType, text) {
149
+ const shape = slide.elements.find((element) => {
150
+ if (element.type !== "shape") return false;
151
+ const maybeShape = element;
152
+ return maybeShape.text?.type === textType;
153
+ });
154
+ if (!shape) return false;
155
+ const shapeWithText = shape;
156
+ if (!shapeWithText.text || typeof shapeWithText.text.content !== "string") {
157
+ return false;
158
+ }
159
+ shapeWithText.text.content = updateHtmlContent(shapeWithText.text.content, text);
160
+ return true;
161
+ }
145
162
  var applyCoverData = (slide, data) => {
146
163
  const title = slide.elements.find(
147
164
  (element) => element.type === "text" && element.textType === "title"
@@ -173,7 +190,12 @@ var applyTransitionData = (slide, data, sectionIndex) => {
173
190
  );
174
191
  if (title) setElementText(title, data.title);
175
192
  if (content) setElementText(content, data.text);
176
- if (partNumber) setElementText(partNumber, `${sectionIndex}`.padStart(2, "0"));
193
+ const formattedSectionIndex = `${sectionIndex}`.padStart(2, "0");
194
+ if (partNumber) {
195
+ setElementText(partNumber, formattedSectionIndex);
196
+ } else {
197
+ setShapeTextByType(slide, "partNumber", formattedSectionIndex);
198
+ }
177
199
  };
178
200
  var applyContentData = (slide, data) => {
179
201
  const title = slide.elements.find(
@@ -196,6 +218,22 @@ var applyContentData = (slide, data) => {
196
218
 
197
219
  // src/custom-content/template-builder.ts
198
220
  var cloneSlide = (slide) => JSON.parse(JSON.stringify(slide));
221
+ function normalizeLabel(value) {
222
+ return value.replace(/\s+/g, " ").replace(/[,。、“”‘’:;!?【】()《》〈〉·,.:;!?()[\]{}"'`~\-_/\\]/g, "").trim().toLowerCase();
223
+ }
224
+ function resolveTransitionIndex(customSlides, currentSlideIndex, transitionTitle, fallbackIndex) {
225
+ const normalizedTitle = normalizeLabel(transitionTitle);
226
+ if (!normalizedTitle) return fallbackIndex;
227
+ const contentsItems = customSlides.slice(0, currentSlideIndex + 1).filter((slide) => slide.type === "contents").flatMap((slide) => slide.data.items);
228
+ for (let index = 0; index < contentsItems.length; index += 1) {
229
+ const normalizedItem = normalizeLabel(contentsItems[index]);
230
+ if (!normalizedItem) continue;
231
+ if (normalizedItem === normalizedTitle || normalizedItem.includes(normalizedTitle) || normalizedTitle.includes(normalizedItem)) {
232
+ return index + 1;
233
+ }
234
+ }
235
+ return fallbackIndex;
236
+ }
199
237
  var applyCustomContentToTemplate = (template, CustomSlides) => {
200
238
  const grouped = template.slides.reduce(
201
239
  (acc, slide) => {
@@ -240,7 +278,7 @@ var applyCustomContentToTemplate = (template, CustomSlides) => {
240
278
  return pickFromPool(`${type}:${desiredCount}`, fallback);
241
279
  };
242
280
  let transitionIndex = 0;
243
- const slides = CustomSlides.map((item) => {
281
+ const slides = CustomSlides.map((item, index) => {
244
282
  const desiredCount = item.type === "contents" ? item.data.items.length : item.type === "content" ? item.data.items.length : void 0;
245
283
  const slide = pickSlide(item.type, desiredCount);
246
284
  if (item.type === "cover") {
@@ -249,7 +287,13 @@ var applyCustomContentToTemplate = (template, CustomSlides) => {
249
287
  applyContentsData(slide, item.data);
250
288
  } else if (item.type === "transition") {
251
289
  transitionIndex += 1;
252
- applyTransitionData(slide, item.data, transitionIndex);
290
+ const partNumber = resolveTransitionIndex(
291
+ CustomSlides,
292
+ index,
293
+ item.data.title,
294
+ transitionIndex
295
+ );
296
+ applyTransitionData(slide, item.data, partNumber);
253
297
  } else if (item.type === "content") {
254
298
  applyContentData(slide, item.data);
255
299
  }
@@ -263,10 +307,15 @@ var applyCustomContentToTemplate = (template, CustomSlides) => {
263
307
 
264
308
  // src/custom-content/index.ts
265
309
  function applyCustomContent(template, input) {
310
+ const normalizedTemplate = (0, import_json2pptx_schema.parseDocument)(template);
266
311
  const CustomSlides = typeof input === "string" ? parseCustomContent(input) : input;
267
- return applyCustomContentToTemplate(template, CustomSlides);
312
+ const updated = applyCustomContentToTemplate(normalizedTemplate, CustomSlides);
313
+ return (0, import_json2pptx_schema.parseDocument)(updated);
268
314
  }
269
315
 
316
+ // src/custom-theme/index.ts
317
+ var import_json2pptx_schema2 = require("json2pptx-schema");
318
+
270
319
  // src/custom-theme/color-utils.ts
271
320
  function normalizeHexColor(value) {
272
321
  const raw = value.trim();
@@ -531,7 +580,9 @@ function applyTheme2Json(deck, update) {
531
580
 
532
581
  // src/custom-theme/index.ts
533
582
  function applyCustomTheme(deck, input) {
534
- return applyTheme2Json(deck, input);
583
+ const normalizedDeck = (0, import_json2pptx_schema2.parseDocument)(deck);
584
+ const updated = applyTheme2Json(normalizedDeck, input);
585
+ return (0, import_json2pptx_schema2.parseDocument)(updated);
535
586
  }
536
587
  // Annotate the CommonJS export names for ESM import in node:
537
588
  0 && (module.exports = {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/custom-content/parser.ts","../src/custom-content/html.ts","../src/custom-content/slide-appliers.ts","../src/custom-content/template-builder.ts","../src/custom-content/index.ts","../src/custom-theme/color-utils.ts","../src/custom-theme/mappings.ts","../src/custom-theme/replacers.ts","../src/custom-theme/theme-applier.ts","../src/custom-theme/index.ts"],"sourcesContent":["import { applyCustomContent, parseCustomContent, applyCustomContentToTemplate } from './custom-content/index'\nimport { applyCustomTheme } from './custom-theme/index'\n\nexport {\n parseCustomContent,\n applyCustomContent,\n applyCustomContentToTemplate,\n\n applyCustomTheme,\n}\n\nexport type {\n CustomSlide,\n Deck,\n PptxCustomContentInput,\n PptxCustomOptions,\n PptxCustomThemeInput,\n TemplateJson,\n TemplateJsonElement,\n TemplateJsonSlide,\n TemplateJsonTheme\n} from './types'\n","import type { BackendContentItem, CustomSlide } from '../types'\n\ntype UnknownRecord = Record<string, unknown>\n\nconst isRecord = (value: unknown): value is UnknownRecord =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst asString = (value: unknown): string | null =>\n typeof value === 'string' ? value : null\n\nconst asStringArray = (value: unknown): string[] | null => {\n if (!Array.isArray(value)) return null\n const normalized = value\n .map(item => asString(item))\n .filter((item): item is string => item !== null)\n return normalized.length === value.length ? normalized : null\n}\n\nconst normalizeType = (value: unknown): CustomSlide['type'] | null => {\n const raw = asString(value)?.trim().toLowerCase()\n if (!raw) return null\n if (raw === 'agenda') return 'contents'\n if (raw === 'section') return 'transition'\n if (raw === 'ending') return 'end'\n if (\n raw === 'cover' ||\n raw === 'contents' ||\n raw === 'transition' ||\n raw === 'content' ||\n raw === 'end'\n ) {\n return raw\n }\n return null\n}\n\nconst normalizeContentItems = (value: unknown): BackendContentItem[] | null => {\n if (!Array.isArray(value)) return null\n const normalized: BackendContentItem[] = []\n for (const item of value) {\n if (!isRecord(item)) return null\n const title = asString(item.title)\n const text = asString(item.text)\n if (title == null || text == null) return null\n normalized.push({ title, text })\n }\n return normalized\n}\n\nconst normalizeSlide = (value: unknown): CustomSlide | null => {\n if (!isRecord(value)) return null\n const type = normalizeType(value.type)\n if (!type) return null\n\n const rawData = isRecord(value.data) ? value.data : {}\n\n if (type === 'cover') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'contents') {\n const items = asStringArray(rawData.items)\n if (!items) return null\n return { type, data: { items } }\n }\n\n if (type === 'transition') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'content') {\n const title = asString(rawData.title)\n const items = normalizeContentItems(rawData.items)\n if (title == null || !items) return null\n return { type, data: { title, items } }\n }\n\n return { type }\n}\n\nconst parseNdJsonSlides = (raw: string): unknown[] =>\n raw\n .split(/\\r?\\n/)\n .map(line => line.trim())\n .filter(Boolean)\n .map(line => JSON.parse(line) as unknown)\n\nconst parseStructuredSlides = (raw: string): unknown[] | null => {\n const trimmed = raw.trim()\n if (!trimmed) return []\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) return null\n\n let parsed: unknown\n try {\n parsed = JSON.parse(trimmed) as unknown\n } catch {\n return null\n }\n if (Array.isArray(parsed)) return parsed\n if (!isRecord(parsed)) return null\n if (Array.isArray(parsed.slides)) return parsed.slides\n if ('type' in parsed) return [parsed]\n return null\n}\n\nexport const parseCustomContent = (raw: string): CustomSlide[] => {\n const candidates = parseStructuredSlides(raw) ?? parseNdJsonSlides(raw)\n const slides = candidates\n .map(item => normalizeSlide(item))\n .filter((item): item is CustomSlide => item !== null)\n\n if (slides.length !== candidates.length) {\n throw new Error('Invalid custom content format')\n }\n return slides\n}\n","import type { TemplateJsonElement } from '../types'\n\nexport const updateHtmlContent = (html: string, text: string) => {\n if (typeof DOMParser === 'undefined') {\n return `<p>${text}</p>`\n }\n const parser = new DOMParser()\n const doc = parser.parseFromString(html, 'text/html')\n const spans = Array.from(doc.querySelectorAll('span'))\n if (spans.length > 0) {\n spans.forEach((span, index) => {\n span.textContent = index === 0 ? text : ''\n })\n } else {\n const paragraph = doc.querySelector('p')\n if (paragraph) {\n paragraph.textContent = text\n } else {\n doc.body.textContent = text\n }\n }\n return doc.body.innerHTML\n}\n\nexport const setElementText = (element: TemplateJsonElement, text: string) => {\n if (element.type !== 'text') return\n element.content = updateHtmlContent(element.content, text)\n}\n","import type {\n BackendContentData,\n BackendContentsData,\n BackendCoverData,\n BackendTransitionData,\n TemplateJsonSlide\n} from '../types'\nimport { setElementText } from './html'\n\nexport const applyCoverData = (slide: TemplateJsonSlide, data: BackendCoverData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n}\n\nexport const applyContentsData = (\n slide: TemplateJsonSlide,\n data: BackendContentsData\n) => {\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n items.forEach((element, index) => {\n const text = data.items[index]\n if (text) setElementText(element, text)\n })\n}\n\nexport const applyTransitionData = (\n slide: TemplateJsonSlide,\n data: BackendTransitionData,\n sectionIndex: number\n) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n const partNumber = slide.elements.find(\n element => element.type === 'text' && element.textType === 'partNumber'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n if (partNumber) setElementText(partNumber, `${sectionIndex}`.padStart(2, '0'))\n}\n\nexport const applyContentData = (slide: TemplateJsonSlide, data: BackendContentData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n if (title) setElementText(title, data.title)\n\n const itemTitles = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'itemTitle'\n )\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n\n data.items.forEach((item, index) => {\n const titleEl = itemTitles[index]\n const textEl = items[index]\n if (titleEl) setElementText(titleEl, item.title)\n if (textEl) setElementText(textEl, item.text)\n })\n}\n","import type { CustomSlide, TemplateJson, TemplateJsonSlide } from '../types'\nimport {\n applyContentData,\n applyContentsData,\n applyCoverData,\n applyTransitionData\n} from './slide-appliers'\n\nconst cloneSlide = (slide: TemplateJsonSlide): TemplateJsonSlide =>\n JSON.parse(JSON.stringify(slide)) as TemplateJsonSlide\n\nexport const applyCustomContentToTemplate = (\n template: TemplateJson,\n CustomSlides: CustomSlide[]\n): TemplateJson => {\n const grouped = template.slides.reduce<Record<string, TemplateJsonSlide[]>>(\n (acc, slide) => {\n const key = slide.type || 'default'\n if (!acc[key]) acc[key] = []\n acc[key].push(slide)\n return acc\n },\n {}\n )\n\n const usage = new Map<string, number>()\n const getTextTypeCount = (slide: TemplateJsonSlide, textType: string) =>\n slide.elements.filter(\n element => element.type === 'text' && element.textType === textType\n ).length\n\n const getContentCapacity = (slide: TemplateJsonSlide) => {\n const titleSlots = getTextTypeCount(slide, 'itemTitle')\n const itemSlots = getTextTypeCount(slide, 'item')\n return Math.min(titleSlots, itemSlots)\n }\n\n const pickFromPool = (key: string, pool: TemplateJsonSlide[]) => {\n const index = usage.get(key) ?? 0\n usage.set(key, index + 1)\n return cloneSlide(pool[index % pool.length])\n }\n\n const pickSlide = (type: string, desiredCount?: number) => {\n const pool = grouped[type] || grouped.default || template.slides\n if (desiredCount == null || pool.length === 1) {\n return pickFromPool(type, pool)\n }\n\n const scored = pool.map(slide => {\n const capacity =\n type === 'content'\n ? getContentCapacity(slide)\n : getTextTypeCount(slide, 'item')\n return { slide, capacity }\n })\n const eligible = scored.filter(item => item.capacity >= desiredCount)\n if (eligible.length > 0) {\n const minCapacity = Math.min(...eligible.map(item => item.capacity))\n const best = eligible\n .filter(item => item.capacity === minCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, best)\n }\n const maxCapacity = Math.max(...scored.map(item => item.capacity))\n const fallback = scored\n .filter(item => item.capacity === maxCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, fallback)\n }\n\n let transitionIndex = 0\n const slides = CustomSlides.map(item => {\n const desiredCount =\n item.type === 'contents'\n ? item.data.items.length\n : item.type === 'content'\n ? item.data.items.length\n : undefined\n const slide = pickSlide(item.type, desiredCount)\n if (item.type === 'cover') {\n applyCoverData(slide, item.data)\n } else if (item.type === 'contents') {\n applyContentsData(slide, item.data)\n } else if (item.type === 'transition') {\n transitionIndex += 1\n applyTransitionData(slide, item.data, transitionIndex)\n } else if (item.type === 'content') {\n applyContentData(slide, item.data)\n }\n return slide\n })\n\n return {\n ...template,\n slides\n }\n}\n","import type { PptxCustomContentInput, TemplateJson } from '../types'\nimport { parseCustomContent } from './parser'\nimport { applyCustomContentToTemplate } from './template-builder'\n\nexport function applyCustomContent (\n template: TemplateJson,\n input: PptxCustomContentInput\n): TemplateJson {\n const CustomSlides = typeof input === 'string' ? parseCustomContent(input) : input\n return applyCustomContentToTemplate(template, CustomSlides)\n}\n\nexport { parseCustomContent, applyCustomContentToTemplate }\n","import type { ColorMapping, RGB } from './types'\n\nexport function normalizeHexColor (value: string): string | null {\n const raw = value.trim()\n const withHash = raw.startsWith('#') ? raw.slice(1) : raw\n if (withHash.length !== 3 && withHash.length !== 6) return null\n if (!/^[0-9a-fA-F]+$/.test(withHash)) return null\n const expanded =\n withHash.length === 3\n ? withHash\n .split('')\n .map((char) => char + char)\n .join('')\n : withHash\n return `#${expanded.toUpperCase()}`\n}\n\nexport function parseColorToRgb (\n value: string\n): (RGB & { alpha?: number }) | null {\n const hex = normalizeHexColor(value)\n if (hex) {\n const raw = hex.slice(1)\n const r = Number.parseInt(raw.slice(0, 2), 16)\n const g = Number.parseInt(raw.slice(2, 4), 16)\n const b = Number.parseInt(raw.slice(4, 6), 16)\n return { r, g, b }\n }\n\n const match = value.match(\n /rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)/i\n )\n if (!match) return null\n const r = Math.round(Number(match[1]))\n const g = Math.round(Number(match[2]))\n const b = Math.round(Number(match[3]))\n const alpha = match[4] !== undefined ? Number(match[4]) : undefined\n return {\n r,\n g,\n b,\n ...(Number.isFinite(alpha) ? { alpha } : {})\n }\n}\n\nexport function normalizeThemeColor (value: string): string | null {\n const hex = normalizeHexColor(value)\n if (hex) return hex\n const parsed = parseColorToRgb(value)\n if (!parsed) return null\n if (parsed.alpha !== undefined) {\n return `rgba(${parsed.r},${parsed.g},${parsed.b},${parsed.alpha})`\n }\n return `rgb(${parsed.r},${parsed.g},${parsed.b})`\n}\n\nexport function isPureColorString (value: string): boolean {\n const trimmed = value.trim()\n if (!trimmed) return false\n if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(trimmed)) return true\n return /^rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)$/i.test(\n trimmed\n )\n}\n\nfunction normalizeColorKey (value?: string): string | null {\n if (!value) return null\n const trimmed = value.trim()\n if (!trimmed) return null\n const parsed = parseColorToRgb(trimmed)\n if (parsed) {\n return `${parsed.r},${parsed.g},${parsed.b},${parsed.alpha ?? 'none'}`\n }\n const hex = normalizeHexColor(trimmed)\n if (hex) return hex\n return trimmed.toLowerCase()\n}\n\nexport function colorsEqual (a: string, b: string): boolean {\n const aKey = normalizeColorKey(a)\n const bKey = normalizeColorKey(b)\n if (!aKey || !bKey) return false\n return aKey === bKey\n}\n\nexport function isWhiteColor (value?: string): boolean {\n const key = normalizeColorKey(value)\n if (!key) return false\n return (\n key === '#FFFFFF' ||\n key === '255,255,255,none' ||\n key === '255,255,255,1'\n )\n}\n\nexport function rgbToString (rgb: RGB): string {\n return `rgb(${rgb.r},${rgb.g},${rgb.b})`\n}\n\nexport function findMappingForColor (\n value: string,\n mappings: ColorMapping[]\n): ColorMapping | undefined {\n const parsed = parseColorToRgb(value)\n if (!parsed) return undefined\n return mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n}\n","import { normalizeHexColor, parseColorToRgb } from './color-utils'\nimport type { ColorMapping } from './types'\n\nexport function buildColorMappings (\n previous: string[],\n next: string[]\n): ColorMapping[] {\n const mappings: ColorMapping[] = []\n const length = Math.min(previous.length, next.length)\n for (let i = 0; i < length; i += 1) {\n const fromParsed = parseColorToRgb(previous[i])\n const toParsed = parseColorToRgb(next[i])\n if (!fromParsed || !toParsed) continue\n const toHex = normalizeHexColor(next[i]) ?? undefined\n mappings.push({\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n })\n }\n return mappings\n}\n\nexport function buildSingleMapping (\n from?: string,\n to?: string\n): ColorMapping | null {\n if (!from || !to) return null\n const fromParsed = parseColorToRgb(from)\n const toParsed = parseColorToRgb(to)\n if (!fromParsed || !toParsed) return null\n const toHex = normalizeHexColor(to) ?? undefined\n return {\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n }\n}\n","import type { Slide, SlideElement } from '../types'\nimport {\n findMappingForColor,\n isPureColorString,\n normalizeThemeColor,\n parseColorToRgb,\n rgbToString\n} from './color-utils'\nimport type { ColorMapping } from './types'\n\nfunction applyFontColorToHtml (value: string, fontColor: string): string {\n if (!value || !fontColor) return value\n const normalized = normalizeThemeColor(fontColor) ?? fontColor\n const hasStyleColor = /\\bcolor\\s*:/i.test(value)\n if (hasStyleColor) {\n return value.replace(/color\\s*:\\s*([^;\"']+)/gi, () => `color: ${normalized}`)\n }\n return value.replace(\n /(<[^>]+style\\s*=\\s*[\"'])([^\"']*)([\"'])/gi,\n (_match, start, styles, end) => {\n if (/\\bcolor\\s*:/i.test(styles)) return _match\n const nextStyles = styles.trim()\n ? `${styles.trim()}; color: ${normalized}`\n : `color: ${normalized}`\n return `${start}${nextStyles}${end}`\n }\n )\n}\n\nfunction replaceColorValue (value: string, mappings: ColorMapping[]): string {\n const mapping = findMappingForColor(value, mappings)\n if (!mapping) return value\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n if (parsed.alpha !== undefined) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceRgbaString (value: string, mappings: ColorMapping[]): string {\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n const mapping = mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n if (!mapping) return value\n if (parsed.alpha !== undefined || value.toLowerCase().startsWith('rgba')) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha ?? 1})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceColorsInText (value: string, mappings: ColorMapping[]): string {\n let next = value\n next = next.replace(/#([0-9a-f]{3}|[0-9a-f]{6})/gi, (match) => {\n const mapping = findMappingForColor(match, mappings)\n if (!mapping) return match\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n })\n next = next.replace(/rgba?\\([^)]*\\)/gi, (match) =>\n replaceRgbaString(match, mappings)\n )\n return next\n}\n\nfunction replaceColorsDeep (value: unknown, mappings: ColorMapping[]): unknown {\n if (typeof value === 'string') {\n const trimmed = value.trim()\n const pureColor = isPureColorString(trimmed)\n if (pureColor) {\n const replaced = replaceColorValue(trimmed, mappings)\n return value === trimmed ? replaced : value.replace(trimmed, replaced)\n }\n return replaceColorsInText(value, mappings)\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => replaceColorsDeep(item, mappings))\n }\n\n if (value && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n const next: Record<string, unknown> = {}\n for (const [key, item] of entries) {\n next[key] = replaceColorsDeep(item, mappings)\n }\n return next\n }\n\n return value\n}\n\nfunction replaceTextElementColors (\n element: SlideElement,\n fontMappings: ColorMapping[],\n fontColor: string\n): SlideElement {\n const next = replaceColorsDeep(element, fontMappings) as SlideElement\n const normalizedFontColor = normalizeThemeColor(fontColor) ?? fontColor\n const withDefault =\n normalizedFontColor && 'defaultColor' in next\n ? { ...next, defaultColor: normalizedFontColor }\n : next\n if (!('content' in withDefault) || typeof withDefault.content !== 'string') {\n return withDefault\n }\n return {\n ...withDefault,\n content: applyFontColorToHtml(withDefault.content, normalizedFontColor)\n }\n}\n\nexport function replaceSlideColors (\n slide: Slide,\n themeMappings: ColorMapping[],\n fontMappings: ColorMapping[],\n fontColor: string\n): Slide {\n const { elements, ...rest } = slide\n const nextSlide = replaceColorsDeep(rest, themeMappings) as Slide\n if (!elements) return nextSlide\n\n const nextElements: SlideElement[] = elements.map((element) => {\n if (element && typeof element === 'object' && element.type === 'text') {\n return replaceTextElementColors(element, fontMappings, fontColor)\n }\n return replaceColorsDeep(element, themeMappings) as SlideElement\n })\n\n return { ...nextSlide, elements: nextElements }\n}\n","import type { Deck, PptxCustomThemeInput } from '../types'\nimport { colorsEqual, isWhiteColor } from './color-utils'\nimport { buildColorMappings, buildSingleMapping } from './mappings'\nimport { replaceSlideColors } from './replacers'\n\nexport function applyTheme2Json (deck: Deck, update: PptxCustomThemeInput): Deck {\n const previousTheme = deck.theme ?? {}\n const themeColors = update.themeColors.slice(0, 6)\n const themeMappings = buildColorMappings(\n previousTheme.themeColors ?? [],\n themeColors\n )\n const fontMapping = buildSingleMapping(\n previousTheme.fontColor,\n update.fontColor\n )\n const fontMappings = fontMapping ? [fontMapping] : []\n\n const nextBackground = update.backgroundColor ?? previousTheme.backgroundColor\n const prevBackground = previousTheme.backgroundColor\n const slides = deck.slides?.map((slide) => {\n const nextSlide = replaceSlideColors(\n slide,\n themeMappings,\n fontMappings,\n update.fontColor\n )\n if (!nextBackground) return nextSlide\n const currentColor = nextSlide.background?.color\n const shouldUpdate =\n !currentColor ||\n (prevBackground && colorsEqual(currentColor, prevBackground)) ||\n (!prevBackground && isWhiteColor(currentColor))\n if (!shouldUpdate) return nextSlide\n return {\n ...nextSlide,\n background: {\n ...(nextSlide.background ?? {}),\n type: nextSlide.background?.type ?? 'solid',\n color: nextBackground\n }\n }\n })\n\n return {\n ...deck,\n theme: {\n ...previousTheme,\n themeColors,\n fontColor: update.fontColor,\n backgroundColor: update.backgroundColor ?? previousTheme.backgroundColor\n },\n slides\n }\n}\n","import type { Deck, PptxCustomThemeInput } from '../types'\nimport { applyTheme2Json } from './theme-applier'\n\nexport function applyCustomTheme (\n deck: Deck,\n input: PptxCustomThemeInput\n): Deck {\n return applyTheme2Json(deck, input)\n}\n\nexport { applyTheme2Json }\n"],"mappings":"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","names":["r","g","b"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/custom-content/index.ts","../src/custom-content/parser.ts","../src/custom-content/html.ts","../src/custom-content/slide-appliers.ts","../src/custom-content/template-builder.ts","../src/custom-theme/index.ts","../src/custom-theme/color-utils.ts","../src/custom-theme/mappings.ts","../src/custom-theme/replacers.ts","../src/custom-theme/theme-applier.ts"],"sourcesContent":["import { applyCustomContent, parseCustomContent, applyCustomContentToTemplate } from './custom-content/index'\nimport { applyCustomTheme } from './custom-theme/index'\n\nexport {\n parseCustomContent,\n applyCustomContent,\n applyCustomContentToTemplate,\n\n applyCustomTheme,\n}\n\nexport type {\n CustomSlide,\n Deck,\n PptxCustomContentInput,\n PptxCustomOptions,\n PptxCustomThemeInput,\n TemplateJson,\n TemplateJsonElement,\n TemplateJsonSlide,\n TemplateJsonTheme\n} from './types'\n","import { parseDocument } from 'json2pptx-schema'\nimport type { PptxCustomContentInput, TemplateJson } from '../types'\nimport { parseCustomContent } from './parser'\nimport { applyCustomContentToTemplate } from './template-builder'\n\nexport function applyCustomContent (\n template: TemplateJson,\n input: PptxCustomContentInput\n): TemplateJson {\n const normalizedTemplate = parseDocument(template) as unknown as TemplateJson\n const CustomSlides = typeof input === 'string' ? parseCustomContent(input) : input\n const updated = applyCustomContentToTemplate(normalizedTemplate, CustomSlides)\n return parseDocument(updated) as unknown as TemplateJson\n}\n\nexport { parseCustomContent, applyCustomContentToTemplate }\n","import type { BackendContentItem, CustomSlide } from '../types'\n\ntype UnknownRecord = Record<string, unknown>\n\nconst isRecord = (value: unknown): value is UnknownRecord =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst asString = (value: unknown): string | null =>\n typeof value === 'string' ? value : null\n\nconst asStringArray = (value: unknown): string[] | null => {\n if (!Array.isArray(value)) return null\n const normalized = value\n .map(item => asString(item))\n .filter((item): item is string => item !== null)\n return normalized.length === value.length ? normalized : null\n}\n\nconst normalizeType = (value: unknown): CustomSlide['type'] | null => {\n const raw = asString(value)?.trim().toLowerCase()\n if (!raw) return null\n if (raw === 'agenda') return 'contents'\n if (raw === 'section') return 'transition'\n if (raw === 'ending') return 'end'\n if (\n raw === 'cover' ||\n raw === 'contents' ||\n raw === 'transition' ||\n raw === 'content' ||\n raw === 'end'\n ) {\n return raw\n }\n return null\n}\n\nconst normalizeContentItems = (value: unknown): BackendContentItem[] | null => {\n if (!Array.isArray(value)) return null\n const normalized: BackendContentItem[] = []\n for (const item of value) {\n if (!isRecord(item)) return null\n const title = asString(item.title)\n const text = asString(item.text)\n if (title == null || text == null) return null\n normalized.push({ title, text })\n }\n return normalized\n}\n\nconst normalizeSlide = (value: unknown): CustomSlide | null => {\n if (!isRecord(value)) return null\n const type = normalizeType(value.type)\n if (!type) return null\n\n const rawData = isRecord(value.data) ? value.data : {}\n\n if (type === 'cover') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'contents') {\n const items = asStringArray(rawData.items)\n if (!items) return null\n return { type, data: { items } }\n }\n\n if (type === 'transition') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'content') {\n const title = asString(rawData.title)\n const items = normalizeContentItems(rawData.items)\n if (title == null || !items) return null\n return { type, data: { title, items } }\n }\n\n return { type }\n}\n\nconst parseNdJsonSlides = (raw: string): unknown[] =>\n raw\n .split(/\\r?\\n/)\n .map(line => line.trim())\n .filter(Boolean)\n .map(line => JSON.parse(line) as unknown)\n\nconst parseStructuredSlides = (raw: string): unknown[] | null => {\n const trimmed = raw.trim()\n if (!trimmed) return []\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) return null\n\n let parsed: unknown\n try {\n parsed = JSON.parse(trimmed) as unknown\n } catch {\n return null\n }\n if (Array.isArray(parsed)) return parsed\n if (!isRecord(parsed)) return null\n if (Array.isArray(parsed.slides)) return parsed.slides\n if ('type' in parsed) return [parsed]\n return null\n}\n\nexport const parseCustomContent = (raw: string): CustomSlide[] => {\n const candidates = parseStructuredSlides(raw) ?? parseNdJsonSlides(raw)\n const slides = candidates\n .map(item => normalizeSlide(item))\n .filter((item): item is CustomSlide => item !== null)\n\n if (slides.length !== candidates.length) {\n throw new Error('Invalid custom content format')\n }\n return slides\n}\n","import type { TemplateJsonElement } from '../types'\n\nexport const updateHtmlContent = (html: string, text: string) => {\n if (typeof DOMParser === 'undefined') {\n return `<p>${text}</p>`\n }\n const parser = new DOMParser()\n const doc = parser.parseFromString(html, 'text/html')\n const spans = Array.from(doc.querySelectorAll('span'))\n if (spans.length > 0) {\n spans.forEach((span, index) => {\n span.textContent = index === 0 ? text : ''\n })\n } else {\n const paragraph = doc.querySelector('p')\n if (paragraph) {\n paragraph.textContent = text\n } else {\n doc.body.textContent = text\n }\n }\n return doc.body.innerHTML\n}\n\nexport const setElementText = (element: TemplateJsonElement, text: string) => {\n if (element.type !== 'text') return\n element.content = updateHtmlContent(element.content, text)\n}\n","import type {\n BackendContentData,\n BackendContentsData,\n BackendCoverData,\n BackendTransitionData,\n TemplateJsonSlide\n} from '../types'\nimport { setElementText, updateHtmlContent } from './html'\n\nfunction setShapeTextByType (\n slide: TemplateJsonSlide,\n textType: string,\n text: string\n): boolean {\n const shape = slide.elements.find((element) => {\n if (element.type !== 'shape') return false\n const maybeShape = element as unknown as {\n text?: { type?: string; content?: string }\n }\n return maybeShape.text?.type === textType\n })\n\n if (!shape) return false\n\n const shapeWithText = shape as unknown as {\n text?: { type?: string; content?: string }\n }\n if (!shapeWithText.text || typeof shapeWithText.text.content !== 'string') {\n return false\n }\n\n shapeWithText.text.content = updateHtmlContent(shapeWithText.text.content, text)\n return true\n}\n\nexport const applyCoverData = (slide: TemplateJsonSlide, data: BackendCoverData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n}\n\nexport const applyContentsData = (\n slide: TemplateJsonSlide,\n data: BackendContentsData\n) => {\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n items.forEach((element, index) => {\n const text = data.items[index]\n if (text) setElementText(element, text)\n })\n}\n\nexport const applyTransitionData = (\n slide: TemplateJsonSlide,\n data: BackendTransitionData,\n sectionIndex: number\n) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n const partNumber = slide.elements.find(\n element => element.type === 'text' && element.textType === 'partNumber'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n const formattedSectionIndex = `${sectionIndex}`.padStart(2, '0')\n if (partNumber) {\n setElementText(partNumber, formattedSectionIndex)\n } else {\n setShapeTextByType(slide, 'partNumber', formattedSectionIndex)\n }\n}\n\nexport const applyContentData = (slide: TemplateJsonSlide, data: BackendContentData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n if (title) setElementText(title, data.title)\n\n const itemTitles = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'itemTitle'\n )\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n\n data.items.forEach((item, index) => {\n const titleEl = itemTitles[index]\n const textEl = items[index]\n if (titleEl) setElementText(titleEl, item.title)\n if (textEl) setElementText(textEl, item.text)\n })\n}\n","import type { CustomSlide, TemplateJson, TemplateJsonSlide } from '../types'\nimport {\n applyContentData,\n applyContentsData,\n applyCoverData,\n applyTransitionData\n} from './slide-appliers'\n\nconst cloneSlide = (slide: TemplateJsonSlide): TemplateJsonSlide =>\n JSON.parse(JSON.stringify(slide)) as TemplateJsonSlide\n\nfunction normalizeLabel (value: string): string {\n return value\n .replace(/\\s+/g, ' ')\n .replace(/[,。、“”‘’:;!?【】()《》〈〉·,.:;!?()[\\]{}\"'`~\\-_/\\\\]/g, '')\n .trim()\n .toLowerCase()\n}\n\nfunction resolveTransitionIndex (\n customSlides: CustomSlide[],\n currentSlideIndex: number,\n transitionTitle: string,\n fallbackIndex: number\n): number {\n const normalizedTitle = normalizeLabel(transitionTitle)\n if (!normalizedTitle) return fallbackIndex\n\n const contentsItems = customSlides\n .slice(0, currentSlideIndex + 1)\n .filter((slide): slide is Extract<CustomSlide, { type: 'contents' }> => slide.type === 'contents')\n .flatMap(slide => slide.data.items)\n\n for (let index = 0; index < contentsItems.length; index += 1) {\n const normalizedItem = normalizeLabel(contentsItems[index])\n if (!normalizedItem) continue\n if (\n normalizedItem === normalizedTitle ||\n normalizedItem.includes(normalizedTitle) ||\n normalizedTitle.includes(normalizedItem)\n ) {\n return index + 1\n }\n }\n\n return fallbackIndex\n}\n\nexport const applyCustomContentToTemplate = (\n template: TemplateJson,\n CustomSlides: CustomSlide[]\n): TemplateJson => {\n const grouped = template.slides.reduce<Record<string, TemplateJsonSlide[]>>(\n (acc, slide) => {\n const key = slide.type || 'default'\n if (!acc[key]) acc[key] = []\n acc[key].push(slide)\n return acc\n },\n {}\n )\n\n const usage = new Map<string, number>()\n const getTextTypeCount = (slide: TemplateJsonSlide, textType: string) =>\n slide.elements.filter(\n element => element.type === 'text' && element.textType === textType\n ).length\n\n const getContentCapacity = (slide: TemplateJsonSlide) => {\n const titleSlots = getTextTypeCount(slide, 'itemTitle')\n const itemSlots = getTextTypeCount(slide, 'item')\n return Math.min(titleSlots, itemSlots)\n }\n\n const pickFromPool = (key: string, pool: TemplateJsonSlide[]) => {\n const index = usage.get(key) ?? 0\n usage.set(key, index + 1)\n return cloneSlide(pool[index % pool.length])\n }\n\n const pickSlide = (type: string, desiredCount?: number) => {\n const pool = grouped[type] || grouped.default || template.slides\n if (desiredCount == null || pool.length === 1) {\n return pickFromPool(type, pool)\n }\n\n const scored = pool.map(slide => {\n const capacity =\n type === 'content'\n ? getContentCapacity(slide)\n : getTextTypeCount(slide, 'item')\n return { slide, capacity }\n })\n const eligible = scored.filter(item => item.capacity >= desiredCount)\n if (eligible.length > 0) {\n const minCapacity = Math.min(...eligible.map(item => item.capacity))\n const best = eligible\n .filter(item => item.capacity === minCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, best)\n }\n const maxCapacity = Math.max(...scored.map(item => item.capacity))\n const fallback = scored\n .filter(item => item.capacity === maxCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, fallback)\n }\n\n let transitionIndex = 0\n const slides = CustomSlides.map((item, index) => {\n const desiredCount =\n item.type === 'contents'\n ? item.data.items.length\n : item.type === 'content'\n ? item.data.items.length\n : undefined\n const slide = pickSlide(item.type, desiredCount)\n if (item.type === 'cover') {\n applyCoverData(slide, item.data)\n } else if (item.type === 'contents') {\n applyContentsData(slide, item.data)\n } else if (item.type === 'transition') {\n transitionIndex += 1\n const partNumber = resolveTransitionIndex(\n CustomSlides,\n index,\n item.data.title,\n transitionIndex\n )\n applyTransitionData(slide, item.data, partNumber)\n } else if (item.type === 'content') {\n applyContentData(slide, item.data)\n }\n return slide\n })\n\n return {\n ...template,\n slides\n }\n}\n","import { parseDocument } from 'json2pptx-schema'\nimport type { Deck, PptxCustomThemeInput } from '../types'\nimport { applyTheme2Json } from './theme-applier'\n\nexport function applyCustomTheme (\n deck: Deck,\n input: PptxCustomThemeInput\n): Deck {\n const normalizedDeck = parseDocument(deck) as unknown as Deck\n const updated = applyTheme2Json(normalizedDeck, input)\n return parseDocument(updated) as unknown as Deck\n}\n\nexport { applyTheme2Json }\n","import type { ColorMapping, RGB } from './types'\n\nexport function normalizeHexColor (value: string): string | null {\n const raw = value.trim()\n const withHash = raw.startsWith('#') ? raw.slice(1) : raw\n if (withHash.length !== 3 && withHash.length !== 6) return null\n if (!/^[0-9a-fA-F]+$/.test(withHash)) return null\n const expanded =\n withHash.length === 3\n ? withHash\n .split('')\n .map((char) => char + char)\n .join('')\n : withHash\n return `#${expanded.toUpperCase()}`\n}\n\nexport function parseColorToRgb (\n value: string\n): (RGB & { alpha?: number }) | null {\n const hex = normalizeHexColor(value)\n if (hex) {\n const raw = hex.slice(1)\n const r = Number.parseInt(raw.slice(0, 2), 16)\n const g = Number.parseInt(raw.slice(2, 4), 16)\n const b = Number.parseInt(raw.slice(4, 6), 16)\n return { r, g, b }\n }\n\n const match = value.match(\n /rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)/i\n )\n if (!match) return null\n const r = Math.round(Number(match[1]))\n const g = Math.round(Number(match[2]))\n const b = Math.round(Number(match[3]))\n const alpha = match[4] !== undefined ? Number(match[4]) : undefined\n return {\n r,\n g,\n b,\n ...(Number.isFinite(alpha) ? { alpha } : {})\n }\n}\n\nexport function normalizeThemeColor (value: string): string | null {\n const hex = normalizeHexColor(value)\n if (hex) return hex\n const parsed = parseColorToRgb(value)\n if (!parsed) return null\n if (parsed.alpha !== undefined) {\n return `rgba(${parsed.r},${parsed.g},${parsed.b},${parsed.alpha})`\n }\n return `rgb(${parsed.r},${parsed.g},${parsed.b})`\n}\n\nexport function isPureColorString (value: string): boolean {\n const trimmed = value.trim()\n if (!trimmed) return false\n if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(trimmed)) return true\n return /^rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)$/i.test(\n trimmed\n )\n}\n\nfunction normalizeColorKey (value?: string): string | null {\n if (!value) return null\n const trimmed = value.trim()\n if (!trimmed) return null\n const parsed = parseColorToRgb(trimmed)\n if (parsed) {\n return `${parsed.r},${parsed.g},${parsed.b},${parsed.alpha ?? 'none'}`\n }\n const hex = normalizeHexColor(trimmed)\n if (hex) return hex\n return trimmed.toLowerCase()\n}\n\nexport function colorsEqual (a: string, b: string): boolean {\n const aKey = normalizeColorKey(a)\n const bKey = normalizeColorKey(b)\n if (!aKey || !bKey) return false\n return aKey === bKey\n}\n\nexport function isWhiteColor (value?: string): boolean {\n const key = normalizeColorKey(value)\n if (!key) return false\n return (\n key === '#FFFFFF' ||\n key === '255,255,255,none' ||\n key === '255,255,255,1'\n )\n}\n\nexport function rgbToString (rgb: RGB): string {\n return `rgb(${rgb.r},${rgb.g},${rgb.b})`\n}\n\nexport function findMappingForColor (\n value: string,\n mappings: ColorMapping[]\n): ColorMapping | undefined {\n const parsed = parseColorToRgb(value)\n if (!parsed) return undefined\n return mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n}\n","import { normalizeHexColor, parseColorToRgb } from './color-utils'\nimport type { ColorMapping } from './types'\n\nexport function buildColorMappings (\n previous: string[],\n next: string[]\n): ColorMapping[] {\n const mappings: ColorMapping[] = []\n const length = Math.min(previous.length, next.length)\n for (let i = 0; i < length; i += 1) {\n const fromParsed = parseColorToRgb(previous[i])\n const toParsed = parseColorToRgb(next[i])\n if (!fromParsed || !toParsed) continue\n const toHex = normalizeHexColor(next[i]) ?? undefined\n mappings.push({\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n })\n }\n return mappings\n}\n\nexport function buildSingleMapping (\n from?: string,\n to?: string\n): ColorMapping | null {\n if (!from || !to) return null\n const fromParsed = parseColorToRgb(from)\n const toParsed = parseColorToRgb(to)\n if (!fromParsed || !toParsed) return null\n const toHex = normalizeHexColor(to) ?? undefined\n return {\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n }\n}\n","import type { Slide, SlideElement } from '../types'\nimport {\n findMappingForColor,\n isPureColorString,\n normalizeThemeColor,\n parseColorToRgb,\n rgbToString\n} from './color-utils'\nimport type { ColorMapping } from './types'\n\nfunction applyFontColorToHtml (value: string, fontColor: string): string {\n if (!value || !fontColor) return value\n const normalized = normalizeThemeColor(fontColor) ?? fontColor\n const hasStyleColor = /\\bcolor\\s*:/i.test(value)\n if (hasStyleColor) {\n return value.replace(/color\\s*:\\s*([^;\"']+)/gi, () => `color: ${normalized}`)\n }\n return value.replace(\n /(<[^>]+style\\s*=\\s*[\"'])([^\"']*)([\"'])/gi,\n (_match, start, styles, end) => {\n if (/\\bcolor\\s*:/i.test(styles)) return _match\n const nextStyles = styles.trim()\n ? `${styles.trim()}; color: ${normalized}`\n : `color: ${normalized}`\n return `${start}${nextStyles}${end}`\n }\n )\n}\n\nfunction replaceColorValue (value: string, mappings: ColorMapping[]): string {\n const mapping = findMappingForColor(value, mappings)\n if (!mapping) return value\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n if (parsed.alpha !== undefined) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceRgbaString (value: string, mappings: ColorMapping[]): string {\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n const mapping = mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n if (!mapping) return value\n if (parsed.alpha !== undefined || value.toLowerCase().startsWith('rgba')) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha ?? 1})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceColorsInText (value: string, mappings: ColorMapping[]): string {\n let next = value\n next = next.replace(/#([0-9a-f]{3}|[0-9a-f]{6})/gi, (match) => {\n const mapping = findMappingForColor(match, mappings)\n if (!mapping) return match\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n })\n next = next.replace(/rgba?\\([^)]*\\)/gi, (match) =>\n replaceRgbaString(match, mappings)\n )\n return next\n}\n\nfunction replaceColorsDeep (value: unknown, mappings: ColorMapping[]): unknown {\n if (typeof value === 'string') {\n const trimmed = value.trim()\n const pureColor = isPureColorString(trimmed)\n if (pureColor) {\n const replaced = replaceColorValue(trimmed, mappings)\n return value === trimmed ? replaced : value.replace(trimmed, replaced)\n }\n return replaceColorsInText(value, mappings)\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => replaceColorsDeep(item, mappings))\n }\n\n if (value && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n const next: Record<string, unknown> = {}\n for (const [key, item] of entries) {\n next[key] = replaceColorsDeep(item, mappings)\n }\n return next\n }\n\n return value\n}\n\nfunction replaceTextElementColors (\n element: SlideElement,\n fontMappings: ColorMapping[],\n fontColor: string\n): SlideElement {\n const next = replaceColorsDeep(element, fontMappings) as SlideElement\n const normalizedFontColor = normalizeThemeColor(fontColor) ?? fontColor\n const withDefault =\n normalizedFontColor && 'defaultColor' in next\n ? { ...next, defaultColor: normalizedFontColor }\n : next\n if (!('content' in withDefault) || typeof withDefault.content !== 'string') {\n return withDefault\n }\n return {\n ...withDefault,\n content: applyFontColorToHtml(withDefault.content, normalizedFontColor)\n }\n}\n\nexport function replaceSlideColors (\n slide: Slide,\n themeMappings: ColorMapping[],\n fontMappings: ColorMapping[],\n fontColor: string\n): Slide {\n const { elements, ...rest } = slide\n const nextSlide = replaceColorsDeep(rest, themeMappings) as Slide\n if (!elements) return nextSlide\n\n const nextElements: SlideElement[] = elements.map((element) => {\n if (element && typeof element === 'object' && element.type === 'text') {\n return replaceTextElementColors(element, fontMappings, fontColor)\n }\n return replaceColorsDeep(element, themeMappings) as SlideElement\n })\n\n return { ...nextSlide, elements: nextElements }\n}\n","import type { Deck, PptxCustomThemeInput } from '../types'\nimport { colorsEqual, isWhiteColor } from './color-utils'\nimport { buildColorMappings, buildSingleMapping } from './mappings'\nimport { replaceSlideColors } from './replacers'\n\nexport function applyTheme2Json (deck: Deck, update: PptxCustomThemeInput): Deck {\n const previousTheme = deck.theme ?? {}\n const themeColors = update.themeColors.slice(0, 6)\n const themeMappings = buildColorMappings(\n previousTheme.themeColors ?? [],\n themeColors\n )\n const fontMapping = buildSingleMapping(\n previousTheme.fontColor,\n update.fontColor\n )\n const fontMappings = fontMapping ? [fontMapping] : []\n\n const nextBackground = update.backgroundColor ?? previousTheme.backgroundColor\n const prevBackground = previousTheme.backgroundColor\n const slides = deck.slides?.map((slide) => {\n const nextSlide = replaceSlideColors(\n slide,\n themeMappings,\n fontMappings,\n update.fontColor\n )\n if (!nextBackground) return nextSlide\n const currentColor = nextSlide.background?.color\n const shouldUpdate =\n !currentColor ||\n (prevBackground && colorsEqual(currentColor, prevBackground)) ||\n (!prevBackground && isWhiteColor(currentColor))\n if (!shouldUpdate) return nextSlide\n return {\n ...nextSlide,\n background: {\n ...(nextSlide.background ?? {}),\n type: nextSlide.background?.type ?? 'solid',\n color: nextBackground\n }\n }\n })\n\n return {\n ...deck,\n theme: {\n ...previousTheme,\n themeColors,\n fontColor: update.fontColor,\n backgroundColor: update.backgroundColor ?? previousTheme.backgroundColor\n },\n slides\n }\n}\n"],"mappings":"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","names":["import_json2pptx_schema","r","g","b"]}
package/dist/index.mjs CHANGED
@@ -1,3 +1,6 @@
1
+ // src/custom-content/index.ts
2
+ import { parseDocument } from "json2pptx-schema";
3
+
1
4
  // src/custom-content/parser.ts
2
5
  var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
3
6
  var asString = (value) => typeof value === "string" ? value : null;
@@ -113,6 +116,20 @@ var setElementText = (element, text) => {
113
116
  };
114
117
 
115
118
  // src/custom-content/slide-appliers.ts
119
+ function setShapeTextByType(slide, textType, text) {
120
+ const shape = slide.elements.find((element) => {
121
+ if (element.type !== "shape") return false;
122
+ const maybeShape = element;
123
+ return maybeShape.text?.type === textType;
124
+ });
125
+ if (!shape) return false;
126
+ const shapeWithText = shape;
127
+ if (!shapeWithText.text || typeof shapeWithText.text.content !== "string") {
128
+ return false;
129
+ }
130
+ shapeWithText.text.content = updateHtmlContent(shapeWithText.text.content, text);
131
+ return true;
132
+ }
116
133
  var applyCoverData = (slide, data) => {
117
134
  const title = slide.elements.find(
118
135
  (element) => element.type === "text" && element.textType === "title"
@@ -144,7 +161,12 @@ var applyTransitionData = (slide, data, sectionIndex) => {
144
161
  );
145
162
  if (title) setElementText(title, data.title);
146
163
  if (content) setElementText(content, data.text);
147
- if (partNumber) setElementText(partNumber, `${sectionIndex}`.padStart(2, "0"));
164
+ const formattedSectionIndex = `${sectionIndex}`.padStart(2, "0");
165
+ if (partNumber) {
166
+ setElementText(partNumber, formattedSectionIndex);
167
+ } else {
168
+ setShapeTextByType(slide, "partNumber", formattedSectionIndex);
169
+ }
148
170
  };
149
171
  var applyContentData = (slide, data) => {
150
172
  const title = slide.elements.find(
@@ -167,6 +189,22 @@ var applyContentData = (slide, data) => {
167
189
 
168
190
  // src/custom-content/template-builder.ts
169
191
  var cloneSlide = (slide) => JSON.parse(JSON.stringify(slide));
192
+ function normalizeLabel(value) {
193
+ return value.replace(/\s+/g, " ").replace(/[,。、“”‘’:;!?【】()《》〈〉·,.:;!?()[\]{}"'`~\-_/\\]/g, "").trim().toLowerCase();
194
+ }
195
+ function resolveTransitionIndex(customSlides, currentSlideIndex, transitionTitle, fallbackIndex) {
196
+ const normalizedTitle = normalizeLabel(transitionTitle);
197
+ if (!normalizedTitle) return fallbackIndex;
198
+ const contentsItems = customSlides.slice(0, currentSlideIndex + 1).filter((slide) => slide.type === "contents").flatMap((slide) => slide.data.items);
199
+ for (let index = 0; index < contentsItems.length; index += 1) {
200
+ const normalizedItem = normalizeLabel(contentsItems[index]);
201
+ if (!normalizedItem) continue;
202
+ if (normalizedItem === normalizedTitle || normalizedItem.includes(normalizedTitle) || normalizedTitle.includes(normalizedItem)) {
203
+ return index + 1;
204
+ }
205
+ }
206
+ return fallbackIndex;
207
+ }
170
208
  var applyCustomContentToTemplate = (template, CustomSlides) => {
171
209
  const grouped = template.slides.reduce(
172
210
  (acc, slide) => {
@@ -211,7 +249,7 @@ var applyCustomContentToTemplate = (template, CustomSlides) => {
211
249
  return pickFromPool(`${type}:${desiredCount}`, fallback);
212
250
  };
213
251
  let transitionIndex = 0;
214
- const slides = CustomSlides.map((item) => {
252
+ const slides = CustomSlides.map((item, index) => {
215
253
  const desiredCount = item.type === "contents" ? item.data.items.length : item.type === "content" ? item.data.items.length : void 0;
216
254
  const slide = pickSlide(item.type, desiredCount);
217
255
  if (item.type === "cover") {
@@ -220,7 +258,13 @@ var applyCustomContentToTemplate = (template, CustomSlides) => {
220
258
  applyContentsData(slide, item.data);
221
259
  } else if (item.type === "transition") {
222
260
  transitionIndex += 1;
223
- applyTransitionData(slide, item.data, transitionIndex);
261
+ const partNumber = resolveTransitionIndex(
262
+ CustomSlides,
263
+ index,
264
+ item.data.title,
265
+ transitionIndex
266
+ );
267
+ applyTransitionData(slide, item.data, partNumber);
224
268
  } else if (item.type === "content") {
225
269
  applyContentData(slide, item.data);
226
270
  }
@@ -234,10 +278,15 @@ var applyCustomContentToTemplate = (template, CustomSlides) => {
234
278
 
235
279
  // src/custom-content/index.ts
236
280
  function applyCustomContent(template, input) {
281
+ const normalizedTemplate = parseDocument(template);
237
282
  const CustomSlides = typeof input === "string" ? parseCustomContent(input) : input;
238
- return applyCustomContentToTemplate(template, CustomSlides);
283
+ const updated = applyCustomContentToTemplate(normalizedTemplate, CustomSlides);
284
+ return parseDocument(updated);
239
285
  }
240
286
 
287
+ // src/custom-theme/index.ts
288
+ import { parseDocument as parseDocument2 } from "json2pptx-schema";
289
+
241
290
  // src/custom-theme/color-utils.ts
242
291
  function normalizeHexColor(value) {
243
292
  const raw = value.trim();
@@ -502,7 +551,9 @@ function applyTheme2Json(deck, update) {
502
551
 
503
552
  // src/custom-theme/index.ts
504
553
  function applyCustomTheme(deck, input) {
505
- return applyTheme2Json(deck, input);
554
+ const normalizedDeck = parseDocument2(deck);
555
+ const updated = applyTheme2Json(normalizedDeck, input);
556
+ return parseDocument2(updated);
506
557
  }
507
558
  export {
508
559
  applyCustomContent,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/custom-content/parser.ts","../src/custom-content/html.ts","../src/custom-content/slide-appliers.ts","../src/custom-content/template-builder.ts","../src/custom-content/index.ts","../src/custom-theme/color-utils.ts","../src/custom-theme/mappings.ts","../src/custom-theme/replacers.ts","../src/custom-theme/theme-applier.ts","../src/custom-theme/index.ts"],"sourcesContent":["import type { BackendContentItem, CustomSlide } from '../types'\n\ntype UnknownRecord = Record<string, unknown>\n\nconst isRecord = (value: unknown): value is UnknownRecord =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst asString = (value: unknown): string | null =>\n typeof value === 'string' ? value : null\n\nconst asStringArray = (value: unknown): string[] | null => {\n if (!Array.isArray(value)) return null\n const normalized = value\n .map(item => asString(item))\n .filter((item): item is string => item !== null)\n return normalized.length === value.length ? normalized : null\n}\n\nconst normalizeType = (value: unknown): CustomSlide['type'] | null => {\n const raw = asString(value)?.trim().toLowerCase()\n if (!raw) return null\n if (raw === 'agenda') return 'contents'\n if (raw === 'section') return 'transition'\n if (raw === 'ending') return 'end'\n if (\n raw === 'cover' ||\n raw === 'contents' ||\n raw === 'transition' ||\n raw === 'content' ||\n raw === 'end'\n ) {\n return raw\n }\n return null\n}\n\nconst normalizeContentItems = (value: unknown): BackendContentItem[] | null => {\n if (!Array.isArray(value)) return null\n const normalized: BackendContentItem[] = []\n for (const item of value) {\n if (!isRecord(item)) return null\n const title = asString(item.title)\n const text = asString(item.text)\n if (title == null || text == null) return null\n normalized.push({ title, text })\n }\n return normalized\n}\n\nconst normalizeSlide = (value: unknown): CustomSlide | null => {\n if (!isRecord(value)) return null\n const type = normalizeType(value.type)\n if (!type) return null\n\n const rawData = isRecord(value.data) ? value.data : {}\n\n if (type === 'cover') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'contents') {\n const items = asStringArray(rawData.items)\n if (!items) return null\n return { type, data: { items } }\n }\n\n if (type === 'transition') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'content') {\n const title = asString(rawData.title)\n const items = normalizeContentItems(rawData.items)\n if (title == null || !items) return null\n return { type, data: { title, items } }\n }\n\n return { type }\n}\n\nconst parseNdJsonSlides = (raw: string): unknown[] =>\n raw\n .split(/\\r?\\n/)\n .map(line => line.trim())\n .filter(Boolean)\n .map(line => JSON.parse(line) as unknown)\n\nconst parseStructuredSlides = (raw: string): unknown[] | null => {\n const trimmed = raw.trim()\n if (!trimmed) return []\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) return null\n\n let parsed: unknown\n try {\n parsed = JSON.parse(trimmed) as unknown\n } catch {\n return null\n }\n if (Array.isArray(parsed)) return parsed\n if (!isRecord(parsed)) return null\n if (Array.isArray(parsed.slides)) return parsed.slides\n if ('type' in parsed) return [parsed]\n return null\n}\n\nexport const parseCustomContent = (raw: string): CustomSlide[] => {\n const candidates = parseStructuredSlides(raw) ?? parseNdJsonSlides(raw)\n const slides = candidates\n .map(item => normalizeSlide(item))\n .filter((item): item is CustomSlide => item !== null)\n\n if (slides.length !== candidates.length) {\n throw new Error('Invalid custom content format')\n }\n return slides\n}\n","import type { TemplateJsonElement } from '../types'\n\nexport const updateHtmlContent = (html: string, text: string) => {\n if (typeof DOMParser === 'undefined') {\n return `<p>${text}</p>`\n }\n const parser = new DOMParser()\n const doc = parser.parseFromString(html, 'text/html')\n const spans = Array.from(doc.querySelectorAll('span'))\n if (spans.length > 0) {\n spans.forEach((span, index) => {\n span.textContent = index === 0 ? text : ''\n })\n } else {\n const paragraph = doc.querySelector('p')\n if (paragraph) {\n paragraph.textContent = text\n } else {\n doc.body.textContent = text\n }\n }\n return doc.body.innerHTML\n}\n\nexport const setElementText = (element: TemplateJsonElement, text: string) => {\n if (element.type !== 'text') return\n element.content = updateHtmlContent(element.content, text)\n}\n","import type {\n BackendContentData,\n BackendContentsData,\n BackendCoverData,\n BackendTransitionData,\n TemplateJsonSlide\n} from '../types'\nimport { setElementText } from './html'\n\nexport const applyCoverData = (slide: TemplateJsonSlide, data: BackendCoverData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n}\n\nexport const applyContentsData = (\n slide: TemplateJsonSlide,\n data: BackendContentsData\n) => {\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n items.forEach((element, index) => {\n const text = data.items[index]\n if (text) setElementText(element, text)\n })\n}\n\nexport const applyTransitionData = (\n slide: TemplateJsonSlide,\n data: BackendTransitionData,\n sectionIndex: number\n) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n const partNumber = slide.elements.find(\n element => element.type === 'text' && element.textType === 'partNumber'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n if (partNumber) setElementText(partNumber, `${sectionIndex}`.padStart(2, '0'))\n}\n\nexport const applyContentData = (slide: TemplateJsonSlide, data: BackendContentData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n if (title) setElementText(title, data.title)\n\n const itemTitles = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'itemTitle'\n )\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n\n data.items.forEach((item, index) => {\n const titleEl = itemTitles[index]\n const textEl = items[index]\n if (titleEl) setElementText(titleEl, item.title)\n if (textEl) setElementText(textEl, item.text)\n })\n}\n","import type { CustomSlide, TemplateJson, TemplateJsonSlide } from '../types'\nimport {\n applyContentData,\n applyContentsData,\n applyCoverData,\n applyTransitionData\n} from './slide-appliers'\n\nconst cloneSlide = (slide: TemplateJsonSlide): TemplateJsonSlide =>\n JSON.parse(JSON.stringify(slide)) as TemplateJsonSlide\n\nexport const applyCustomContentToTemplate = (\n template: TemplateJson,\n CustomSlides: CustomSlide[]\n): TemplateJson => {\n const grouped = template.slides.reduce<Record<string, TemplateJsonSlide[]>>(\n (acc, slide) => {\n const key = slide.type || 'default'\n if (!acc[key]) acc[key] = []\n acc[key].push(slide)\n return acc\n },\n {}\n )\n\n const usage = new Map<string, number>()\n const getTextTypeCount = (slide: TemplateJsonSlide, textType: string) =>\n slide.elements.filter(\n element => element.type === 'text' && element.textType === textType\n ).length\n\n const getContentCapacity = (slide: TemplateJsonSlide) => {\n const titleSlots = getTextTypeCount(slide, 'itemTitle')\n const itemSlots = getTextTypeCount(slide, 'item')\n return Math.min(titleSlots, itemSlots)\n }\n\n const pickFromPool = (key: string, pool: TemplateJsonSlide[]) => {\n const index = usage.get(key) ?? 0\n usage.set(key, index + 1)\n return cloneSlide(pool[index % pool.length])\n }\n\n const pickSlide = (type: string, desiredCount?: number) => {\n const pool = grouped[type] || grouped.default || template.slides\n if (desiredCount == null || pool.length === 1) {\n return pickFromPool(type, pool)\n }\n\n const scored = pool.map(slide => {\n const capacity =\n type === 'content'\n ? getContentCapacity(slide)\n : getTextTypeCount(slide, 'item')\n return { slide, capacity }\n })\n const eligible = scored.filter(item => item.capacity >= desiredCount)\n if (eligible.length > 0) {\n const minCapacity = Math.min(...eligible.map(item => item.capacity))\n const best = eligible\n .filter(item => item.capacity === minCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, best)\n }\n const maxCapacity = Math.max(...scored.map(item => item.capacity))\n const fallback = scored\n .filter(item => item.capacity === maxCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, fallback)\n }\n\n let transitionIndex = 0\n const slides = CustomSlides.map(item => {\n const desiredCount =\n item.type === 'contents'\n ? item.data.items.length\n : item.type === 'content'\n ? item.data.items.length\n : undefined\n const slide = pickSlide(item.type, desiredCount)\n if (item.type === 'cover') {\n applyCoverData(slide, item.data)\n } else if (item.type === 'contents') {\n applyContentsData(slide, item.data)\n } else if (item.type === 'transition') {\n transitionIndex += 1\n applyTransitionData(slide, item.data, transitionIndex)\n } else if (item.type === 'content') {\n applyContentData(slide, item.data)\n }\n return slide\n })\n\n return {\n ...template,\n slides\n }\n}\n","import type { PptxCustomContentInput, TemplateJson } from '../types'\nimport { parseCustomContent } from './parser'\nimport { applyCustomContentToTemplate } from './template-builder'\n\nexport function applyCustomContent (\n template: TemplateJson,\n input: PptxCustomContentInput\n): TemplateJson {\n const CustomSlides = typeof input === 'string' ? parseCustomContent(input) : input\n return applyCustomContentToTemplate(template, CustomSlides)\n}\n\nexport { parseCustomContent, applyCustomContentToTemplate }\n","import type { ColorMapping, RGB } from './types'\n\nexport function normalizeHexColor (value: string): string | null {\n const raw = value.trim()\n const withHash = raw.startsWith('#') ? raw.slice(1) : raw\n if (withHash.length !== 3 && withHash.length !== 6) return null\n if (!/^[0-9a-fA-F]+$/.test(withHash)) return null\n const expanded =\n withHash.length === 3\n ? withHash\n .split('')\n .map((char) => char + char)\n .join('')\n : withHash\n return `#${expanded.toUpperCase()}`\n}\n\nexport function parseColorToRgb (\n value: string\n): (RGB & { alpha?: number }) | null {\n const hex = normalizeHexColor(value)\n if (hex) {\n const raw = hex.slice(1)\n const r = Number.parseInt(raw.slice(0, 2), 16)\n const g = Number.parseInt(raw.slice(2, 4), 16)\n const b = Number.parseInt(raw.slice(4, 6), 16)\n return { r, g, b }\n }\n\n const match = value.match(\n /rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)/i\n )\n if (!match) return null\n const r = Math.round(Number(match[1]))\n const g = Math.round(Number(match[2]))\n const b = Math.round(Number(match[3]))\n const alpha = match[4] !== undefined ? Number(match[4]) : undefined\n return {\n r,\n g,\n b,\n ...(Number.isFinite(alpha) ? { alpha } : {})\n }\n}\n\nexport function normalizeThemeColor (value: string): string | null {\n const hex = normalizeHexColor(value)\n if (hex) return hex\n const parsed = parseColorToRgb(value)\n if (!parsed) return null\n if (parsed.alpha !== undefined) {\n return `rgba(${parsed.r},${parsed.g},${parsed.b},${parsed.alpha})`\n }\n return `rgb(${parsed.r},${parsed.g},${parsed.b})`\n}\n\nexport function isPureColorString (value: string): boolean {\n const trimmed = value.trim()\n if (!trimmed) return false\n if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(trimmed)) return true\n return /^rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)$/i.test(\n trimmed\n )\n}\n\nfunction normalizeColorKey (value?: string): string | null {\n if (!value) return null\n const trimmed = value.trim()\n if (!trimmed) return null\n const parsed = parseColorToRgb(trimmed)\n if (parsed) {\n return `${parsed.r},${parsed.g},${parsed.b},${parsed.alpha ?? 'none'}`\n }\n const hex = normalizeHexColor(trimmed)\n if (hex) return hex\n return trimmed.toLowerCase()\n}\n\nexport function colorsEqual (a: string, b: string): boolean {\n const aKey = normalizeColorKey(a)\n const bKey = normalizeColorKey(b)\n if (!aKey || !bKey) return false\n return aKey === bKey\n}\n\nexport function isWhiteColor (value?: string): boolean {\n const key = normalizeColorKey(value)\n if (!key) return false\n return (\n key === '#FFFFFF' ||\n key === '255,255,255,none' ||\n key === '255,255,255,1'\n )\n}\n\nexport function rgbToString (rgb: RGB): string {\n return `rgb(${rgb.r},${rgb.g},${rgb.b})`\n}\n\nexport function findMappingForColor (\n value: string,\n mappings: ColorMapping[]\n): ColorMapping | undefined {\n const parsed = parseColorToRgb(value)\n if (!parsed) return undefined\n return mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n}\n","import { normalizeHexColor, parseColorToRgb } from './color-utils'\nimport type { ColorMapping } from './types'\n\nexport function buildColorMappings (\n previous: string[],\n next: string[]\n): ColorMapping[] {\n const mappings: ColorMapping[] = []\n const length = Math.min(previous.length, next.length)\n for (let i = 0; i < length; i += 1) {\n const fromParsed = parseColorToRgb(previous[i])\n const toParsed = parseColorToRgb(next[i])\n if (!fromParsed || !toParsed) continue\n const toHex = normalizeHexColor(next[i]) ?? undefined\n mappings.push({\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n })\n }\n return mappings\n}\n\nexport function buildSingleMapping (\n from?: string,\n to?: string\n): ColorMapping | null {\n if (!from || !to) return null\n const fromParsed = parseColorToRgb(from)\n const toParsed = parseColorToRgb(to)\n if (!fromParsed || !toParsed) return null\n const toHex = normalizeHexColor(to) ?? undefined\n return {\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n }\n}\n","import type { Slide, SlideElement } from '../types'\nimport {\n findMappingForColor,\n isPureColorString,\n normalizeThemeColor,\n parseColorToRgb,\n rgbToString\n} from './color-utils'\nimport type { ColorMapping } from './types'\n\nfunction applyFontColorToHtml (value: string, fontColor: string): string {\n if (!value || !fontColor) return value\n const normalized = normalizeThemeColor(fontColor) ?? fontColor\n const hasStyleColor = /\\bcolor\\s*:/i.test(value)\n if (hasStyleColor) {\n return value.replace(/color\\s*:\\s*([^;\"']+)/gi, () => `color: ${normalized}`)\n }\n return value.replace(\n /(<[^>]+style\\s*=\\s*[\"'])([^\"']*)([\"'])/gi,\n (_match, start, styles, end) => {\n if (/\\bcolor\\s*:/i.test(styles)) return _match\n const nextStyles = styles.trim()\n ? `${styles.trim()}; color: ${normalized}`\n : `color: ${normalized}`\n return `${start}${nextStyles}${end}`\n }\n )\n}\n\nfunction replaceColorValue (value: string, mappings: ColorMapping[]): string {\n const mapping = findMappingForColor(value, mappings)\n if (!mapping) return value\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n if (parsed.alpha !== undefined) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceRgbaString (value: string, mappings: ColorMapping[]): string {\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n const mapping = mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n if (!mapping) return value\n if (parsed.alpha !== undefined || value.toLowerCase().startsWith('rgba')) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha ?? 1})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceColorsInText (value: string, mappings: ColorMapping[]): string {\n let next = value\n next = next.replace(/#([0-9a-f]{3}|[0-9a-f]{6})/gi, (match) => {\n const mapping = findMappingForColor(match, mappings)\n if (!mapping) return match\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n })\n next = next.replace(/rgba?\\([^)]*\\)/gi, (match) =>\n replaceRgbaString(match, mappings)\n )\n return next\n}\n\nfunction replaceColorsDeep (value: unknown, mappings: ColorMapping[]): unknown {\n if (typeof value === 'string') {\n const trimmed = value.trim()\n const pureColor = isPureColorString(trimmed)\n if (pureColor) {\n const replaced = replaceColorValue(trimmed, mappings)\n return value === trimmed ? replaced : value.replace(trimmed, replaced)\n }\n return replaceColorsInText(value, mappings)\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => replaceColorsDeep(item, mappings))\n }\n\n if (value && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n const next: Record<string, unknown> = {}\n for (const [key, item] of entries) {\n next[key] = replaceColorsDeep(item, mappings)\n }\n return next\n }\n\n return value\n}\n\nfunction replaceTextElementColors (\n element: SlideElement,\n fontMappings: ColorMapping[],\n fontColor: string\n): SlideElement {\n const next = replaceColorsDeep(element, fontMappings) as SlideElement\n const normalizedFontColor = normalizeThemeColor(fontColor) ?? fontColor\n const withDefault =\n normalizedFontColor && 'defaultColor' in next\n ? { ...next, defaultColor: normalizedFontColor }\n : next\n if (!('content' in withDefault) || typeof withDefault.content !== 'string') {\n return withDefault\n }\n return {\n ...withDefault,\n content: applyFontColorToHtml(withDefault.content, normalizedFontColor)\n }\n}\n\nexport function replaceSlideColors (\n slide: Slide,\n themeMappings: ColorMapping[],\n fontMappings: ColorMapping[],\n fontColor: string\n): Slide {\n const { elements, ...rest } = slide\n const nextSlide = replaceColorsDeep(rest, themeMappings) as Slide\n if (!elements) return nextSlide\n\n const nextElements: SlideElement[] = elements.map((element) => {\n if (element && typeof element === 'object' && element.type === 'text') {\n return replaceTextElementColors(element, fontMappings, fontColor)\n }\n return replaceColorsDeep(element, themeMappings) as SlideElement\n })\n\n return { ...nextSlide, elements: nextElements }\n}\n","import type { Deck, PptxCustomThemeInput } from '../types'\nimport { colorsEqual, isWhiteColor } from './color-utils'\nimport { buildColorMappings, buildSingleMapping } from './mappings'\nimport { replaceSlideColors } from './replacers'\n\nexport function applyTheme2Json (deck: Deck, update: PptxCustomThemeInput): Deck {\n const previousTheme = deck.theme ?? {}\n const themeColors = update.themeColors.slice(0, 6)\n const themeMappings = buildColorMappings(\n previousTheme.themeColors ?? [],\n themeColors\n )\n const fontMapping = buildSingleMapping(\n previousTheme.fontColor,\n update.fontColor\n )\n const fontMappings = fontMapping ? [fontMapping] : []\n\n const nextBackground = update.backgroundColor ?? previousTheme.backgroundColor\n const prevBackground = previousTheme.backgroundColor\n const slides = deck.slides?.map((slide) => {\n const nextSlide = replaceSlideColors(\n slide,\n themeMappings,\n fontMappings,\n update.fontColor\n )\n if (!nextBackground) return nextSlide\n const currentColor = nextSlide.background?.color\n const shouldUpdate =\n !currentColor ||\n (prevBackground && colorsEqual(currentColor, prevBackground)) ||\n (!prevBackground && isWhiteColor(currentColor))\n if (!shouldUpdate) return nextSlide\n return {\n ...nextSlide,\n background: {\n ...(nextSlide.background ?? {}),\n type: nextSlide.background?.type ?? 'solid',\n color: nextBackground\n }\n }\n })\n\n return {\n ...deck,\n theme: {\n ...previousTheme,\n themeColors,\n fontColor: update.fontColor,\n backgroundColor: update.backgroundColor ?? previousTheme.backgroundColor\n },\n slides\n }\n}\n","import type { Deck, PptxCustomThemeInput } from '../types'\nimport { applyTheme2Json } from './theme-applier'\n\nexport function applyCustomTheme (\n deck: Deck,\n input: PptxCustomThemeInput\n): Deck {\n return applyTheme2Json(deck, input)\n}\n\nexport { applyTheme2Json }\n"],"mappings":"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","names":["r","g","b"]}
1
+ {"version":3,"sources":["../src/custom-content/index.ts","../src/custom-content/parser.ts","../src/custom-content/html.ts","../src/custom-content/slide-appliers.ts","../src/custom-content/template-builder.ts","../src/custom-theme/index.ts","../src/custom-theme/color-utils.ts","../src/custom-theme/mappings.ts","../src/custom-theme/replacers.ts","../src/custom-theme/theme-applier.ts"],"sourcesContent":["import { parseDocument } from 'json2pptx-schema'\nimport type { PptxCustomContentInput, TemplateJson } from '../types'\nimport { parseCustomContent } from './parser'\nimport { applyCustomContentToTemplate } from './template-builder'\n\nexport function applyCustomContent (\n template: TemplateJson,\n input: PptxCustomContentInput\n): TemplateJson {\n const normalizedTemplate = parseDocument(template) as unknown as TemplateJson\n const CustomSlides = typeof input === 'string' ? parseCustomContent(input) : input\n const updated = applyCustomContentToTemplate(normalizedTemplate, CustomSlides)\n return parseDocument(updated) as unknown as TemplateJson\n}\n\nexport { parseCustomContent, applyCustomContentToTemplate }\n","import type { BackendContentItem, CustomSlide } from '../types'\n\ntype UnknownRecord = Record<string, unknown>\n\nconst isRecord = (value: unknown): value is UnknownRecord =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst asString = (value: unknown): string | null =>\n typeof value === 'string' ? value : null\n\nconst asStringArray = (value: unknown): string[] | null => {\n if (!Array.isArray(value)) return null\n const normalized = value\n .map(item => asString(item))\n .filter((item): item is string => item !== null)\n return normalized.length === value.length ? normalized : null\n}\n\nconst normalizeType = (value: unknown): CustomSlide['type'] | null => {\n const raw = asString(value)?.trim().toLowerCase()\n if (!raw) return null\n if (raw === 'agenda') return 'contents'\n if (raw === 'section') return 'transition'\n if (raw === 'ending') return 'end'\n if (\n raw === 'cover' ||\n raw === 'contents' ||\n raw === 'transition' ||\n raw === 'content' ||\n raw === 'end'\n ) {\n return raw\n }\n return null\n}\n\nconst normalizeContentItems = (value: unknown): BackendContentItem[] | null => {\n if (!Array.isArray(value)) return null\n const normalized: BackendContentItem[] = []\n for (const item of value) {\n if (!isRecord(item)) return null\n const title = asString(item.title)\n const text = asString(item.text)\n if (title == null || text == null) return null\n normalized.push({ title, text })\n }\n return normalized\n}\n\nconst normalizeSlide = (value: unknown): CustomSlide | null => {\n if (!isRecord(value)) return null\n const type = normalizeType(value.type)\n if (!type) return null\n\n const rawData = isRecord(value.data) ? value.data : {}\n\n if (type === 'cover') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'contents') {\n const items = asStringArray(rawData.items)\n if (!items) return null\n return { type, data: { items } }\n }\n\n if (type === 'transition') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'content') {\n const title = asString(rawData.title)\n const items = normalizeContentItems(rawData.items)\n if (title == null || !items) return null\n return { type, data: { title, items } }\n }\n\n return { type }\n}\n\nconst parseNdJsonSlides = (raw: string): unknown[] =>\n raw\n .split(/\\r?\\n/)\n .map(line => line.trim())\n .filter(Boolean)\n .map(line => JSON.parse(line) as unknown)\n\nconst parseStructuredSlides = (raw: string): unknown[] | null => {\n const trimmed = raw.trim()\n if (!trimmed) return []\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) return null\n\n let parsed: unknown\n try {\n parsed = JSON.parse(trimmed) as unknown\n } catch {\n return null\n }\n if (Array.isArray(parsed)) return parsed\n if (!isRecord(parsed)) return null\n if (Array.isArray(parsed.slides)) return parsed.slides\n if ('type' in parsed) return [parsed]\n return null\n}\n\nexport const parseCustomContent = (raw: string): CustomSlide[] => {\n const candidates = parseStructuredSlides(raw) ?? parseNdJsonSlides(raw)\n const slides = candidates\n .map(item => normalizeSlide(item))\n .filter((item): item is CustomSlide => item !== null)\n\n if (slides.length !== candidates.length) {\n throw new Error('Invalid custom content format')\n }\n return slides\n}\n","import type { TemplateJsonElement } from '../types'\n\nexport const updateHtmlContent = (html: string, text: string) => {\n if (typeof DOMParser === 'undefined') {\n return `<p>${text}</p>`\n }\n const parser = new DOMParser()\n const doc = parser.parseFromString(html, 'text/html')\n const spans = Array.from(doc.querySelectorAll('span'))\n if (spans.length > 0) {\n spans.forEach((span, index) => {\n span.textContent = index === 0 ? text : ''\n })\n } else {\n const paragraph = doc.querySelector('p')\n if (paragraph) {\n paragraph.textContent = text\n } else {\n doc.body.textContent = text\n }\n }\n return doc.body.innerHTML\n}\n\nexport const setElementText = (element: TemplateJsonElement, text: string) => {\n if (element.type !== 'text') return\n element.content = updateHtmlContent(element.content, text)\n}\n","import type {\n BackendContentData,\n BackendContentsData,\n BackendCoverData,\n BackendTransitionData,\n TemplateJsonSlide\n} from '../types'\nimport { setElementText, updateHtmlContent } from './html'\n\nfunction setShapeTextByType (\n slide: TemplateJsonSlide,\n textType: string,\n text: string\n): boolean {\n const shape = slide.elements.find((element) => {\n if (element.type !== 'shape') return false\n const maybeShape = element as unknown as {\n text?: { type?: string; content?: string }\n }\n return maybeShape.text?.type === textType\n })\n\n if (!shape) return false\n\n const shapeWithText = shape as unknown as {\n text?: { type?: string; content?: string }\n }\n if (!shapeWithText.text || typeof shapeWithText.text.content !== 'string') {\n return false\n }\n\n shapeWithText.text.content = updateHtmlContent(shapeWithText.text.content, text)\n return true\n}\n\nexport const applyCoverData = (slide: TemplateJsonSlide, data: BackendCoverData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n}\n\nexport const applyContentsData = (\n slide: TemplateJsonSlide,\n data: BackendContentsData\n) => {\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n items.forEach((element, index) => {\n const text = data.items[index]\n if (text) setElementText(element, text)\n })\n}\n\nexport const applyTransitionData = (\n slide: TemplateJsonSlide,\n data: BackendTransitionData,\n sectionIndex: number\n) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n const partNumber = slide.elements.find(\n element => element.type === 'text' && element.textType === 'partNumber'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n const formattedSectionIndex = `${sectionIndex}`.padStart(2, '0')\n if (partNumber) {\n setElementText(partNumber, formattedSectionIndex)\n } else {\n setShapeTextByType(slide, 'partNumber', formattedSectionIndex)\n }\n}\n\nexport const applyContentData = (slide: TemplateJsonSlide, data: BackendContentData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n if (title) setElementText(title, data.title)\n\n const itemTitles = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'itemTitle'\n )\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n\n data.items.forEach((item, index) => {\n const titleEl = itemTitles[index]\n const textEl = items[index]\n if (titleEl) setElementText(titleEl, item.title)\n if (textEl) setElementText(textEl, item.text)\n })\n}\n","import type { CustomSlide, TemplateJson, TemplateJsonSlide } from '../types'\nimport {\n applyContentData,\n applyContentsData,\n applyCoverData,\n applyTransitionData\n} from './slide-appliers'\n\nconst cloneSlide = (slide: TemplateJsonSlide): TemplateJsonSlide =>\n JSON.parse(JSON.stringify(slide)) as TemplateJsonSlide\n\nfunction normalizeLabel (value: string): string {\n return value\n .replace(/\\s+/g, ' ')\n .replace(/[,。、“”‘’:;!?【】()《》〈〉·,.:;!?()[\\]{}\"'`~\\-_/\\\\]/g, '')\n .trim()\n .toLowerCase()\n}\n\nfunction resolveTransitionIndex (\n customSlides: CustomSlide[],\n currentSlideIndex: number,\n transitionTitle: string,\n fallbackIndex: number\n): number {\n const normalizedTitle = normalizeLabel(transitionTitle)\n if (!normalizedTitle) return fallbackIndex\n\n const contentsItems = customSlides\n .slice(0, currentSlideIndex + 1)\n .filter((slide): slide is Extract<CustomSlide, { type: 'contents' }> => slide.type === 'contents')\n .flatMap(slide => slide.data.items)\n\n for (let index = 0; index < contentsItems.length; index += 1) {\n const normalizedItem = normalizeLabel(contentsItems[index])\n if (!normalizedItem) continue\n if (\n normalizedItem === normalizedTitle ||\n normalizedItem.includes(normalizedTitle) ||\n normalizedTitle.includes(normalizedItem)\n ) {\n return index + 1\n }\n }\n\n return fallbackIndex\n}\n\nexport const applyCustomContentToTemplate = (\n template: TemplateJson,\n CustomSlides: CustomSlide[]\n): TemplateJson => {\n const grouped = template.slides.reduce<Record<string, TemplateJsonSlide[]>>(\n (acc, slide) => {\n const key = slide.type || 'default'\n if (!acc[key]) acc[key] = []\n acc[key].push(slide)\n return acc\n },\n {}\n )\n\n const usage = new Map<string, number>()\n const getTextTypeCount = (slide: TemplateJsonSlide, textType: string) =>\n slide.elements.filter(\n element => element.type === 'text' && element.textType === textType\n ).length\n\n const getContentCapacity = (slide: TemplateJsonSlide) => {\n const titleSlots = getTextTypeCount(slide, 'itemTitle')\n const itemSlots = getTextTypeCount(slide, 'item')\n return Math.min(titleSlots, itemSlots)\n }\n\n const pickFromPool = (key: string, pool: TemplateJsonSlide[]) => {\n const index = usage.get(key) ?? 0\n usage.set(key, index + 1)\n return cloneSlide(pool[index % pool.length])\n }\n\n const pickSlide = (type: string, desiredCount?: number) => {\n const pool = grouped[type] || grouped.default || template.slides\n if (desiredCount == null || pool.length === 1) {\n return pickFromPool(type, pool)\n }\n\n const scored = pool.map(slide => {\n const capacity =\n type === 'content'\n ? getContentCapacity(slide)\n : getTextTypeCount(slide, 'item')\n return { slide, capacity }\n })\n const eligible = scored.filter(item => item.capacity >= desiredCount)\n if (eligible.length > 0) {\n const minCapacity = Math.min(...eligible.map(item => item.capacity))\n const best = eligible\n .filter(item => item.capacity === minCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, best)\n }\n const maxCapacity = Math.max(...scored.map(item => item.capacity))\n const fallback = scored\n .filter(item => item.capacity === maxCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, fallback)\n }\n\n let transitionIndex = 0\n const slides = CustomSlides.map((item, index) => {\n const desiredCount =\n item.type === 'contents'\n ? item.data.items.length\n : item.type === 'content'\n ? item.data.items.length\n : undefined\n const slide = pickSlide(item.type, desiredCount)\n if (item.type === 'cover') {\n applyCoverData(slide, item.data)\n } else if (item.type === 'contents') {\n applyContentsData(slide, item.data)\n } else if (item.type === 'transition') {\n transitionIndex += 1\n const partNumber = resolveTransitionIndex(\n CustomSlides,\n index,\n item.data.title,\n transitionIndex\n )\n applyTransitionData(slide, item.data, partNumber)\n } else if (item.type === 'content') {\n applyContentData(slide, item.data)\n }\n return slide\n })\n\n return {\n ...template,\n slides\n }\n}\n","import { parseDocument } from 'json2pptx-schema'\nimport type { Deck, PptxCustomThemeInput } from '../types'\nimport { applyTheme2Json } from './theme-applier'\n\nexport function applyCustomTheme (\n deck: Deck,\n input: PptxCustomThemeInput\n): Deck {\n const normalizedDeck = parseDocument(deck) as unknown as Deck\n const updated = applyTheme2Json(normalizedDeck, input)\n return parseDocument(updated) as unknown as Deck\n}\n\nexport { applyTheme2Json }\n","import type { ColorMapping, RGB } from './types'\n\nexport function normalizeHexColor (value: string): string | null {\n const raw = value.trim()\n const withHash = raw.startsWith('#') ? raw.slice(1) : raw\n if (withHash.length !== 3 && withHash.length !== 6) return null\n if (!/^[0-9a-fA-F]+$/.test(withHash)) return null\n const expanded =\n withHash.length === 3\n ? withHash\n .split('')\n .map((char) => char + char)\n .join('')\n : withHash\n return `#${expanded.toUpperCase()}`\n}\n\nexport function parseColorToRgb (\n value: string\n): (RGB & { alpha?: number }) | null {\n const hex = normalizeHexColor(value)\n if (hex) {\n const raw = hex.slice(1)\n const r = Number.parseInt(raw.slice(0, 2), 16)\n const g = Number.parseInt(raw.slice(2, 4), 16)\n const b = Number.parseInt(raw.slice(4, 6), 16)\n return { r, g, b }\n }\n\n const match = value.match(\n /rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)/i\n )\n if (!match) return null\n const r = Math.round(Number(match[1]))\n const g = Math.round(Number(match[2]))\n const b = Math.round(Number(match[3]))\n const alpha = match[4] !== undefined ? Number(match[4]) : undefined\n return {\n r,\n g,\n b,\n ...(Number.isFinite(alpha) ? { alpha } : {})\n }\n}\n\nexport function normalizeThemeColor (value: string): string | null {\n const hex = normalizeHexColor(value)\n if (hex) return hex\n const parsed = parseColorToRgb(value)\n if (!parsed) return null\n if (parsed.alpha !== undefined) {\n return `rgba(${parsed.r},${parsed.g},${parsed.b},${parsed.alpha})`\n }\n return `rgb(${parsed.r},${parsed.g},${parsed.b})`\n}\n\nexport function isPureColorString (value: string): boolean {\n const trimmed = value.trim()\n if (!trimmed) return false\n if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(trimmed)) return true\n return /^rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)$/i.test(\n trimmed\n )\n}\n\nfunction normalizeColorKey (value?: string): string | null {\n if (!value) return null\n const trimmed = value.trim()\n if (!trimmed) return null\n const parsed = parseColorToRgb(trimmed)\n if (parsed) {\n return `${parsed.r},${parsed.g},${parsed.b},${parsed.alpha ?? 'none'}`\n }\n const hex = normalizeHexColor(trimmed)\n if (hex) return hex\n return trimmed.toLowerCase()\n}\n\nexport function colorsEqual (a: string, b: string): boolean {\n const aKey = normalizeColorKey(a)\n const bKey = normalizeColorKey(b)\n if (!aKey || !bKey) return false\n return aKey === bKey\n}\n\nexport function isWhiteColor (value?: string): boolean {\n const key = normalizeColorKey(value)\n if (!key) return false\n return (\n key === '#FFFFFF' ||\n key === '255,255,255,none' ||\n key === '255,255,255,1'\n )\n}\n\nexport function rgbToString (rgb: RGB): string {\n return `rgb(${rgb.r},${rgb.g},${rgb.b})`\n}\n\nexport function findMappingForColor (\n value: string,\n mappings: ColorMapping[]\n): ColorMapping | undefined {\n const parsed = parseColorToRgb(value)\n if (!parsed) return undefined\n return mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n}\n","import { normalizeHexColor, parseColorToRgb } from './color-utils'\nimport type { ColorMapping } from './types'\n\nexport function buildColorMappings (\n previous: string[],\n next: string[]\n): ColorMapping[] {\n const mappings: ColorMapping[] = []\n const length = Math.min(previous.length, next.length)\n for (let i = 0; i < length; i += 1) {\n const fromParsed = parseColorToRgb(previous[i])\n const toParsed = parseColorToRgb(next[i])\n if (!fromParsed || !toParsed) continue\n const toHex = normalizeHexColor(next[i]) ?? undefined\n mappings.push({\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n })\n }\n return mappings\n}\n\nexport function buildSingleMapping (\n from?: string,\n to?: string\n): ColorMapping | null {\n if (!from || !to) return null\n const fromParsed = parseColorToRgb(from)\n const toParsed = parseColorToRgb(to)\n if (!fromParsed || !toParsed) return null\n const toHex = normalizeHexColor(to) ?? undefined\n return {\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n }\n}\n","import type { Slide, SlideElement } from '../types'\nimport {\n findMappingForColor,\n isPureColorString,\n normalizeThemeColor,\n parseColorToRgb,\n rgbToString\n} from './color-utils'\nimport type { ColorMapping } from './types'\n\nfunction applyFontColorToHtml (value: string, fontColor: string): string {\n if (!value || !fontColor) return value\n const normalized = normalizeThemeColor(fontColor) ?? fontColor\n const hasStyleColor = /\\bcolor\\s*:/i.test(value)\n if (hasStyleColor) {\n return value.replace(/color\\s*:\\s*([^;\"']+)/gi, () => `color: ${normalized}`)\n }\n return value.replace(\n /(<[^>]+style\\s*=\\s*[\"'])([^\"']*)([\"'])/gi,\n (_match, start, styles, end) => {\n if (/\\bcolor\\s*:/i.test(styles)) return _match\n const nextStyles = styles.trim()\n ? `${styles.trim()}; color: ${normalized}`\n : `color: ${normalized}`\n return `${start}${nextStyles}${end}`\n }\n )\n}\n\nfunction replaceColorValue (value: string, mappings: ColorMapping[]): string {\n const mapping = findMappingForColor(value, mappings)\n if (!mapping) return value\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n if (parsed.alpha !== undefined) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceRgbaString (value: string, mappings: ColorMapping[]): string {\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n const mapping = mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n if (!mapping) return value\n if (parsed.alpha !== undefined || value.toLowerCase().startsWith('rgba')) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha ?? 1})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceColorsInText (value: string, mappings: ColorMapping[]): string {\n let next = value\n next = next.replace(/#([0-9a-f]{3}|[0-9a-f]{6})/gi, (match) => {\n const mapping = findMappingForColor(match, mappings)\n if (!mapping) return match\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n })\n next = next.replace(/rgba?\\([^)]*\\)/gi, (match) =>\n replaceRgbaString(match, mappings)\n )\n return next\n}\n\nfunction replaceColorsDeep (value: unknown, mappings: ColorMapping[]): unknown {\n if (typeof value === 'string') {\n const trimmed = value.trim()\n const pureColor = isPureColorString(trimmed)\n if (pureColor) {\n const replaced = replaceColorValue(trimmed, mappings)\n return value === trimmed ? replaced : value.replace(trimmed, replaced)\n }\n return replaceColorsInText(value, mappings)\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => replaceColorsDeep(item, mappings))\n }\n\n if (value && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n const next: Record<string, unknown> = {}\n for (const [key, item] of entries) {\n next[key] = replaceColorsDeep(item, mappings)\n }\n return next\n }\n\n return value\n}\n\nfunction replaceTextElementColors (\n element: SlideElement,\n fontMappings: ColorMapping[],\n fontColor: string\n): SlideElement {\n const next = replaceColorsDeep(element, fontMappings) as SlideElement\n const normalizedFontColor = normalizeThemeColor(fontColor) ?? fontColor\n const withDefault =\n normalizedFontColor && 'defaultColor' in next\n ? { ...next, defaultColor: normalizedFontColor }\n : next\n if (!('content' in withDefault) || typeof withDefault.content !== 'string') {\n return withDefault\n }\n return {\n ...withDefault,\n content: applyFontColorToHtml(withDefault.content, normalizedFontColor)\n }\n}\n\nexport function replaceSlideColors (\n slide: Slide,\n themeMappings: ColorMapping[],\n fontMappings: ColorMapping[],\n fontColor: string\n): Slide {\n const { elements, ...rest } = slide\n const nextSlide = replaceColorsDeep(rest, themeMappings) as Slide\n if (!elements) return nextSlide\n\n const nextElements: SlideElement[] = elements.map((element) => {\n if (element && typeof element === 'object' && element.type === 'text') {\n return replaceTextElementColors(element, fontMappings, fontColor)\n }\n return replaceColorsDeep(element, themeMappings) as SlideElement\n })\n\n return { ...nextSlide, elements: nextElements }\n}\n","import type { Deck, PptxCustomThemeInput } from '../types'\nimport { colorsEqual, isWhiteColor } from './color-utils'\nimport { buildColorMappings, buildSingleMapping } from './mappings'\nimport { replaceSlideColors } from './replacers'\n\nexport function applyTheme2Json (deck: Deck, update: PptxCustomThemeInput): Deck {\n const previousTheme = deck.theme ?? {}\n const themeColors = update.themeColors.slice(0, 6)\n const themeMappings = buildColorMappings(\n previousTheme.themeColors ?? [],\n themeColors\n )\n const fontMapping = buildSingleMapping(\n previousTheme.fontColor,\n update.fontColor\n )\n const fontMappings = fontMapping ? [fontMapping] : []\n\n const nextBackground = update.backgroundColor ?? previousTheme.backgroundColor\n const prevBackground = previousTheme.backgroundColor\n const slides = deck.slides?.map((slide) => {\n const nextSlide = replaceSlideColors(\n slide,\n themeMappings,\n fontMappings,\n update.fontColor\n )\n if (!nextBackground) return nextSlide\n const currentColor = nextSlide.background?.color\n const shouldUpdate =\n !currentColor ||\n (prevBackground && colorsEqual(currentColor, prevBackground)) ||\n (!prevBackground && isWhiteColor(currentColor))\n if (!shouldUpdate) return nextSlide\n return {\n ...nextSlide,\n background: {\n ...(nextSlide.background ?? {}),\n type: nextSlide.background?.type ?? 'solid',\n color: nextBackground\n }\n }\n })\n\n return {\n ...deck,\n theme: {\n ...previousTheme,\n themeColors,\n fontColor: update.fontColor,\n backgroundColor: update.backgroundColor ?? previousTheme.backgroundColor\n },\n slides\n }\n}\n"],"mappings":"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","names":["parseDocument","r","g","b","parseDocument"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pptx-custom",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Custom content and theme utilities for PPTX JSON templates.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.cjs",
@@ -33,11 +33,15 @@
33
33
  "sideEffects": false,
34
34
  "scripts": {
35
35
  "build": "tsup",
36
+ "dev:watch": "tsup --watch",
36
37
  "typecheck": "tsc -p tsconfig.json --noEmit",
37
38
  "prepublishOnly": "pnpm run build"
38
39
  },
40
+ "dependencies": {
41
+ "json2pptx-schema": "0.1.0"
42
+ },
39
43
  "devDependencies": {
40
44
  "tsup": "^8.5.1",
41
45
  "typescript": "^5.6.3"
42
46
  }
43
- }
47
+ }