@@ -4,7 +4,7 @@ import {dirname, join, resolve} from "node:path";
4
4
import { fileURLToPath } from "node:url" ;
5
5
import type { TemplateLiteral } from "acorn" ;
6
6
import { JSDOM } from "jsdom" ;
7
- import type { PluginOption } from "vite" ;
7
+ import type { PluginOption , IndexHtmlTransformContext } from "vite" ;
8
8
import type { Cell } from "../lib/notebook.js" ;
9
9
import { deserialize } from "../lib/serialize.js" ;
10
10
import { Sourcemap } from "../javascript/sourcemap.js" ;
@@ -23,13 +23,16 @@ export interface ObservableOptions {
23
23
serializer ?: XMLSerializer ;
24
24
/** The path to the page template; defaults to the default template. */
25
25
template ?: string ;
26
+ /** A function which performs a per-page transformation of the template HTML. */
27
+ transformTemplate ?: ( template : string , context : IndexHtmlTransformContext ) => string | Promise < string > ;
26
28
}
27
29
28
30
export function observable ( {
29
31
window = new JSDOM ( ) . window ,
30
32
parser = new window . DOMParser ( ) ,
31
33
serializer = new window . XMLSerializer ( ) ,
32
- template = fileURLToPath ( import . meta. resolve ( "../templates/default.html" ) )
34
+ template = fileURLToPath ( import . meta. resolve ( "../templates/default.html" ) ) ,
35
+ transformTemplate = undefined
33
36
} : ObservableOptions = { } ) : PluginOption {
34
37
return {
35
38
name : "observable" ,
@@ -45,7 +48,10 @@ export function observable({
45
48
order : "pre" ,
46
49
async handler ( input , context ) {
47
50
const notebook = deserialize ( input , { parser} ) ;
48
- const tsource = await readFile ( template , "utf-8" ) ;
51
+ let tsource = await readFile ( template , "utf-8" ) ;
52
+ if ( transformTemplate !== undefined ) {
53
+ tsource = await transformTemplate ( tsource , context ) ;
54
+ }
49
55
const document = parser . parseFromString ( tsource , "text/html" ) ;
50
56
const statics = new Set < Cell > ( ) ;
51
57
const assets = new Set < string > ( ) ;
0 commit comments