fix: parse parallelization chunk arg, inline b64 for og image
This commit is contained in:
		
							parent
							
								
									a737207981
								
							
						
					
					
						commit
						e86544064c
					
				| @ -1,7 +1,7 @@ | ||||
| import { QuartzEmitterPlugin } from "../types" | ||||
| import { i18n } from "../../i18n" | ||||
| import { unescapeHTML } from "../../util/escape" | ||||
| import { FullSlug, getFileExtension } from "../../util/path" | ||||
| import { FullSlug, getFileExtension, joinSegments, QUARTZ } from "../../util/path" | ||||
| import { ImageOptions, SocialImageOptions, defaultImage, getSatoriFonts } from "../../util/og" | ||||
| import sharp from "sharp" | ||||
| import satori, { SatoriOptions } from "satori" | ||||
| @ -10,6 +10,8 @@ import { Readable } from "stream" | ||||
| import { write } from "./helpers" | ||||
| import { BuildCtx } from "../../util/ctx" | ||||
| import { QuartzPluginData } from "../vfile" | ||||
| import fs from "node:fs/promises" | ||||
| import chalk from "chalk" | ||||
| 
 | ||||
| const defaultOptions: SocialImageOptions = { | ||||
|   colorScheme: "lightMode", | ||||
| @ -28,7 +30,25 @@ async function generateSocialImage( | ||||
|   userOpts: SocialImageOptions, | ||||
| ): Promise<Readable> { | ||||
|   const { width, height } = userOpts | ||||
|   const imageComponent = userOpts.imageStructure(cfg, userOpts, title, description, fonts, fileData) | ||||
|   const iconPath = joinSegments(QUARTZ, "static", "icon.png") | ||||
|   let iconBase64: string | undefined = undefined | ||||
|   try { | ||||
|     const iconData = await fs.readFile(iconPath) | ||||
|     iconBase64 = `data:image/png;base64,${iconData.toString("base64")}` | ||||
|   } catch (err) { | ||||
|     console.warn(chalk.yellow(`Warning: Could not find icon at ${iconPath}`)) | ||||
|   } | ||||
| 
 | ||||
|   const imageComponent = userOpts.imageStructure({ | ||||
|     cfg, | ||||
|     userOpts, | ||||
|     title, | ||||
|     description, | ||||
|     fonts, | ||||
|     fileData, | ||||
|     iconBase64, | ||||
|   }) | ||||
| 
 | ||||
|   const svg = await satori(imageComponent, { | ||||
|     width, | ||||
|     height, | ||||
|  | ||||
| @ -172,7 +172,7 @@ export async function parseMarkdown(ctx: BuildCtx, fps: FilePath[]): Promise<Pro | ||||
|       workerType: "thread", | ||||
|     }) | ||||
|     const errorHandler = (err: any) => { | ||||
|       console.error(`${err}`.replace(/^error:\s*/i, "")) | ||||
|       console.error(err) | ||||
|       process.exit(1) | ||||
|     } | ||||
| 
 | ||||
| @ -201,7 +201,7 @@ export async function parseMarkdown(ctx: BuildCtx, fps: FilePath[]): Promise<Pro | ||||
| 
 | ||||
|     const markdownToHtmlPromises: WorkerPromise<ProcessedContent[]>[] = [] | ||||
|     processedFiles = 0 | ||||
|     for (const [mdChunk, _] of mdResults) { | ||||
|     for (const mdChunk of mdResults) { | ||||
|       markdownToHtmlPromises.push(pool.exec("processHtml", [serializableCtx, mdChunk])) | ||||
|     } | ||||
|     const results: ProcessedContent[][] = await Promise.all( | ||||
|  | ||||
| @ -35,7 +35,7 @@ export class QuartzLogger { | ||||
|         const truncated = truncate(output, columns) | ||||
|         process.stdout.write(truncated) | ||||
|         this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerChars.length | ||||
|       }, 20) | ||||
|       }, 50) | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -13,6 +13,7 @@ import chalk from "chalk" | ||||
| 
 | ||||
| const defaultHeaderWeight = [700] | ||||
| const defaultBodyWeight = [400] | ||||
| 
 | ||||
| export async function getSatoriFonts(headerFont: FontSpecification, bodyFont: FontSpecification) { | ||||
|   // Get all weights for header and body fonts
 | ||||
|   const headerWeights: FontWeight[] = ( | ||||
| @ -134,21 +135,12 @@ export type SocialImageOptions = { | ||||
|   excludeRoot: boolean | ||||
|   /** | ||||
|    * JSX to use for generating image. See satori docs for more info (https://github.com/vercel/satori)
 | ||||
|    * @param cfg global quartz config | ||||
|    * @param userOpts options that can be set by user | ||||
|    * @param title title of current page | ||||
|    * @param description description of current page | ||||
|    * @param fonts global font that can be used for styling | ||||
|    * @param fileData full fileData of current page | ||||
|    * @returns prepared jsx to be used for generating image | ||||
|    */ | ||||
|   imageStructure: ( | ||||
|     cfg: GlobalConfiguration, | ||||
|     userOpts: UserOpts, | ||||
|     title: string, | ||||
|     description: string, | ||||
|     fonts: SatoriOptions["fonts"], | ||||
|     fileData: QuartzPluginData, | ||||
|     options: ImageOptions & { | ||||
|       userOpts: UserOpts | ||||
|       iconBase64?: string | ||||
|     }, | ||||
|   ) => JSXInternal.Element | ||||
| } | ||||
| 
 | ||||
| @ -178,17 +170,17 @@ export type ImageOptions = { | ||||
| } | ||||
| 
 | ||||
| // This is the default template for generated social image.
 | ||||
| export const defaultImage: SocialImageOptions["imageStructure"] = ( | ||||
|   cfg: GlobalConfiguration, | ||||
|   { colorScheme }: UserOpts, | ||||
|   title: string, | ||||
|   description: string, | ||||
|   _fonts: SatoriOptions["fonts"], | ||||
|   fileData: QuartzPluginData, | ||||
| ) => { | ||||
| export const defaultImage: SocialImageOptions["imageStructure"] = ({ | ||||
|   cfg, | ||||
|   userOpts, | ||||
|   title, | ||||
|   description, | ||||
|   fileData, | ||||
|   iconBase64, | ||||
| }) => { | ||||
|   const { colorScheme } = userOpts | ||||
|   const fontBreakPoint = 32 | ||||
|   const useSmallerFont = title.length > fontBreakPoint | ||||
|   const iconPath = `https://${cfg.baseUrl}/static/icon.png` | ||||
| 
 | ||||
|   // Format date if available
 | ||||
|   const rawDate = getDate(cfg, fileData) | ||||
| @ -226,14 +218,16 @@ export const defaultImage: SocialImageOptions["imageStructure"] = ( | ||||
|           marginBottom: "0.5rem", | ||||
|         }} | ||||
|       > | ||||
|         <img | ||||
|           src={iconPath} | ||||
|           width={56} | ||||
|           height={56} | ||||
|           style={{ | ||||
|             borderRadius: "50%", | ||||
|           }} | ||||
|         /> | ||||
|         {iconBase64 && ( | ||||
|           <img | ||||
|             src={iconBase64} | ||||
|             width={56} | ||||
|             height={56} | ||||
|             style={{ | ||||
|               borderRadius: "50%", | ||||
|             }} | ||||
|           /> | ||||
|         )} | ||||
|         <div | ||||
|           style={{ | ||||
|             display: "flex", | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user