''' Author: Tony Zorman https://github.com/slotThe/slotThe.github.io/blob/main/scripts/opt-fonts.py modified by Yu Cong ''' import os import re from pathlib import Path from bs4 import BeautifulSoup from fontTools.subset import Options, Subsetter from fontTools.ttLib import TTFont code_font = "IosevkaCustom" text_font = "Lato" # title_font = "Vollkorn" # latex_font = "KaTeX" def used_glyphs(path: str) -> tuple[str, str]: html = [ # Get HTML for all pages BeautifulSoup(Path(f"{p}/{f}").read_text(), "html.parser") for (p, _, fs) in os.walk(path) for f in fs if f.endswith(".html") ] # latex_html = [p.find_all("span", class_=re.compile("katex*")) for p in html] # latex = set() # Glyphs used in LaTeX # [latex.update(tag.get_text()) for page in latex_html for tag in page] code_html = [page.find_all("code") for page in html] + [ page.find_all("div", class_=re.compile("highlight-*")) for page in html ] code = set() # Glyphs used in code [code.update(tag.get_text()) for page in code_html for tag in page] # Fonts used only for titles and headings. # title_html = [ # page.find_all(h) for page in html for h in ["h" + str(x) for x in range(1, 7)] # ] # title = set() # [title.update(tag.get_text()) for page in title_html for tag in page] # For the regular text, only keep what's strictly needed. normal = set() # [tag.extract() for page in latex_html for tag in page] # Mutates `hmtl`! [tag.extract() for page in code_html for tag in page] # Mutates `html`! [normal.update(page.get_text()) for page in html] # Return only the relevant glyphs for each of the fonts. return "HomeDraftsAbu".join(code), "↑".join(normal) def optimise_font(in_file: str, out_file: str, text: str) -> None: before_size = os.path.getsize(in_file) # might be that in_file = out_file options = Options(hinting=False, desubroutinize=True) if text_font in in_file: options.layout_features = ["*"] # small-caps et al font = TTFont(in_file, lazy=True) font.flavor = "woff2" subs = Subsetter(options) subs.populate(text=text) subs.subset(font) font.save(out_file) font.close() print( f"Size for {Path(in_file).stem} changed from " f"{before_size / 1024:.1f}KB " f"to {os.path.getsize(out_file) / 1024:.1f}KB" ) def main() -> None: in_path = f"fonts/" code, normal = used_glyphs(f"_site/") for font in os.listdir(in_path): in_file = in_path + font optimise_font( in_file, f"fonts/{font.replace('.ttf', '.woff2')}", code if code_font in in_file else normal, ) if __name__ == "__main__": main()