-
Notifications
You must be signed in to change notification settings - Fork 745
Open
Description
Just wondering if you'd be interested a PR that touches this component to inject custom theme data, which would allow referencing colours by relative accent1
tags rather than absolute hex codes?
Line 1753 in 5a30b0f
export function makeXmlTheme (pres: IPresentationProps): string { |
I prefer to get input before unilaterally trying to make any design decisions in the PR, so just opening this ticket as a discussion point first.
This pseudocode is roughly what I had in mind:
import PptxGenJS from "pptxgenjs"
import HexColor = PptxGenJS.HexColor
import ThemeColor = PptxGenJS.ThemeColor
/** Update existing theme props. */
export interface ThemeProps {
name?: string
colors: Record<ThemeColor, HexColor>
headFontFace?: string
bodyFontFace?: string
}
/** Update existing presentation props. */
export interface IPresentationProps {
theme: ThemeProps
}
/** Inject theme into presentation. */
export function makeXmlTheme({
theme: {
name = "Office",
colors, // TODO: Resolve default colors.
headFontFace = "Calibri Light",
bodyFontFace = "Calibri"
}
}: IPresentationProps): string {
return /* language=XML */ `
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">
<a:themeElements>
<a:clrScheme name="${name}">
<a:dk1>
<a:sysClr val="windowText" lastClr="${colors.tx1.replace(/^#/, ``)}"/>
</a:dk1>
<a:lt1>
<a:sysClr val="window" lastClr="${colors.bg1.replace(/^#/, ``)}"/>
</a:lt1>
<a:dk2>
<a:srgbClr val="${colors.tx2.replace(/^#/, ``)}"/>
</a:dk2>
<a:lt2>
<a:srgbClr val="${colors.bg2.replace(/^#/, ``)}"/>
</a:lt2>
<a:accent1>
<a:srgbClr val="${colors.accent1.replace(/^#/, ``)}"/>
</a:accent1>
<a:accent2>
<a:srgbClr val="${colors.accent2.replace(/^#/, ``)}"/>
</a:accent2>
<a:accent3>
<a:srgbClr val="${colors.accent3.replace(/^#/, ``)}"/>
</a:accent3>
<a:accent4>
<a:srgbClr val="${colors.accent4.replace(/^#/, ``)}"/>
</a:accent4>
<a:accent5>
<a:srgbClr val="${colors.accent5.replace(/^#/, ``)}"/>
</a:accent5>
<a:accent6>
<a:srgbClr val="${colors.accent6.replace(/^#/, ``)}"/>
</a:accent6>
<a:hlink>
<a:srgbClr val="${colors.accent1.replace(/^#/, ``)}"/>
</a:hlink>
<a:folHlink>
<a:srgbClr val="${colors.accent1.replace(/^#/, ``)}"/>
</a:folHlink>
</a:clrScheme>
<a:fontScheme name="${name}">
<a:majorFont>
<a:latin typeface="${headFontFace}"/>
<a:ea typeface=""/>
<a:cs typeface=""/>
</a:majorFont>
<a:minorFont>
<a:latin typeface="${bodyFontFace}"/>
<a:ea typeface=""/>
<a:cs typeface=""/>
</a:minorFont>
</a:fontScheme>
/** ... rest of theme **/
</a:theme>
`
.trim()
.replace(/\n+/g, ` `)
.replace(/>\s+</g, `><`)
}
}
FWIW I have this POC working with the following custom implementation:
async #writeWithTheme(filename: string): Promise<void> {
const data = await this.pptx().write({
outputType: "nodebuffer",
compression: false
})
logger.debug(`Adding office theme to "${filename}".`)
const zip = new JSZip()
await zip.loadAsync(data)
zip.file("ppt/theme/theme1.xml", makeXmlTheme("Office", this.theme))
logger.debug(`Generating zip content.`)
const output = await zip.generateAsync({
type: "nodebuffer",
compression: "DEFLATE"
})
logger.debug(`Writing presentation to "${filename}".`)
await writeFile(filename, output)
}
Metadata
Metadata
Assignees
Labels
No labels