119 lines
3.7 KiB
Python
119 lines
3.7 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
生成字体清单文件
|
||
扫描 fonts/ 目录下的所有字体文件,同时生成:
|
||
1. frontend/public/fonts.json
|
||
2. miniprogram/assets/fonts.json
|
||
3. miniprogram/assets/fonts.js
|
||
"""
|
||
|
||
import os
|
||
import json
|
||
from pathlib import Path
|
||
|
||
def scan_fonts(font_dir='fonts'):
|
||
"""扫描字体目录,返回字体信息列表"""
|
||
fonts = []
|
||
font_dir_path = Path(font_dir)
|
||
|
||
if not font_dir_path.exists():
|
||
print(f"字体目录不存在: {font_dir}")
|
||
return fonts
|
||
|
||
# 递归遍历 fonts 目录(支持多级分类)
|
||
for font_file in sorted(font_dir_path.rglob('*')):
|
||
if not font_file.is_file():
|
||
continue
|
||
if font_file.suffix.lower() not in ['.ttf', '.otf']:
|
||
continue
|
||
|
||
relative_parent = font_file.parent.relative_to(font_dir_path)
|
||
category_name = str(relative_parent).replace('\\', '/')
|
||
if category_name == '.':
|
||
category_name = '未分类'
|
||
|
||
relative_path = font_file.relative_to(font_dir_path).as_posix()
|
||
|
||
# 先生成基础信息,id 在后续统一按序号回填
|
||
font_info = {
|
||
'id': '',
|
||
'name': font_file.stem,
|
||
'filename': font_file.name,
|
||
'category': category_name,
|
||
'relativePath': relative_path,
|
||
}
|
||
|
||
fonts.append(font_info)
|
||
|
||
# 统一排序后分配 4 位数字 id(0001、0002...)
|
||
fonts = sorted(fonts, key=lambda x: (x['category'], x['name'], x['filename']))
|
||
for index, font in enumerate(fonts, start=1):
|
||
font['id'] = f"{index:04d}"
|
||
|
||
return fonts
|
||
|
||
|
||
def build_manifest(fonts, path_prefix):
|
||
"""根据路径前缀构建对外清单"""
|
||
prefix = f"/{str(path_prefix or '').strip('/')}"
|
||
if prefix == '/':
|
||
prefix = ''
|
||
|
||
manifest = []
|
||
for font in fonts:
|
||
manifest.append({
|
||
'id': font['id'],
|
||
'name': font['name'],
|
||
'filename': font['filename'],
|
||
'category': font['category'],
|
||
'path': f"{prefix}/{font['relativePath']}",
|
||
})
|
||
|
||
return manifest
|
||
|
||
def write_fonts_json(fonts, output_file):
|
||
"""写入字体清单 JSON 文件"""
|
||
os.makedirs(os.path.dirname(output_file), exist_ok=True)
|
||
with open(output_file, 'w', encoding='utf-8') as f:
|
||
json.dump(fonts, f, ensure_ascii=False, indent=2)
|
||
print(f"字体清单已保存到: {output_file}")
|
||
|
||
|
||
def write_fonts_js(fonts, output_file):
|
||
"""写入小程序可 require 的 JS 清单文件"""
|
||
os.makedirs(os.path.dirname(output_file), exist_ok=True)
|
||
content = "module.exports = " + json.dumps(fonts, ensure_ascii=False, indent=2) + "\n"
|
||
with open(output_file, 'w', encoding='utf-8') as f:
|
||
f.write(content)
|
||
print(f"字体清单已保存到: {output_file}")
|
||
|
||
|
||
def main():
|
||
"""主函数"""
|
||
# 扫描字体(唯一来源:仓库根目录 fonts/)
|
||
fonts = scan_fonts('fonts')
|
||
|
||
print(f"找到 {len(fonts)} 个字体文件")
|
||
|
||
# Web 清单:统一指向根目录 fonts
|
||
web_fonts = build_manifest(fonts, '/fonts')
|
||
write_fonts_json(web_fonts, 'frontend/public/fonts.json')
|
||
|
||
# 小程序清单:同样指向根目录 fonts(与 web 共用一份字体目录)
|
||
miniprogram_fonts = build_manifest(fonts, '/fonts')
|
||
write_fonts_json(miniprogram_fonts, 'miniprogram/assets/fonts.json')
|
||
write_fonts_js(miniprogram_fonts, 'miniprogram/assets/fonts.js')
|
||
|
||
# 统计信息
|
||
categories = {}
|
||
for font in fonts:
|
||
category = font['category']
|
||
categories[category] = categories.get(category, 0) + 1
|
||
|
||
print("\n按类别统计:")
|
||
for category, count in sorted(categories.items()):
|
||
print(f" {category}: {count} 个字体")
|
||
|
||
if __name__ == '__main__':
|
||
main()
|