first commit
This commit is contained in:
95
opt-fonts.py
Normal file
95
opt-fonts.py
Normal file
@@ -0,0 +1,95 @@
|
||||
'''
|
||||
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()
|
||||
Reference in New Issue
Block a user