import { img as convertBase64ToImage } from 'base64-img' ; import cheerio from 'cheerio' ; import { createHash } from 'crypto' ; import fs from 'fs-extra' ; import path from 'path' ; import { getHTMLFiles } from '../theme/src/utils/jupyterBook' ; const DATA_IMAGES = `_data-images` ; const DATA_IMAGES_DIR = path . resolve ( __dirname , '../public' , DATA_IMAGES ) ; param file async function convertDataImage ( file ) { const html = await fs . readFile ( file , 'utf-8' ) ; const $ = cheerio . load ( html ) ; const prevHtml = $ . html ( ) ; for ( const node of $ ( 'img' ) . toArray ( ) ) { const src = $ ( node ) ?. attr ( 'src' ) ?? '' ; if ( src . startsWith ( 'data:' ) ) { const [ , data ] = src . split ( ';' ) ; const hash = createHash ( 'sha256' ) . update ( data ) . digest ( 'base64' ) ; const name = hash . replaceAll ( '/' , '-' ) . replaceAll ( /=$/g , '' ) ; const filename = await new Promise < string > ( ( resolve , reject ) => convertBase64ToImage ( src , DATA_IMAGES_DIR , name , ( error , imageFile ) => { if ( error ) { reject ( error ) ; } else { resolve ( imageFile ) ; } } ) ) ; $ ( node ) ?. attr ( 'src' , path . join ( '/' , DATA_IMAGES , path . basename ( filename ) ) ) ; } const nextHtml = $ . html ( ) ; if ( nextHtml !== prevHtml ) { await fs . writeFile ( file , nextHtml ) ; } } } async function convertDataImages ( ) { const files = await getHTMLFiles ( ) ; if ( ! ( await fs . pathExists ( DATA_IMAGES_DIR ) ) ) { await fs . mkdirp ( DATA_IMAGES_DIR ) ; } await Promise . all ( files . map ( convertDataImage ) ) ; } convertDataImages ( ) ;