#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 混沌学园风格微信公众号 HTML 生成脚本 用途:将提取的图片列表与文字内容,生成符合混沌品牌视觉体系的微信公众号 HTML 排版。 使用方法: python3 build_hundun_html.py <输出HTML路径> 设计规范: - 白底 (#FFFFFF) + 混沌黄 (#F5B700) + 石墨黑 (#181818) - Hero 大图 + 双列瀑布流副图 - 100% 内联样式,微信公众号编辑器兼容 - 所有图片加 referrerpolicy="no-referrer" 详细规范请参阅 SKILL.md """ import sys import re import html as html_lib from pathlib import Path # ============================================================ # 混沌色彩体系常量 # ============================================================ COLOR_PRIMARY = "#F5B700" # 混沌黄 COLOR_SECONDARY = "#D99B00" # 深金(正文强调) COLOR_DARK = "#181818" # 石墨黑 COLOR_DARK_SUB = "#242424" # 辅助深色(深色卡片子容器) COLOR_BG = "#FFFFFF" # 原生白底 COLOR_CARD = "#F8F9FA" # 极浅灰(内容卡片) COLOR_MODULE = "#FFFDF5" # 微黄底(课程模块卡片) COLOR_TEXT = "#2B2B2B" # 主正文 COLOR_TEXT_ALT = "#333333" # 辅助正文 COLOR_TEXT_SUB = "#4E5969" # 二级正文 COLOR_BORDER = "#E5E6EB" # 边框灰 COLOR_DIVIDER = "#D9D9D9" # 虚线分割 FONT_STACK = ( "-apple-system, BlinkMacSystemFont, 'PingFang SC', " "'Hiragino Sans GB', 'Microsoft YaHei', sans-serif" ) def loadImages(filePath: str) -> dict: """ 从 extracted_content.txt 加载图片索引映射。 :param filePath: 提取结果文件路径 :return: {索引: URL} 字典 """ imgDict = {} with open(filePath, 'r', encoding='utf-8') as f: for line in f: match = re.match(r'\[(\d+)\]\s+(https?://\S+)', line.strip()) if match: idx = int(match.group(1)) url = html_lib.unescape(match.group(2)) imgDict[idx] = url return imgDict def renderHeroMasonry(imgDict: dict, imgIndices: list, maxSub: int = 6) -> str: """ 渲染 Hero 大图 + 双列瀑布流副图。 :param imgDict: 全局图片索引字典 :param imgIndices: 本组图片索引列表 :param maxSub: 最大副图数量 :return: HTML 字符串 """ urls = [imgDict[i] for i in imgIndices if i in imgDict] if not urls: return "" heroUrl = urls[0] subUrls = urls[1:1 + maxSub] heroHtml = f'''
''' if not subUrls: return heroHtml leftUrls = subUrls[0::2] rightUrls = subUrls[1::2] def buildCol(colUrls): imgs = [] for u in colUrls: imgs.append( f'' ) return "\n".join(imgs) leftHtml = buildCol(leftUrls) rightHtml = buildCol(rightUrls) masonryHtml = f'''
{leftHtml}
{rightHtml}
''' return heroHtml + masonryHtml def renderYearCard(year: str, title: str, desc: str, imgHtml: str, highlight: bool = False) -> str: """ 渲染时间线年份卡片。 :param year: 年份文字(如"2018年冬") :param title: 小标题 :param desc: 描述段落 :param imgHtml: 内部图片 HTML(由 renderHeroMasonry 生成) :param highlight: 是否用混沌黄边框高亮(用于最新年份) :return: HTML 字符串 """ borderStyle = f"2px solid {COLOR_PRIMARY}" if highlight else f"1px solid {COLOR_BORDER}" badgeBg = COLOR_PRIMARY if highlight else COLOR_DARK badgeColor = "#000000" if highlight else COLOR_PRIMARY titleColor = COLOR_DARK return f'''
{year}

{title}

{desc}

{imgHtml}
''' def renderModuleCard(name: str, dateRange: str, theme: str, desc: str) -> str: """ 渲染课程模块卡片(微黄底)。 :param name: 模块名称(如"一模块 · 亮剑") :param dateRange: 时间(如"2026.8.29 - 8.30") :param theme: 主题文字 :param desc: 描述文字 :return: HTML 字符串 """ return f'''

{name}

{dateRange}

{theme}

{desc}

''' def renderRequirementCard(icon: str, title: str, items: list) -> str: """ 渲染招募要求卡片。 :param icon: emoji 图标 :param title: 卡片标题(如"1. 产业研究能力") :param items: 列表项文字列表 :return: HTML 字符串 """ liHtml = "\n".join(f"
  • {item}
  • " for item in items) return f'''

    {icon} {title}

    ''' def wrapPage(innerHtml: str) -> str: """ 将内部 HTML 包裹为完整的微信公众号页面容器。 :param innerHtml: 内部所有模块的 HTML :return: 完整的 HTML 片段 """ return f'''
    {innerHtml}
    ''' # ============================================================ # 示例用法(可按需修改 main 逻辑适配不同文章) # ============================================================ if __name__ == "__main__": if len(sys.argv) < 3: print("用法: python3 build_hundun_html.py <输出HTML路径>") print("示例: python3 build_hundun_html.py ./output/extracted_content.txt ./output/article.html") sys.exit(1) inputFile = sys.argv[1] outputFile = sys.argv[2] imgDict = loadImages(inputFile) print(f"📦 已加载 {len(imgDict)} 张图片索引") # 示例:生成一个简单的年份卡片 imgHtml = renderHeroMasonry(imgDict, [1, 2, 3, 4, 5]) yearCard = renderYearCard("2024年", "示例年份", "这是一段示例描述文字。", imgHtml) fullHtml = wrapPage(yearCard) Path(outputFile).write_text(fullHtml, encoding='utf-8') print(f"✅ HTML 已生成: {outputFile}")