2026-10-22 22:19:50 +08:00

32 lines
1.6 KiB
JavaScript

import path from 'node:path';
import fs from 'node:fs/promises';
import * as cheerio from 'cheerio';
import { root, relative, write } from './lib.mjs';
export async function addFonts(asset,site,output){
const cjk=new Set();const korean=new Set();
for(const page of output){
const $=cheerio.load(await fs.readFile(path.join(root,site.id,page.file),'utf8'));$('script,style').remove();
for(const char of $('body').text()){
if(/[\u2e80-\u9fff\uff00-\uffef]/u.test(char))cjk.add(char);
else if(/[\uac00-\ud7af]/u.test(char))korean.add(char);
}
}
const styles=[];
for(const [family,characters,licenseFolder] of [['Noto Sans SC',cjk,'notosanssc'],['Noto Sans KR',korean,'notosanskr']]){
const sorted=[...characters].sort((a,b)=>a.codePointAt(0)-b.codePointAt(0));
if(!sorted.length)continue;
for(let i=0;i<sorted.length;i+=400){
const u=new URL('https://fonts.googleapis.com/css2');u.searchParams.set('family',family+':wght@400;700');u.searchParams.set('display','swap');u.searchParams.set('text',sorted.slice(i,i+400).join(''));
styles.push(asset.ensure(u.href,site.origin,'.css'));
}
asset.ensure(`https://raw.githubusercontent.com/google/fonts/main/ofl/${licenseFolder}/OFL.txt`,site.origin,'.txt');
}
for(const page of output){
const file=path.join(root,site.id,page.file);const $=cheerio.load(await fs.readFile(file,'utf8'));
for(const style of styles)$('head').append(`<link rel="stylesheet" href="${relative(page.file,style)}">`);
await write(file,$.html());
}
console.log(`${site.id}: embedding local CJK fonts (${cjk.size} CJK characters, ${korean.size} Korean characters)`);
}