#!/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()