Skip to content

Commit aabd088

Browse files
committed
chore(screenshot): use automad-prism-themes
1 parent 057ad61 commit aabd088

File tree

4 files changed

+171
-37
lines changed

4 files changed

+171
-37
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ The color schemes is based on the [Prism library](https://prismjs.com).
419419

420420
![](https://i.imgur.com/uFfviX7.png)
421421

422-
The [Prism repository](https://github.com/PrismJS/prism-themes/tree/master?tab=readme-ov-file#available-themes) offers a wide range of themes to choose from as well as a [CDN option](https://unpkg.com/browse/[email protected]/themes).
422+
The [automad-prism-themes repository](https://github.com/automadcms/automad-prism-themes) offers a wide range of themes to choose from as well as a [CDN option](https://unpkg.com/browse/automad-prism-themes@latest/dist/).
423423

424424
##### element
425425

packages/screenshot/README.md

Lines changed: 134 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,17 @@ const buffer = await browserless.screenshot('https://example.com', {
6161

6262
### Options
6363

64-
| Option | Type | Default | Description |
65-
|--------|------|---------|-------------|
66-
| `type` | `string` | `'png'` | Image format: `'png'`, `'jpeg'`, `'webp'` |
67-
| `quality` | `number` || Quality (0-100) for JPEG/WebP |
68-
| `fullPage` | `boolean` | `false` | Capture full scrollable page |
69-
| `element` | `string` || CSS selector for element screenshot |
70-
| `codeScheme` | `string` | `'atom-dark'` | Prism.js theme for code highlighting |
71-
| `waitUntil` | `string` | `'auto'` | When to consider navigation done |
72-
| `waitForDom` | `number` | `0` | DOM stability window in ms (idle is `waitForDom / 10`, `0` disables DOM wait) |
73-
| `isPageReady` | `function` | `({ isWhite }) => !isWhite` | Custom readiness predicate for retry loop |
74-
| `overlay` | `object` | `{}` | Browser overlay options |
64+
| Option | Type | Default | Description |
65+
| ------------- | ---------- | --------------------------- | ----------------------------------------------------------------------------- |
66+
| `type` | `string` | `'png'` | Image format: `'png'`, `'jpeg'`, `'webp'` |
67+
| `quality` | `number` | | Quality (0-100) for JPEG/WebP |
68+
| `fullPage` | `boolean` | `false` | Capture full scrollable page |
69+
| `element` | `string` | | CSS selector for element screenshot |
70+
| `codeScheme` | `string` | `'atom-dark'` | Prism.js theme for code highlighting |
71+
| `waitUntil` | `string` | `'auto'` | When to consider navigation done |
72+
| `waitForDom` | `number` | `0` | DOM stability window in ms (idle is `waitForDom / 10`, `0` disables DOM wait) |
73+
| `isPageReady` | `function` | `({ isWhite }) => !isWhite` | Custom readiness predicate for retry loop |
74+
| `overlay` | `object` | `{}` | Browser overlay options |
7575

7676
All [Puppeteer page.screenshot() options](https://pptr.dev/api/puppeteer.screenshotoptions) are supported.
7777

@@ -84,10 +84,10 @@ const buffer = await browserless.screenshot(url, {
8484
overlay: {
8585
// Browser frame theme: 'dark' or 'light'
8686
browser: 'dark',
87-
87+
8888
// Background: color, gradient, or image URL
8989
background: 'linear-gradient(225deg, #FF057C 0%, #8D0B93 50%, #321575 100%)',
90-
90+
9191
// Margin around the screenshot (default: 0.2 = 20%)
9292
margin: 0.2
9393
}
@@ -149,8 +149,114 @@ const buffer = await browserless.screenshot('https://api.example.com/data', {
149149
})
150150
```
151151

152-
Available themes from [prism-themes](https://github.com/PrismJS/prism-themes):
153-
- `atom-dark`, `ghcolors`, `dracula`, `duotone-dark`, `duotone-light`, `material-dark`, `material-light`, `nord`, `synthwave84`, and more
152+
Available themes from [automad-prism-themes](https://github.com/automadcms/automad-prism-themes) and [prism-themes](https://github.com/PrismJS/prism-themes). When a theme exists in both, the automad version is used.
153+
154+
| Theme | Source |
155+
| --------------------------------- | ------------ |
156+
| `a11y-dark` | prism-themes |
157+
| `atom-dark` | automad |
158+
| `atom-one-dark` | automad |
159+
| `atom-one-light` | automad |
160+
| `aura-dark` | automad |
161+
| `automad-dark` | automad |
162+
| `automad-light` | automad |
163+
| `ayu-dark` | automad |
164+
| `ayu-light` | automad |
165+
| `ayu-mirage` | automad |
166+
| `base` | automad |
167+
| `base16-ateliersulphurpool.light` | prism-themes |
168+
| `bearded-arc-blueberry` | automad |
169+
| `bearded-vivid-light` | automad |
170+
| `boola-dark` | automad |
171+
| `boola-light` | automad |
172+
| `catppuccin-frappe` | automad |
173+
| `catppuccin-latte` | automad |
174+
| `catppuccin-macchiato` | automad |
175+
| `catppuccin-mocha` | automad |
176+
| `cb` | prism-themes |
177+
| `coldark-cold` | automad |
178+
| `coldark-dark` | automad |
179+
| `coy-without-shadows` | prism-themes |
180+
| `darcula` | prism-themes |
181+
| `dark-frost` | automad |
182+
| `dark-space` | automad |
183+
| `dracula` | automad |
184+
| `duotone-dark` | automad |
185+
| `duotone-earth` | automad |
186+
| `duotone-forest` | automad |
187+
| `duotone-light` | automad |
188+
| `duotone-sea` | automad |
189+
| `duotone-space` | automad |
190+
| `ghcolors` | prism-themes |
191+
| `github-dark` | automad |
192+
| `github-light` | automad |
193+
| `gruvbox-dark` | automad |
194+
| `gruvbox-light` | automad |
195+
| `holi-theme` | prism-themes |
196+
| `hopscotch` | prism-themes |
197+
| `laserwave` | automad |
198+
| `lucario` | prism-themes |
199+
| `material-dark` | prism-themes |
200+
| `material-light` | prism-themes |
201+
| `material-oceanic` | prism-themes |
202+
| `night-owl` | automad |
203+
| `night-owl-light` | automad |
204+
| `nightfall` | automad |
205+
| `nord` | automad |
206+
| `one-dark` | prism-themes |
207+
| `one-light` | prism-themes |
208+
| `panda` | automad |
209+
| `poimandres` | automad |
210+
| `pojoaque` | prism-themes |
211+
| `rose-pine` | automad |
212+
| `rose-pine-dawn` | automad |
213+
| `sakura-sun` | automad |
214+
| `sea-shells-dark` | automad |
215+
| `serendipity-midnight` | automad |
216+
| `serendipity-morning` | automad |
217+
| `serendipity-sunset` | automad |
218+
| `shades-of-purple` | automad |
219+
| `solarized-dark-atom` | automad |
220+
| `synthwave84` | automad |
221+
| `tailwind-ice` | automad |
222+
| `tailwind-moon-blue` | automad |
223+
| `tokyo-night` | automad |
224+
| `tokyo-night-light` | automad |
225+
| `tokyo-night-storm` | automad |
226+
| `verdandi` | automad |
227+
| `verdandi-alter` | automad |
228+
| `violet-dream` | automad |
229+
| `vs` | prism-themes |
230+
| `vsc-dark-plus` | automad |
231+
| `xonokai` | prism-themes |
232+
| `z-touch` | prism-themes |
233+
234+
Some themes also offer light/dark combo variants that bundle both modes in a single CSS file, switching automatically based on the page's dark mode class. Since screenshots render without a dark mode context, the light variant will always be used — prefer explicit themes like `github-light` or `github-dark` instead.
235+
236+
Available combo themes:
237+
238+
| Combo theme | Light | Dark |
239+
| ---------------------------------- | --------------------- | ----------------------- |
240+
| `atom-one.light-dark` | `atom-one-light` | `atom-one-dark` |
241+
| `automad.light-dark` | `automad-light` | `automad-dark` |
242+
| `ayu.light-dark` | `ayu-light` | `ayu-dark` |
243+
| `ayu-mirage.light-dark` | `ayu-light` | `ayu-mirage` |
244+
| `bearded-arc-blueberry.light-dark` | `bearded-vivid-light` | `bearded-arc-blueberry` |
245+
| `boola.light-dark` | `boola-light` | `boola-dark` |
246+
| `catppuccin-frappe.light-dark` | `catppuccin-latte` | `catppuccin-frappe` |
247+
| `catppuccin-macchiato.light-dark` | `catppuccin-latte` | `catppuccin-macchiato` |
248+
| `catppuccin-mocha.light-dark` | `catppuccin-latte` | `catppuccin-mocha` |
249+
| `coldark.light-dark` | `coldark-cold` | `coldark-dark` |
250+
| `github.light-dark` | `github-light` | `github-dark` |
251+
| `gruvbox.light-dark` | `gruvbox-light` | `gruvbox-dark` |
252+
| `night-owl.light-dark` | `night-owl-light` | `night-owl` |
253+
| `rose-pine.light-dark` | `rose-pine-dawn` | `rose-pine` |
254+
| `serendipity-midnight.light-dark` | `serendipity-morning` | `serendipity-midnight` |
255+
| `serendipity-sunset.light-dark` | `serendipity-morning` | `serendipity-sunset` |
256+
| `tailwind-moon-blue.light-dark` | `tailwind-ice` | `tailwind-moon-blue` |
257+
| `tokyo-night-storm.light-dark` | `tokyo-night-light` | `tokyo-night-storm` |
258+
| `tokyo-night.light-dark` | `tokyo-night-light` | `tokyo-night` |
259+
| `verdandi.light-dark` | `verdandi` | `verdandi-alter` |
154260

155261
### Smart Content Detection
156262

@@ -222,22 +328,22 @@ const buffer = await browserless.screenshot('https://example.com', {
222328

223329
This is a **core functionality package** for screenshot capture:
224330

225-
| Consumer | Purpose |
226-
|----------|---------|
227-
| `browserless` (core) | Provides the `.screenshot()` method |
228-
| `@browserless/cli` | Powers the `browserless screenshot` command |
229-
| `@browserless/pdf` | Uses `isWhiteScreenshot` for content detection |
331+
| Consumer | Purpose |
332+
| -------------------- | ---------------------------------------------- |
333+
| `browserless` (core) | Provides the `.screenshot()` method |
334+
| `@browserless/cli` | Powers the `browserless screenshot` command |
335+
| `@browserless/pdf` | Uses `isWhiteScreenshot` for content detection |
230336

231337
### Dependencies
232338

233-
| Package | Purpose |
234-
|---------|---------|
235-
| `@browserless/goto` | Page navigation with ad blocking |
236-
| `sharp` | Image composition for overlays; White/blank screenshot detection |
237-
| `prism-themes` | Syntax highlighting themes |
238-
| `svg-gradient` | Generate gradient backgrounds |
239-
| `got` | Fetch remote background images |
240-
| `is-html-content` | Detect if content is HTML vs code |
339+
| Package | Purpose |
340+
| ---------------------- | ---------------------------------------------------------------- |
341+
| `@browserless/goto` | Page navigation with ad blocking |
342+
| `sharp` | Image composition for overlays; White/blank screenshot detection |
343+
| `automad-prism-themes` | Syntax highlighting themes |
344+
| `svg-gradient` | Generate gradient backgrounds |
345+
| `got` | Fetch remote background images |
346+
| `is-html-content` | Detect if content is HTML vs code |
241347

242348
## License
243349

packages/screenshot/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"null-prototype-object": "~1.2.5",
4646
"p-reflect": "~2.1.0",
4747
"pretty-ms": "~7.0.1",
48+
"automad-prism-themes": "~0.3.7",
4849
"prism-themes": "~1.9.0",
4950
"sharp": "~0.34.5",
5051
"svg-gradient": "~1.0.4"

packages/screenshot/src/pretty/theme.js

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,45 @@ const { readFile } = require('fs/promises')
55
const isHttpUrl = require('is-url-http')
66
const path = require('path')
77

8+
const { existsSync, readdirSync } = require('fs')
9+
810
const CACHE = new NullProtoObj()
911

10-
const GET_THEME_PATH = () => require('prism-themes').themesDirectory
12+
const GET_THEME_INDEX = () => {
13+
const automadRoot = path.dirname(require.resolve('automad-prism-themes/package.json'))
14+
const { themesDirectory } = require('automad-prism-themes')
15+
const prismRoot = path.dirname(require.resolve('prism-themes/package.json'))
16+
const { themesDirectory: prismThemesDirectory } = require('prism-themes')
1117

12-
const THEME_PATH = () => CACHE.root || (CACHE.root = GET_THEME_PATH())
18+
const dirs = [
19+
themesDirectory,
20+
path.resolve(automadRoot, 'dist'),
21+
prismThemesDirectory,
22+
path.resolve(prismRoot, 'themes')
23+
].filter(dir => dir && existsSync(dir))
1324

14-
module.exports = async themeId => {
15-
if (isHttpUrl(themeId)) return `<link rel="stylesheet" type="text/css" href="${themeId}">`
25+
const index = new NullProtoObj()
26+
for (const dir of dirs) {
27+
for (const file of readdirSync(dir)) {
28+
const match = file.match(/^prism-(.+)\.css$/)
29+
if (match && !match[1].endsWith('.min') && !(match[1] in index)) {
30+
index[match[1]] = path.resolve(dir, file)
31+
}
32+
}
33+
}
34+
return index
35+
}
1636

17-
const stylesheet =
18-
CACHE[themeId] ||
19-
(CACHE[themeId] = await readFile(path.resolve(THEME_PATH(), `prism-${themeId}.css`)))
37+
const THEME_INDEX = () => CACHE.index || (CACHE.index = GET_THEME_INDEX())
2038

21-
return `<style>${stylesheet}</style>`
39+
const readTheme = async themeId => {
40+
const filePath = THEME_INDEX()[themeId]
41+
if (!filePath) throw new Error(`Unable to resolve Prism theme: ${themeId}`)
42+
return readFile(filePath)
43+
}
44+
45+
module.exports = async themeId => {
46+
if (isHttpUrl(themeId)) return `<link rel="stylesheet" type="text/css" href="${themeId}">`
47+
CACHE[themeId] = CACHE[themeId] || (await readTheme(themeId))
48+
return `<style>${CACHE[themeId]}</style>`
2249
}

0 commit comments

Comments
 (0)