(files: PptxFiles)
| 94 | * 3. Parses each component and assembles the final structure |
| 95 | */ |
| 96 | export function buildPresentation(files: PptxFiles): PresentationData { |
| 97 | // --- Parse presentation root --- |
| 98 | const presRoot = parseXml(files.presentation) |
| 99 | const presRels = parseRels(files.presentationRels) |
| 100 | |
| 101 | // --- Slide size --- |
| 102 | const sldSz = presRoot.child('sldSz') |
| 103 | const width = emuToPx(sldSz.numAttr('cx') ?? 9144000) // default 10 inches |
| 104 | const height = emuToPx(sldSz.numAttr('cy') ?? 6858000) // default 7.5 inches |
| 105 | |
| 106 | // --- WPS detection --- |
| 107 | const isWps = detectWps(files.presentation) |
| 108 | |
| 109 | // --- Parse themes --- |
| 110 | const themes = new Map<string, ThemeData>() |
| 111 | for (const [themePath, themeXml] of files.themes) { |
| 112 | const themeRoot = parseXml(themeXml) |
| 113 | themes.set(themePath, parseTheme(themeRoot)) |
| 114 | } |
| 115 | |
| 116 | // --- Parse slide masters and build master→theme mapping --- |
| 117 | const masters = new Map<string, MasterData>() |
| 118 | const masterToTheme = new Map<string, string>() |
| 119 | |
| 120 | for (const [masterPath, masterXml] of files.slideMasters) { |
| 121 | const masterRoot = parseXml(masterXml) |
| 122 | const masterData = parseMaster(masterRoot) |
| 123 | |
| 124 | // Find theme relationship for this master |
| 125 | const masterRelsPath = relsPathFor(masterPath) |
| 126 | const masterRelsXml = files.slideMasterRels.get(masterRelsPath) |
| 127 | if (masterRelsXml) { |
| 128 | const masterRels = parseRels(masterRelsXml) |
| 129 | masterData.rels = masterRels |
| 130 | const themeRel = findRelByType(masterRels, 'theme') |
| 131 | if (themeRel) { |
| 132 | const themePath = resolveRelTarget(basePath(masterPath), themeRel.target) |
| 133 | masterToTheme.set(masterPath, themePath) |
| 134 | } |
| 135 | } |
| 136 | masters.set(masterPath, masterData) |
| 137 | } |
| 138 | |
| 139 | // --- Parse slide layouts and build layout→master mapping --- |
| 140 | const layouts = new Map<string, LayoutData>() |
| 141 | const layoutToMaster = new Map<string, string>() |
| 142 | |
| 143 | for (const [layoutPath, layoutXml] of files.slideLayouts) { |
| 144 | const layoutRoot = parseXml(layoutXml) |
| 145 | const layoutData = parseLayout(layoutRoot) |
| 146 | |
| 147 | // Find master relationship for this layout |
| 148 | const layoutRelsPath = relsPathFor(layoutPath) |
| 149 | const layoutRelsXml = files.slideLayoutRels.get(layoutRelsPath) |
| 150 | if (layoutRelsXml) { |
| 151 | const layoutRels = parseRels(layoutRelsXml) |
| 152 | layoutData.rels = layoutRels |
| 153 | const masterRel = findRelByType(layoutRels, 'slideMaster') |
no test coverage detected