Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(og image): more configurations #268

Merged
merged 2 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions packages/vitepress-plugin-og-image/src/vitepress/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ async function renderSVGAndRewriteHTML(
domain: string,
imageUrlResolver: BuildEndGenerateOpenGraphImagesOptions['svgImageUrlResolver'],
additionalFontBuffers?: Buffer[],
resultImageWidth?: number,
maxCharactersPerLine?: number,
): Promise<TaskResult> {
const fileName = basename(file, '.html')
const ogImageFilePathBaseName = `og-${fileName}.png`
Expand Down Expand Up @@ -109,6 +111,7 @@ async function renderSVGAndRewriteHTML(
page.title,
page.category ?? '',
ogImageTemplateSvg,
maxCharactersPerLine,
)

let width: number
Expand All @@ -119,7 +122,7 @@ async function renderSVGAndRewriteHTML(
ogImageFilePathFullName,
ogImageTemplateSvgPath,
relative(siteConfig.srcDir, file),
{ fontPath: await tryToLocateFontFile(siteConfig), imageUrlResolver, additionalFontBuffers },
{ fontPath: await tryToLocateFontFile(siteConfig), imageUrlResolver, additionalFontBuffers, resultImageWidth },
)
width = res.width
height = res.height
Expand Down Expand Up @@ -182,10 +185,11 @@ async function renderSVGAndSavePNG(
fontPath?: string
imageUrlResolver?: BuildEndGenerateOpenGraphImagesOptions['svgImageUrlResolver']
additionalFontBuffers?: Buffer[]
resultImageWidth?: number
},
) {
try {
const { png: pngBuffer, width, height } = await renderSVG(svgContent, await initFontBuffer(options), options.imageUrlResolver, options.additionalFontBuffers)
const { png: pngBuffer, width, height } = await renderSVG(svgContent, await initFontBuffer(options), options.imageUrlResolver, options.additionalFontBuffers, options.resultImageWidth)

try {
await fs.writeFile(saveAs, pngBuffer, 'binary')
Expand Down Expand Up @@ -256,6 +260,18 @@ export interface BuildEndGenerateOpenGraphImagesOptions {
* and will fallback to a builtin template.
*/
templateSvgPath?: string

/**
* Width of the result image.
* Defaults to `1200`.
*/
resultImageWidth?: number
nekomeowww marked this conversation as resolved.
Show resolved Hide resolved

/**
* Maximum characters per line.
* Defaults to `17`.
*/
maxCharactersPerLine?: number
nekomeowww marked this conversation as resolved.
Show resolved Hide resolved
}

export interface BuildEndGenerateOpenGraphImagesOptionsCategory {
Expand Down Expand Up @@ -513,6 +529,8 @@ export function buildEndGenerateOpenGraphImages(options: BuildEndGenerateOpenGra
options.baseUrl,
options.svgImageUrlResolver,
options.svgFontBuffers,
options.resultImageWidth,
options.maxCharactersPerLine,
)
}))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,35 @@ import { escape } from './escape'

const imageBuffers = new Map<string, Promise<Buffer>>()

export function templateSVG(siteName: string, siteDescription: string, title: string, category: string, ogTemplate: string): string {
export function templateSVG(siteName: string, siteDescription: string, title: string, category: string, ogTemplate: string, maxCharactersPerLine?: number): string {
maxCharactersPerLine ??= 17

// Remove emoji and split lines
const lines = removeEmoji(title)
.trim()
.replace(/(?![^\n]{1,17}$)([^\n]{1,17})\s/g, '$1\n')
.replaceAll('\r\n', '\n')
.split('\n')
.map(line => line.trim())

// Restricted 17 words per line
const maxLineLength = 17
// Restricted `maxCharactersPerLine` characters per line
for (let i = 0; i < lines.length; i++) {
const val = lines[i].trim()

if (val.length > maxLineLength) {
if (val.length > maxCharactersPerLine) {
// attempt to break at a space
let breakPoint = val.lastIndexOf(' ', maxLineLength)
let breakPoint = val.lastIndexOf(' ', maxCharactersPerLine)

// attempt to break before before a capital letter
if (breakPoint < 0) {
for (let j = Math.min(val.length - 1, maxLineLength); j > 0; j--) {
for (let j = Math.min(val.length - 1, maxCharactersPerLine); j > 0; j--) {
if (val[j] === val[j].toUpperCase()) {
breakPoint = j
break
}
}
}
if (breakPoint < 0)
breakPoint = maxLineLength
breakPoint = maxCharactersPerLine

lines[i] = val.slice(0, breakPoint)
lines[i + 1] = `${val.slice(lines[i].length)}${lines[i + 1] || ''}`
Expand Down Expand Up @@ -101,6 +103,7 @@ export async function renderSVG(
fontBuffer?: Uint8Array,
imageUrlResolver?: BuildEndGenerateOpenGraphImagesOptions['svgImageUrlResolver'],
additionalFontBuffers?: Uint8Array[],
resultImageWidth?: number,
): Promise<{
png: Uint8Array
width: number
Expand All @@ -110,7 +113,7 @@ export async function renderSVG(
const resvg = new Resvg(
svgContent,
{
fitTo: { mode: 'width', value: 1200 },
fitTo: { mode: 'width', value: resultImageWidth ?? 1200 },
font: {
fontBuffers: fontBuffer
? [fontBuffer, ...(additionalFontBuffers ?? [])]
Expand Down
Loading