pptx-custom 0.1.3 → 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;
@@ -304,10 +307,15 @@ var applyCustomContentToTemplate = (template, CustomSlides) => {
304
307
 
305
308
  // src/custom-content/index.ts
306
309
  function applyCustomContent(template, input) {
310
+ const normalizedTemplate = (0, import_json2pptx_schema.parseDocument)(template);
307
311
  const CustomSlides = typeof input === "string" ? parseCustomContent(input) : input;
308
- return applyCustomContentToTemplate(template, CustomSlides);
312
+ const updated = applyCustomContentToTemplate(normalizedTemplate, CustomSlides);
313
+ return (0, import_json2pptx_schema.parseDocument)(updated);
309
314
  }
310
315
 
316
+ // src/custom-theme/index.ts
317
+ var import_json2pptx_schema2 = require("json2pptx-schema");
318
+
311
319
  // src/custom-theme/color-utils.ts
312
320
  function normalizeHexColor(value) {
313
321
  const raw = value.trim();
@@ -572,7 +580,9 @@ function applyTheme2Json(deck, update) {
572
580
 
573
581
  // src/custom-theme/index.ts
574
582
  function applyCustomTheme(deck, input) {
575
- 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);
576
586
  }
577
587
  // Annotate the CommonJS export names for ESM import in node:
578
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, 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 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;
@@ -275,10 +278,15 @@ var applyCustomContentToTemplate = (template, CustomSlides) => {
275
278
 
276
279
  // src/custom-content/index.ts
277
280
  function applyCustomContent(template, input) {
281
+ const normalizedTemplate = parseDocument(template);
278
282
  const CustomSlides = typeof input === "string" ? parseCustomContent(input) : input;
279
- return applyCustomContentToTemplate(template, CustomSlides);
283
+ const updated = applyCustomContentToTemplate(normalizedTemplate, CustomSlides);
284
+ return parseDocument(updated);
280
285
  }
281
286
 
287
+ // src/custom-theme/index.ts
288
+ import { parseDocument as parseDocument2 } from "json2pptx-schema";
289
+
282
290
  // src/custom-theme/color-utils.ts
283
291
  function normalizeHexColor(value) {
284
292
  const raw = value.trim();
@@ -543,7 +551,9 @@ function applyTheme2Json(deck, update) {
543
551
 
544
552
  // src/custom-theme/index.ts
545
553
  function applyCustomTheme(deck, input) {
546
- return applyTheme2Json(deck, input);
554
+ const normalizedDeck = parseDocument2(deck);
555
+ const updated = applyTheme2Json(normalizedDeck, input);
556
+ return parseDocument2(updated);
547
557
  }
548
558
  export {
549
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, 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 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.3",
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",
@@ -37,8 +37,11 @@
37
37
  "typecheck": "tsc -p tsconfig.json --noEmit",
38
38
  "prepublishOnly": "pnpm run build"
39
39
  },
40
+ "dependencies": {
41
+ "json2pptx-schema": "0.1.0"
42
+ },
40
43
  "devDependencies": {
41
44
  "tsup": "^8.5.1",
42
45
  "typescript": "^5.6.3"
43
46
  }
44
- }
47
+ }