answer-me-with-html 架构解析:一份 Markdown 稿件如何变成单文件 HTML 讲解页
【免费下载链接】answer-me-with-htmlAnswer me with HTML — an agent skill that answers hard questions with a one-page HTML you can actually read. 让 AI Agent 用一页 HTML 回答复杂问题。项目地址https://gitcode.com/gh_mirrors/an/answer-me-with-html点击查看免费下载本文以仓库自带的示例草稿 examples/architecture.md 为主线拆解 answer-me-with-html 的核心架构模型只写内容稿扩展 MarkdownCLI 负责解析、排版、配色、暗黑模式、SVG 自动布局和写作风格检查。读完后你会掌握它的渲染管线parse → STE lint → 组件渲染 → dagre 布局 → 模板组装、各模块的源码位置以及出错时错误 正确示例的自我修复闭环。1. 设计起点模型与 CLI 的分工示例文档开篇就明确了整条管线的分工边界原文面板 B工作谁来做决定讲什么、分几个面板模型写关系、数据和说明文字模型排版、配色、暗黑模式CLI计算图形坐标CLIdagre检查写作风格CLISTE lint结果模型不再输出 CSS、JS 和 SVG 坐标。一次 Bash 调用就能拿到成品页面。原文面板 B 的 callout这条分工线在仓库多处可以得到印证package.json 的 description 就是这句话的实现版the model writes a short Markdown draft; the bundled CLI handles templates, SVG auto-layout and an STE controlled-writing check。Agent 技能文件 skills/answer-me-with-html/SKILL.md 对模型侧的约束非常直白You write only thecontent draft(extended Markdown). TheamCLI does all layout, colours, dark mode and diagram coordinates.Do not hand-write HTML / CSS / SVG.依赖面极小dependencies只有 dagrejs/dagre图布局和markedMarkdown 正文说明排版、配色、暗黑模式确实全部由 CLI 自带的模板与主题系统完成。理解了这个边界示例文档里的每一张图流程图、目录树、时序图都只是 CLI 管线的可视化表达下文逐一展开。2. 一次 render 的全过程原文面板 A 用项目自己的flow组件语法画出了主管线这是一段可以直接交给am render渲染的草稿语法fence 语言即组件名(Markdown 稿件) - parse: frontmatter 面板 parse - STE lint 组件渲染 STE lint -- 终端警告 组件渲染 - dagre 布局: flow 组件渲染 dagre 布局 - 模板与插槽 模板与插槽 - *[(单文件 HTML)] group render.js: parse, STE lint, 组件渲染, dagre 布局, 模板与插槽这张图的 group 框就标在render.js上——五个环节全部发生在 src/render.js 的renderDoc()里CLI 入口 src/cli.js 的cmdRender只是读文件、调它、落盘。按源码顺序拆解2.1 parse从 frontmatter 到面板与块解析逻辑在 src/parse.js 的parseDoc()文件头注释一句话概括frontmatter → meta;##headings → panels (slots); panel bodies → markdown blocks and fenced blocks且只做结构切分不做渲染。要点frontmatter 白名单src/parse.js 的CHOICES定义了合法取值——template: sheet | doc | video、theme: auto | 主题名、style: off | 80 | strict、mode: auto | light | dark。示例草稿用了template: doctheme: shadcn分别对应单列线性讲解页面板 ≥3 时带目录和卡片风格主题渲染截图左侧的 A/B/C/D 目录就是 doc 模板的目录栏。面板切分每个## 标题开一个面板字母 IDA、B、C…可省略、自动分配assignIdssrc/parse.js## A 标题 {span2}形式的面板属性也在这里解析。块切分正文按 Markdown 块md与 fence 块fence带语言与参数交替切分行号一律按源文件 1-based 记录——这就是后面所有报错都能精确到L14的基础。默认值DEFAULT_META给出template: sheet、theme: auto、style: 80、mode: auto、cols: 3src/parse.js命令行参数通过applyOverrides覆盖草稿与配置src/render.js。2.2 主题解析与 STE lint解析之后renderDoc先处理主题theme: auto会被pickTheme落成一个真实主题——页面场景下doc 模板或不含任何图形块的草稿选paper否则选blueprintsrc/themes/registry.js。落定的主题会写进页面供页内主题切换器使用。接着是 STE 受控写作检查详见第 4 节style: off直接跳过style: strict且存在警告时抛LintError不写页面src/render.js默认的80只产生警告、随输出一起打印。2.3 组件渲染每个 fence 块按语言名查组件注册表 src/components/index.js。从源码结构看当前注册了9 个组件callout、kv、timeline、annot、tree、limits、sequence、flow、ask示例文档目录树里写的是 8 个可视为早期版本的快照。语言是html/svg的 fence 走 escape hatch 原样嵌入其他语言则是代码块支持src引用真实文件、diff语法等见am help code。组件的render()返回 HTML异常统一包装成带line/component/example字段的RenderErrorsrc/render.js为第 6 节的错误闭环提供数据。2.4 dagre 布局涉及图形的块示例里的flow在这一阶段由 dagre 计算坐标并画出 SVG详见第 3 节。2.5 模板与插槽产出单文件 HTML最后renderDoc用 src/templates/ 里的模板sheet/doc把 intro 与面板 HTML 填进插槽再由 src/render.js 的shell()组装外壳。所谓单文件体现在style里内联整套主题 CSSpageCss含暗黑模式 token页脚内联 runtime JS主题/明暗切换、lightbox 放大、复制按钮原稿保存在隐藏的#am-source中sourceTag这正是am patch能对成品页就地替换单个面板的前提src/cli.js图片被内联为 data URI代码块引用真实文件后一并嵌入——页面离线可开、不依赖任何网络资源。输出默认落在~/.answer-me-with-html/pages/可用环境变量AM_HOME移动文件名由标题 slug 加时间戳构成src/cli.js。3. 图形层模型只写关系坐标全部交给 dagre示例面板 A 的图就是flow组件画的。flow的契约在 src/components/flow.js方向参数TB | LR | BT | RL默认 TB如flow LRA - B: label实线、A -- B虚线A - B C扇出行尾: label是边标签方括号决定形状(round)圆角矩形、{diamond}菱形、[(cylinder)]圆柱数据库、[rect]矩形*节点高亮group 组名: B, C画分组框对应示例图里包住五个环节的group render.js: ...。layout()的实现src/components/flow.js说明了模型不写坐标是怎么落地的节点尺寸不是拍脑袋的常量nodeSize()先用文本测量measure/wrap上限 150 字符换行算出宽高中再乘形状系数菱形要放大 1.5/1.6 倍。建图new dagre.graphlib.Graph({ compound: groups.length 0, multigraph: true })setGraph({ rankdir, nodesep: 36, ranksep: 46, ... })分组用setParent挂成 compound cluster。dagre.layout(g)之后节点读g.node()的中心坐标、边读g.edge().points再用clipEnds()修正菱形端点否则箭头会悬浮在菱形斜边外。最终输出的 SVG 里每条边/节点带data-key与视频模式下按源行号的data-step支持页面内的变更标记/-/~增删改与视频逐行步进。这就是分工表里计算图形坐标 | CLIdagre的完整含义草稿里只出现parse - STE lint 组件渲染这样的关系描述x/y一个都不写。4. STE 受控写作检查CLI 替读者把关文风分工表最后一行检查写作风格 | CLISTE lint对应 src/lint/ste.js。它只约束稿件里的说明性文字核心规则src/lint/ste.js句长中文陈述句 ≤45 字、程序性句子编号列表项≤35 字英文分别为 25 词 / 20 词段长每段最多 6 句MAX_SENTENCES英语查未收录词表src/lint/wordlist.en.js并给出替换建议正则识别被动语态中文查轻动词、的字链和套话src/lint/wordlist.zh.js日语含假名只查句长与段长其他语言只用语言中性的长度规则代码、行内代码、标题、带no状态的表格行、除callout外的组件内容全部跳过src/lint/ste.js 文件头注释。严格度由 frontmatter 的style控制三档行为不同off不检查80默认只警告页面照写警告随输出打印strict下任何警告都会让渲染失败LintErrorno page was writtensrc/render.js、src/render.js。也可以单独跑 src/cli.js 的cmdLintam lint file [--style off|80|strict]只查不渲染strict下有警告时退出码为 1。5. 目录结构原文面板 C 用tree组件给出了精简目录树同样是草稿语法可直接渲染answer-me-with-html bin/am.js | CLI 入口 src/ parse.js | 稿件 → 面板与块 render.js | 主流程 components/ | 8 个组件 lint/ | STE 受控写作检查 themes/ | blueprint 与 shadcn 两套主题 skills/answer-me-with-html/ | Agent Skill对照当前仓库这棵树的主干依旧准确但有两处演进以当前源码为准components/现在注册了 9 个组件新增ask等见 src/components/index.jsthemes/的内置主题有 4 套blueprint、shadcn、paper、3b1bsrc/themes/registry.js其中3b1b面向视频此外还有src/languages/页面语言与字体、src/runtime/浏览器端运行时、src/video/讲解视频管线等示例树未列出的模块。Agent Skill 一侧skills/answer-me-with-html/ 除SKILL.md外还带references/settings、video与scripts/am.mjs是模型侧的入口CLI 侧 bin/am.js 注册为am与answer-me-with-html两个可执行命令package.json。6. 出错时怎么办带正确示例的自修复闭环原文面板 D 用时序图描述了 Agent 视角的错误处理模型 - am: render 稿件 am -- 模型: ✗ L14 [flow] 错误 正确示例 模型 - 模型: 按示例修正 模型 - am: 再次 render am -- 模型: ✓ 页面路径这个闭环的每一环都有源码支撑错误从哪来组件解析失败抛ComponentError被 src/render.js 捕获后连同组件自带的example每个组件注册时都提供了最小正确示例见 src/components/flow.js包装成RenderError。怎么报给模型src/cli.js 的reportError打印三行——✗ L14 [flow] message、缩进的Correct example:正确示例、Full syntax: am help flow指向完整语法文档退出码 1。模型拿到的是可直接粘贴的修法而不是一句语法错误。另一类失败style: strict下的 lint 失败走LintError分支列出全部警告并声明no page was writtensrc/cli.jsfrontmatter 取值非法则走ParseError如Invalid theme value …。成功路径emit()打印✓ 文件路径加一行摘要doc · shadcn · 4 panels · flow×1并列出内嵌的代码文件与各类警告src/cli.js。因为RenderError强制携带line与component且所有解析器从第一天起就维护 1-based 行号src/parse.js 头注释第几行、哪个组件、改成什么样三要素齐备模型按示例修正后再次 render 即可收敛——这正是时序图最后一帧✓ 页面路径的来源。7. 自己跑一遍这个示例前置条件是 Node 20package.json 的engines安装方式见 INSTALL.md。然后直接以仓库内这份草稿为输入am render examples/architecture.md # 渲染出 doc 模板 shadcn 主题的单文件页面 am lint examples/architecture.md # 只跑 STE 检查 am list # 列模板、主题、组件 am help flow # 查看 flow 组件语法与示例输出默认写入~/.answer-me-with-html/pages/终端打印✓ 路径并按配置自动打开浏览器。页面顶部的主题/明暗切换器说明配色、暗黑模式确实由 CLI 负责切换只是运行时换 token页面本身已经内联了所有主题的 CSS。小结answer-me-with-html 的架构本质是一次职责切分——模型侧的产物被收窄为一份结构化的 Markdown 内容稿frontmatter ##面板 组件 fence而 src/parse.js 的解析、src/lint/ste.js 的文风检查、src/components/flow.js 的 dagre 布局、src/templates/ 的模板组装全部收敛在 src/render.js 一条管线里最终产出可离线打开、保留原稿可 patch 的单文件 HTML。理解了这条管线就能解释为什么模型不写 CSS、JS 和 SVG 坐标依然能稳定产出排版一致的讲解页。赞分享【免费下载链接】answer-me-with-htmlAnswer me with HTML — an agent skill that answers hard questions with a one-page HTML you can actually read. 让 AI Agent 用一页 HTML 回答复杂问题。项目地址https://gitcode.com/gh_mirrors/an/answer-me-with-html点击查看免费下载相关推荐用专属 Agent 维护演讲演示文稿presentation-claude-gemini 如何守护 52 页单文件 HTML 幻灯片用专属 Agent 维护演讲演示文稿presentation claude gemini 如何守护 52 页单文件 HTML 幻灯片 本指南围绕 claude文档教程AI 技能html-anything resume-modern 技能解析从一份 Markdown 简历到 A4 单页极简简历 HTMLhtml anything resume modern 技能解析从一份 Markdown 简历到 A4 单页极简简历 HTML 本文围绕 html anythAI 应用人工智能AI AgentAI 写作媒体生成Quartz 插件详解ContentPage 页面类型插件如何为 Markdown 内容生成完整 HTML 页面Quartz 插件详解ContentPage 页面类型插件如何为 Markdown 内容生成完整 HTML 页面 ContentPage 是 Quartz v前端开发工具CLI上一篇终极安全审计指南如何识别和修复fishhook符号重绑定问题下一篇FastAPI OpenAPI Callbacks 实战用 Swagger UI 文档化你的 API 回调接口创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考