# 数学历史 **Repository Path**: wangyidao/math-history ## Basic Information - **Project Name**: 数学历史 - **Description**: 探索数学发展史的开源项目,整理古今数学思想、定理演变与关键人物贡献,助力数学教育与历史研究。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-08-03 - **Last Updated**: 2026-08-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 世界数学发展史 · math-history 一个用 [Astro](https://astro.build) 构建的静态网站,以**时间轴、数学问题、学科分支结构图、数学奖项**四条主线呈现世界数学的发展脉络。数据(内容)与展示(界面)完全分离——你只需写 Markdown 文件,网站会自动生成页面、列表和筛选。 > 站点口号:从巴比伦到当代,数学的思想脉络。 --- ## 1. 技术栈 | 类别 | 选型 | |---|---| | 框架 | Astro 5(`静态输出` 模式) | | 内容 | Astro Content Collections(Markdown + Zod schema) | | 公式 | KaTeX(remark-math + rehype-katex) | | 结构图 | Cytoscape.js + cytoscape-fcose(可交互关系图) | | 主题 | 原木 Nordic 风格(OKLCH 变量 + 真实暗色模式) | | 字体 | Manrope / JetBrains Mono / Noto Sans SC(自托管) | | 产物 | RSS、sitemap、404 | --- ## 2. 快速开始 ```bash npm install # 安装依赖(首次) npm run dev # 本地开发,带热更新,默认 http://localhost:4321 npm run build # 生成静态站点到 dist/ npm run preview # 本地预览已构建的 dist/ ``` > 要求 Node 18.20+ / 20+(Astro 5 需要 Node ≥ 18.20.8 或 ≥ 20.3)。 --- ## 3. 项目结构 ``` math-history/ ├─ src/ │ ├─ content.config.ts # ★ 内容数据契约(每个字段的类型定义) │ ├─ content/ # ★ 你主要在这里写内容 │ │ ├─ milestones/ # 时间轴里程碑(.md) │ │ ├─ problems/ # 数学问题(.md) │ │ ├─ fields/ # 学科 / 分支(.md) │ │ ├─ awards/ # 数学奖项(.md) │ │ └─ laureates/ # 获奖人(.md) │ ├─ data/ │ │ └─ fields-graph.json # 结构图数据(由脚本生成,勿手改) │ ├─ layouts/ # 页面骨架(Base / Detail) │ ├─ components/ # 卡片、时间轴项、筛选条等 │ ├─ pages/ # 路由 + 渲染 │ ├─ styles/global.css # 主题与设计变量 │ └─ consts.ts # 站点标题、时代/领域/状态枚举 ├─ scripts/ │ ├─ gen_fields_graph.py # 生成结构图数据 │ ├─ gen_sitemap.mjs # 构建环境补生成 sitemap(见 §7) │ ├─ _validate.py # 内容校验工具(milestones / 跨引用) │ ├─ _validate_awards.py # 内容校验工具(awards / laureates / 跨引用) │ └─ fetch_awards_by_year.py # 按年份抓取/脚手架化获奖人(见 §4.10) ├─ astro.config.mjs # 站点域名、sitemap、KaTeX 插件 └─ package.json ``` **核心原则**:`src/content/` 是唯一需要你动笔的地方。新增一个 `.md` 文件,网站就会自动多出对应页面并出现在列表/时间轴/筛选里——无需改路由或索引。 --- ## 4. ★ 如何增加内容 所有内容都是 `src/content/<集合>/.md` 文件:顶部 `---` 之间是 **YAML 前置字段(结构化数据)**,下方是 **Markdown 正文(叙述)**。 > **slug = 文件名(不含 `.md`)**。例如 `src/content/fields/number-theory.md` 的 slug 是 `number-theory`。跨引用(见 §4.4)填的就是这个文件名。 ### 4.1 时间轴里程碑(milestones) 新建 `src/content/milestones/.md`: ```markdown --- title: 欧几里得《几何原本》 summary: 公理化几何的奠基之作,影响西方数学两千年。 year: -300 # 数字年份;公元前用负数,或写成 "约公元前300年" era: 古代 # 见下方 era 取值 region: 古希腊 # 文明 / 地域 culture: 古希腊数学 # 可选 relatedProblems: [riemann-hypothesis] # 可选,关联问题的 slug 数组 relatedFields: [geometry] # 可选,关联分支的 slug 数组 draft: false # true = 不发布(草稿) --- 正文用 Markdown 书写。可插入公式:行内 $a^2+b^2=c^2$, 独立成段用块级: $$ \int_{-\infty}^{\infty} e^{-x^2}\,dx = \sqrt{\pi} $$ ``` `era` 取值(必须其一):`古代` / `中世纪` / `文艺复兴` / `17世纪` / `18世纪` / `19世纪` / `20世纪` / `当代`。 ### 4.2 数学问题(problems) 新建 `src/content/problems/.md`: ```markdown --- title: 费马最后定理 summary: 当整数 n>2 时,方程 xⁿ+yⁿ=zⁿ 没有正整数解。 status: solved # solved / unsolved / partial 三选一 proposedYear: 1637 # 可选 proposedBy: 皮埃尔·德·费马 # 可选 field: number-theory # 可选,主属分支 slug significance: 数论史上的里程碑 # 可选,卡片摘要 latestProgress: 1994 年安德鲁·怀尔斯给出证明 # unsolved / partial 才需要 references: # 可选,参考资料 - title: 维基百科:费马最后定理 url: https://zh.wikipedia.org/wiki/费马最后定理 # 必须是完整 http(s) 链接 draft: false --- 正文分几块写:提出背景、详细描述、解决过程(或最新进展)。 未解决 / 部分解决的问题,重点写 `latestProgress` 里提到的近期突破。 ``` `status` 取值:`solved`(已解决)/ `unsolved`(未解决)/ `partial`(部分解决)。 卡片上会用不同颜色的徽章区分;`unsolved`/`partial` 必须填 `latestProgress`。 ### 4.3 学科 / 分支(fields) 新建 `src/content/fields/.md`: ```markdown --- nameZh: 数论 nameEn: Number Theory msc: "11" # 可选,MSC-2020 一级代码 area: 代数与数论 # 见下方 area 取值 parent: null # 可选,父节点 slug(结构图用) related: [algebraic-geometry, group-theory] # 可选,横向相关分支 slug background: 数论研究整数及其推广对象的性质…… # 产生背景 mainQuestions: # 主要研究问题(要点列表) - 素数在整数中的分布规律 - 丢番图方程的可解性与解的结构 draft: false --- 正文可补充更细的介绍、代表人物、经典结果等。 ``` `area` 取值(必须其一):`基础与逻辑` / `代数与数论` / `分析` / `几何与拓扑` / `应用与计算`。 > 分支的**详情页和卡片列表是全自动的**——丢一个 `.md` 文件即可。 > 但要让它出现在首页的**可交互结构图**里,还需额外一步,见 §4.7。 ### 4.4 数学奖项(awards) 新建 `src/content/awards/.md`(slug 建议用英文短名,如 `fields-medal`): ```markdown --- title: 菲尔兹奖 nameEn: Fields Medal established: 1936 foundedBy: 国际数学联盟(IMU) frequency: 每四年一次,获奖者须在该年元旦前未满 40 岁 prize: 金牌一枚及约 15,000 加元 description: 公认数学界最高荣誉,常被誉为"数学界的诺贝尔奖" criteria: 表彰已取得杰出成就且具有未来领袖潜力的数学家 draft: false --- 正文写奖项设立背景、历史与评选特点(可用小标题)。 ``` `award` 的 slug 是**固定的六个之一**:`fields-medal` / `abel-prize` / `wolf-prize` / `chern-medal` / `breakthrough-prize` / `shaw-prize`。奖项详情页会自动罗列其全部获奖人(按年份倒序),无需手动登记。 ### 4.5 获奖人(laureates) 新建 `src/content/laureates/.md`。slug 建议 `<奖项slug>-<年份>-<英文名>`(全小写、连字符),例如 `fields-1936-ahlfors`、`abel-2016-wiles`,保证唯一: ```markdown --- name: 安德鲁·怀尔斯 nameEn: Andrew Wiles award: abel-prize # 必须六选一(见 §4.4) year: 2016 # 获奖年份(数字) nationality: 英国 # 可选 birthYear: 1953 # 可选 contribution: 因彻底证明费马最后定理而获奖 # 一句话获奖原因(卡片用) landmark: true # true=含"问题来龙去脉"长文;false=仅摘要 relatedFields: [number-theory] # 可选,关联分支 slug relatedProblems: [fermat-last-theorem] # 可选,关联问题 slug draft: false --- ## 获奖原因 <详述其获奖的主要工作与贡献,为何重要> ## 问题来龙去脉 ``` - `landmark: true` 的条目:详情页会渲染完整的「获奖原因 + 问题来龙去脉」;`false` 则正文写 200–400 字摘要即可。 - `relatedFields` / `relatedProblems` 同样遵循 §4.6 的 slug 规则(填错成死链,不报错)。 ### 4.6 跨引用(slug)规则 - `relatedProblems` / `relatedFields`(里程碑)、`field`(问题)、`parent` / `related`(分支)、以及获奖人的 `relatedFields` / `relatedProblems` 填的都是**别的 `.md` 文件的文件名(slug)**。 - 填错只会变成**死链**,**不会让构建报错**。写完后用 §6 的校验脚本对一下。 - 推荐做法:先确定要引用的文件存在,再回填 slug。 ### 4.7 让新分支出现在结构图里(仅 fields 需要) 结构图数据来自 `scripts/gen_fields_graph.py` 里**硬编码的字段表**,不是直接读 frontmatter。所以新增分支后: 1. 在 `scripts/gen_fields_graph.py` 的 `FIELDS` 列表里加一行(格式见脚本内已有条目); 如需横向连线,在 `RELATED` 列表里加一对 `(slugA, slugB)`。 2. 运行脚本重新生成图数据: ```bash python scripts/gen_fields_graph.py ``` 它会重写 `src/data/fields-graph.json`(68 节点 / 118 边这类输出即成功)。 3. 重新 `npm run build`。 > 想彻底免去这步?可以把脚本改成直接读 `src/content/fields/*.md` 的 frontmatter 来生成图——这样加分支就是纯纯的「丢一个 .md」。需要的话可以提个需求。 ### 4.8 公式(KaTeX) 正文里任何位置都能用 LaTeX: - 行内:`$E = mc^2$` - 块级:`$$ \sum_{n=1}^{\infty}\frac{1}{n^2} = \frac{\pi^2}{6} $$` 构建时自动渲染,无需额外配置。 ### 4.9 草稿模式 任意文件加 `draft: true` 即不会被发布,适合先囤素材、逐步补全。设为 `false`(或删掉该行)即发布。 ### 4.10 按年份抓取获奖记录(fetch_awards_by_year.py) 某一年度的获奖名单公布后,可用本脚本快速搭好获奖人**草稿文件**,再人工补全与发布。脚本只依赖 Python 标准库(无需 `pip install`),在 `math-history/` 根目录运行即可。 ```bash # 1) 联网自动抓取某年「全部适用奖项」的获奖人,并生成草稿 python scripts/fetch_awards_by_year.py --year 2026 # 2) 只抓某个奖项 python scripts/fetch_awards_by_year.py --year 2026 --award fields-medal # 3) 无网络 / 自动提取不全时,手动给出英文名直接脚手架(最稳妥,推荐) python scripts/fetch_awards_by_year.py --year 2026 --award fields-medal \ --names "Yu Deng, Hong Wang, John Pardon, Jacob Tsimerman" # 4) 先预览将要创建哪些文件,不落盘 python scripts/fetch_awards_by_year.py --year 2026 --dry-run # 5) 只打印该年各奖项的官方来源链接(不抓取、不生成文件) python scripts/fetch_awards_by_year.py --year 2026 --no-fetch # 6) 把抓取到的名单额外导出成 JSON(便于二次处理) python scripts/fetch_awards_by_year.py --year 2026 --json awards-2026.json ``` **脚本做了什么** - 按本站点约定生成 `src/content/laureates/<前缀>-<年份>-<英文名>.md`。文件名前缀对照:`fields-medal→fields`、`abel-prize→abel`、`wolf-prize→wolf`、`chern-medal→chern`、`breakthrough-prize→breakthrough`、`shaw-prize→shaw`(与 §4.5 示例 `fields-1936-ahlfors` / `abel-2016-wiles` 一致)。 - 文件一律标记为 `draft: true`,并在正文写下官方来源链接——**不会自动发布**。 - 已存在的 slug 自动跳过,不覆盖、也不生成 `-2` 重复文件;同年同姓的两位获奖人会用 `-2` / `-3` 自动区分。 **生成后你还要做(重要)** 1. 打开生成的 `.md`:补 `name`(中文名)、`nationality`、`birthYear`、`contribution`;重点人物把 `landmark` 改为 `true` 并补写「问题来龙去脉」长文。 2. 确认无误后,把 `draft` 改为 `false` 再发布。 3. 视情况更新对应奖项页(§4.4)正文里的「历届列表 / 累计人数」等文字。 4. 跑一遍 `python scripts/_validate_awards.py` 确认无死链(`ERRORS: 0`)。 > ⚠️ 自动抓取来自维基百科表格,属 best-effort 解析,**可能漏人、错名或抓到非获奖人**。生成后务必对照官方来源人工校对,再发布——这也契合本站点「不错不漏」的原则。沃尔夫奖每年轮换学科(部分年份无数学奖),更需以官网为准。 --- ## 5. 内容契约(schema) 字段类型由 `src/content.config.ts` 用 Zod 定义。构建时 Astro 会按此校验每个 `.md`——**字段缺失或类型不对会导致构建失败**,按报错补字段即可。三个集合的字段见 §4.1–§4.3 的模板(带 `★` 的是必填)。 --- ## 6. 校验工具 写完后想自检有没有填错(尤其跨引用 slug 对不上),运行: ```bash # 校验时间轴 / 学科分支的跨引用 cd src/content/milestones python ../../../scripts/_validate.py # 校验奖项 / 获奖人的跨引用与 slug 唯一性 cd ../../.. python scripts/_validate_awards.py ``` `_validate.py` 会检查:必填字段是否齐全、`era` 取值是否合法、`relatedProblems` / `relatedFields` 是否指向已存在的 slug。`_validate_awards.py` 会检查:奖项文件是否齐全、获奖人 `award` 取值是否合法、slug 是否唯一、`relatedFields` / `relatedProblems` 是否指向已存在的 slug。输出 `ERRORS: 0` 即通过。 (这只是一个轻量辅助检查;构建本身的 Zod 校验才是强制关卡。) --- ## 7. 部署与 sitemap 说明 - **部署**:把 `npm run build` 生成的 `dist/` 整个目录丢到任意静态托管(GitHub Pages / Vercel / Netlify / Nginx)即可。 - **上线前**:把 `astro.config.mjs` 里的 `site: 'https://math-history.example.com'` 改成你的真实域名(sitemap 和 RSS 都依赖它)。 - **sitemap**:正常情况下 `npm run build` 会自动生成 `sitemap-index.xml` + `sitemap-0.xml`。若你所在环境在构建末尾清理阶段异常(导致 sitemap 缺失),可手动补生成: ```bash node scripts/gen_sitemap.mjs # 扫描 dist/ 生成 sitemap + robots.txt ``` 在能正常跑 `astro build` 的机器上无需此步。 --- ## 8. 常见问题 **Q:加了一篇,但页面没出现?** A:检查文件名(slug)是否符合约定、frontmatter 里 `draft` 是否为 `false`、以及 `---` 包裹的 YAML 是否有语法错误(比如 `:` 后面的值含冒号没加引号)。 **Q:年份怎么写公元前?** A:用负数(如 `year: -300` 会显示为「公元前 300」),或写成字符串 `year: "约公元前300年"`。 **Q:references 的 url 报错?** A:`url` 必须是合法 URL(`z.string().url()`),必须以 `http://` / `https://` 等开头,不能只写域名。 **Q:结构图里看不到我新加的分支?** A:分支详情页会自动有,但结构图需要按 §4.7 把条目加进 `gen_fields_graph.py` 并重跑脚本。 **Q:想改界面 / 配色 / 字体?** A:主题变量集中在 `src/styles/global.css`,站点文案/枚举在 `src/consts.ts`,布局在 `src/layouts/`,组件在 `src/components/`——这些一般不需要动,除非要定制外观。