natolambert/colloquium

GitHub: natolambert/colloquium

一款面向学术人员的 Markdown 原生幻灯片工具,支持 AI 驱动、Git 友好和单文件 HTML 输出。

Stars: 224 | Forks: 15

# 研讨会 用于学术报告演讲的基于 Markdown 的幻灯片创建工具。对 Git 友好,可由 AI 驱动,支持输出单文件 HTML。 **[文档](https://natolambert.github.io/colloquium/)** · **[核心示例 (RLHF Book)](https://rlhfbook.com/course)** · **[PyPI](https://pypi.org/project/colloquium/)** ## 安装说明 Colloquium 使用 [uv](https://docs.astral.sh/uv/) 进行快速、可靠的 Python 包管理。 ``` uv tool install colloquium # 或在 project 内部 uv pip install colloquium ``` 用于开发环境: ``` git clone https://github.com/natolambert/colloquium.git cd colloquium uv pip install -e ".[dev]" ``` ## 快速开始 创建一个 Markdown 文件: ``` --- title: "My Talk" author: "Jane Doe" date: "2026-02-22" --- # 我的 Talk Jane Doe --- ## Key Results - Finding one - Finding two --- ## 结论 Thanks for listening! ``` 构建它: ``` colloquium build slides.md # → slides.html colloquium serve slides.md # dev server with live reload colloquium export slides.md # PDF via a headless Chromium-based browser colloquium capture slides.md # per-slide PNGs for AI review ``` ## CLI 命令 | 命令 | 描述 | |---------|-------------| | `colloquium build ` | 构建为独立的 HTML | | `colloquium serve ` | 带有实时刷新的开发服务器 | | `colloquium export ` | 导出为 PDF(需要基于 Chromium 的浏览器) | | `colloquium capture ` | 将幻灯片捕获为单独的 PNG | ## Frontmatter 参考 所有配置都放在文件顶部的 YAML frontmatter 块中。 ``` --- title: "Talk Title" author: "Author Name" date: "2026-02-22" theme: default aspect_ratio: "16:9" fonts: heading: "Playfair Display" # Google Font for h1/h2/h3 body: "Source Sans 3" # Google Font for body text footer: left: "https://example.com/logo.png" # image URL → logo, plain text → text center: "My Talk Title" right: "auto" # "auto" → slide numbers "3 / 12" custom_css: ".slide h2 { color: red; }" # inline CSS overrides --- ``` | 键 | 默认值 | 描述 | |-----|---------|-------------| | `title` | `"Untitled"` | 演示文稿标题(用于 `` 和标题幻灯片) | | `author` | `""` | 作者姓名 | | `date` | `""` | 日期字符串 | | `theme` | `"default"` | 主题名称 | | `aspect_ratio` | `"16:9"` | 幻灯片宽高比 | | `fonts.heading` | Inter | 标题的 Google Font | | `fonts.body` | Inter | 正文文本的 Google Font | | `footer.left` | `""` | 左侧页脚区域(文本、图片 URL 或 `"auto"`) | | `footer.center` | `""` | 中间页脚区域 | | `footer.right` | `"auto"` | 右侧页脚区域(`"auto"` = 幻灯片页码) | | `custom_css` | `""` | 注入页面的额外 CSS | 页脚文本支持 `{n}`(当前幻灯片页码)和 `{N}`(幻灯片总数)以用于自定义计数器,例如 `"Lambert {n}/{N}"` → `"Lambert 6/23"`。 当完全省略 `footer:` 时,将使用仅在右侧区域带有幻灯片计数器的最简页脚。 使用 `{n}` 和 `{N}` 占位符将当前幻灯片页码和总页数内联嵌入到文本中: ``` footer: left: "rlhfbook.com" right: "Lambert {n}/{N}" # renders as "Lambert 3/25" ``` 如果没有区域使用 `"auto"`、`{n}` 或 `{N}`,幻灯片计数器将自动放置在第一个空白区域中。 ## 幻灯片结构 幻灯片之间通过单独一行的 `---` 进行分隔。每张幻灯片中的第一个标题将成为幻灯片标题: | 标题 | 行为 | |---------|----------| | `# Title` | 标题幻灯片 — 居中、大字号文本、`slide--title` 布局 | | `## Title` | 内容幻灯片 — 顶部带有标题的标准布局 | | `###` 至 `######` | 在幻灯片内容中渲染为副标题 | ``` # 欢迎 ← 标题 slide (居中, 大号) --- ## Key Results ← 内容 slide (标题 + 正文) ### Sub-section ← 在 slide 正文中渲染为 h3 Normal paragraph text. ``` ## 幻灯片指令 通过 HTML 注释进行单张幻灯片配置。可以将它们放置在幻灯片中的任何位置。 ``` ## 我的 Slide <!-- layout: section-break --> <!-- class: highlight special --> <!-- style: background: #1a1a2e --> <!-- notes: Remember to mention X --> <!-- align: center --> <!-- valign: bottom --> <!-- columns: 2 --> <!-- rows: 35/65 --> <!-- padding: compact --> <!-- size: large --> <!-- title: hidden --> ``` ### 布局 | 指令 | 效果 | |-----------|--------| | `<!-- layout: title -->` | 居中的标题幻灯片(与 `# Heading` 配合使用) | | `<!-- layout: title-left -->` | 左对齐的标题幻灯片,带有堆叠的元数据 | | `<!-- layout: title-sidebar -->` | 宽标题,带有右侧元数据栏 | | `<!-- layout: title-banner -->` | 编辑型标题幻灯片,大标题在顶部,元数据靠近底部 | | `<!-- layout: content -->` | 默认内容布局(与 `## Heading` 配合使用) | | `<!-- layout: section-break -->` | 深色强调背景,居中文本 | | `<!-- layout: two-column -->` | 双列网格布局 | | `<!-- layout: image-left -->` | 图片在左,文本在右 | | `<!-- layout: image-right -->` | 文本在左,图片在右 | | `<!-- layout: code -->` | 针对大段代码块优化 | ### 分列 使用 `|||` 分割列之间的内容: ``` <!-- columns: 2 --> ## 结果 Left column content ||| Right column content ``` | 值 | 效果 | |-------|--------| | `2` | 两个等宽列 | | `3` | 三个等宽列 | | `60/40` | 60%/40% 分割 | | `40/60` | 40%/60% 分割 | | `70/30` | 70%/30% 分割 | | `30/70` | 30%/70% 分割 | 允许使用任意数字比例,例如 `25/75`、`33/67` 或 `1/2/1`。 ### 分行 使用 `===` 分割行块之间的内容,实现幻灯片垂直分割: ``` <!-- rows: 35/65 --> ## 概述 Top row content === Bottom row content ``` | 值 | 效果 | |-------|--------| | `2` | 两个等高行 | | `3` | 三个等高行 | | `60/40` | 60%/40% 分割 | | `40/60` | 40%/60% 分割 | | `35/65` | 35%/65% 分割 | | `65/35` | 65%/35% 分割 | | `70/30` | 70%/30% 分割 | | `30/70` | 30%/70% 分割 | 此处同样允许使用任意数字比例,例如 `25/75` 或 `20/30/50`。 要在特定的行块内使用列布局,请在该行的顶部添加行级局部指令: ``` <!-- rows: 35/65 --> ## 概述 <!-- row-columns: 40/60 --> Left text ||| Right text === ![Wide image](https://raw.githubusercontent.com/natolambert/colloquium/main/figure.png) ``` 在幻灯片根级别,使用 `columns:` 或 `rows:`。对于嵌套布局,请在行块内使用 `row-columns:`。 ### 文本与间距 | 指令 | 可选值 | |-----------|--------| | `<!-- align: ... -->` | `left`、`center`、`right` | | `<!-- valign: ... -->` | `top`、`center`、`bottom` | | `<!-- size: ... -->` | `small` (20px)、`normal` (24px)、`large` (28px) | | `<!-- padding: ... -->` | `compact` (30px)、`normal` (60px)、`wide` (90px) | | `<!-- title: ... -->` | `top`、`center`、`hidden` | ### 其他 | 指令 | 描述 | |-----------|-------------| | `<!-- class: name1 name2 -->` | 为幻灯片添加 CSS 类 | | `<!-- style: css-here -->` | 幻灯片元素上的内联 CSS | | `<!-- notes: text -->` | 演讲者备注(在演示视图中隐藏) | | `<!-- after: references -->` | 将此幻灯片移动到自动生成的参考文献幻灯片之后;不计入页脚的 `{N}` 总数中 | | `<!-- class: figure-captions -->` | 将该幻灯片上的独立 Markdown 图片转换为带有编号的图表,说明文字取自 `![alt](https://raw.githubusercontent.com/natolambert/colloquium/main/...)` | | `<!-- class: no-figure-captions -->` | 对特定幻灯片禁用全局的图表说明文字 | | `<!-- img-align: center -->` | 仅对齐图片(`left`、`center`、`right`)— 不影响标题 | | `<!-- img-valign: top -->` | 在网格/行单元格中垂直对齐独立图片(`top`、`center`、`bottom`) | | `<!-- img-fill: true -->` | 扩展图片以填满可用的幻灯片空间 | | `<!-- img-overflow: true -->` | 让网格单元格中的图片溢出其盒子,而不是缩放适应内部 | 请参阅[网站上的示例](https://natolambert.github.io/colloquium/)以获取已渲染的演示文稿和可直接复制粘贴的代码片段,或浏览 [`examples/`](./examples/) 中的源码。 ### 参考文献 Frontmatter 选项: ``` bibliography: refs.bib citation_style: author-year citation_order: auto ``` - `citation_style: numeric` 保持引用和参考文献按照首次出现的顺序排列。 - 非数值样式默认按字母顺序排序。 - 设置 `citation_order: appearance` 可以让作者-年份或标题-年份的引用保持源码中的顺序。 要在自动生成的参考文献之后添加附录或备用幻灯片,请将它们放在 Markdown 文件的末尾并添加一个幻灯片指令: ``` --- <!-- after: references --> ## Backup 分析 Extra material ``` 这些位于参考文献之后的幻灯片将在参考文献部分之后渲染,但它们不会计入页脚的 `{N}` 总数中。如果主要演讲加上生成的参考文献总计 30 张幻灯片,则参考文献之后的第一张幻灯片编号为 `31/30`。 ## 内容功能 **数学公式** (KaTeX) — 行内公式 `$E=mc^2$` 和块级公式 `$$\sum_{i=1}^n x_i$$` **代码** (highlight.js) — 带有语言语法高亮的围栏代码块 **表格** — 标准 Markdown 表格 **图片** — `![alt](https://raw.githubusercontent.com/natolambert/colloquium/main/url)` 自动调整尺寸(支持 SVG 矢量图) 要在整个演示文稿中启用带编号的图表说明文字,请将以下内容添加到 frontmatter 中: ``` figure_captions: true ``` 独立的 Markdown 图片将渲染为带有编号的图表,并使用 alt 文本作为说明: ``` ![Training recipe overview](https://raw.githubusercontent.com/natolambert/colloquium/main/assets/recipe.png) ``` 这将渲染为 `Figure 1: Training recipe overview`。留空 alt 文本即可隐藏说明文字: ``` ![](https://raw.githubusercontent.com/natolambert/colloquium/main/assets/recipe.png) ``` 如果你只想在选定的幻灯片上显示说明文字,请改用 `figure-captions` 作为幻灯片 class: ``` <!-- class: figure-captions --> ![Training recipe overview](https://raw.githubusercontent.com/natolambert/colloquium/main/assets/recipe.png) ``` 如果演示文稿启用了 `figure_captions: true`,请为不想显示说明的幻灯片添加 `no-figure-captions` 以将其排除。 ### 文本大小 使用 HTML class 属性控制任何元素或块的字体大小: ``` <span class="text-2xl">Big emphasis text</span> Normal paragraph text. <div class="text-sm"> - Dense bullet point one - Dense bullet point two </div> <span class="text-xs">Footnote or citation</span> <div class="colloquium-spacer-md"></div> <div class="colloquium-footnote"> This is useful for speaker-side caveats or details that should stay visually secondary. </div> ``` | 类名 | 缩放比例 | 用例 | |-------|-------|----------| | `text-xs` | 0.65em | 脚注、引用 | | `text-sm` | 0.8em | 密集的列表、细微细节 | | `text-base` | 1em | 默认 | | `text-lg` | 1.2em | 提示框 | | `text-xl` | 1.4em | 核心要点 | | `text-2xl` | 1.7em | 重点强调 | | `text-3xl` | 2.2em | 大号陈述文本 | | `text-4xl` | 2.8em | 核心文本 | ### 间距与脚注 当你想在正文和示例之间留出更多呼吸空间时,可以使用小型间隔块: ``` After pretraining we are left with a glorified autocomplete model. <div class="colloquium-spacer-md"></div> ```conversation messages: ... ``` ``` Available spacer helpers: - `colloquium-spacer-sm` - `colloquium-spacer-md` - `colloquium-spacer-lg` Use `colloquium-footnote` for secondary caveats or context inside the slide body: ```markdown <div class="colloquium-footnote"> Base models are also becoming more flexible through midtraining and related data mixtures. </div> ``` 对于位于页脚上方的幻灯片级脚注,请使用指令: ``` <!-- footnote: Base models are also becoming more flexible through midtraining. --> <!-- footnote-right: Right-aligned note for this slide. --> ``` 它们与浮动引用共享相同的左下角/右下角区域;当两者同时存在时,引用会堆叠在脚注上方。 对于行内编号脚注,请在希望标记出现的位置使用 `^[...]`: ``` This sentence ends with a numbered footnote.^[Base models are also becoming more flexible through midtraining.] ``` 行内脚注会汇集到同一个浮动页脚区域中,并按每张幻灯片单独编号。它们默认位于右侧;在需要时可显式设置所在侧: ``` <!-- footnotes: left --> ``` 请使用 [`examples/footnotes/`](./examples/footnotes/) 中的专用示例演示文稿获取可直接复制粘贴的代码片段。 ### 图表 在围栏代码块中使用 YAML,通过 Chart.js 实现行内图表: ```chart type: line height: 500 width: 800 data: labels: [Q1, Q2, Q3, Q4] datasets: - label: Revenue data: [10, 25, 40, 60] color: "#4AA691" options: scales: y: ticks: prefix: "$" suffix: "K" ``` | 键 | 默认值 | 描述 | |-----|---------|-------------| | `type` | `bar` | 图表类型:`line`、`bar`、`scatter`、`pie`、`doughnut` | | `height` | `400` | 容器高度(以像素为单位) | | `width` | `100%` | 容器宽度(以像素为单位,省略则表示满宽) | | `data.labels` | `[]` | X 轴标签 | | `data.datasets[].label` | `"Series N"` | 图例标签 | | `data.datasets[].data` | `[]` | 数据值 | | `data.datasets[].color` | auto | 系列颜色 | | `options.scales.{x,y}.ticks.prefix` | `""` | 添加在刻度标签前的前缀(例如 `"$"`) | | `options.scales.{x,y}.ticks.suffix` | `""` |添加在刻度标签后的后缀(例如 `"%"`) | | `options.scales.{x,y}.grid.display` | `true` | 显示/隐藏网格线 | ### 对话 在围栏代码块中使用 YAML 渲染 LLM 样式的聊天气泡: ```conversation size: 0.9 messages: - role: user content: "What is RLHF?" - role: assistant model: "Tülu 3 405B" content: "**RLHF** is a technique for aligning language models..." - role: system content: "You are a helpful AI assistant." ``` | 角色 | 样式 | |------|---------| | `user` | 右对齐气泡,强调色背景,白色文本 | | `assistant` | 左对齐气泡,code-bg 背景 | | `system` | 居中,带边框,柔和的斜体文本 | 消息内容支持 Markdown 格式(加粗、斜体、行内代码)。 可选的对话设置: | 键 | 默认值 | 描述 | |-----|---------|-------------| | `size` | 未设置 | 气泡字体缩放比例,为正数值,如 `0.9` 或 `1.05` | | `messages[].model` | 未设置 | 显示在角色旁边的可选模型标签,例如 `ASSISTANT (Llama 3.1 405B Base)` | ### 盒子 在围栏代码块中使用 YAML 渲染带圆角的提示卡片: ```box title: DPO became popular because: tone: accent content: | - Far simpler to implement - Far cheaper to run - Often reaches most of the final performance ``` 可选的盒子设置: | 键 | 默认值 | 描述 | |-----|---------|-------------| | `title` | 未设置 | 显示在盒子顶部的加粗标题 | | `tone` | `accent` | 视觉样式:`accent`、`muted` 或 `surface` | | `content` | 未设置 | 标题下方的可选 Markdown 正文 | | `size` | 未设置 | 字体缩放比例,为正数值,如 `0.9` 或 `1.05` | | `align` | 未设置 | 盒子内的文本对齐方式:`left`、`center` 或 `right` | | `compact` | `false` | 缩紧盒子内的段落和列表间距 | `box` 也支持仅包含标题的提示: ```box title: Core idea tone: accent ``` 支持的色调有: | 色调 | 用途 | |------|-----| | `accent` | 使用演示文稿强调色的高对比度高亮盒子 | | `muted` | 使用代码/背景表层、更柔和的辅助卡片 | | `surface` | 用于参考文献、注意事项或旁注的中性带边框面板 | ### Built With 徽章 使用常规布局工具在幻灯片中的任意位置渲染紧凑的 GitHub 徽章: ``` <!-- align: right --> <!-- valign: bottom --> ```builtwith repo: natolambert/colloquium ``` ``` 可选设置: | 键 | 默认值 | 描述 | |-----|---------|-------------| | `label` | `"Built with"` | 仓库名称上方的小标签 | | `repo` | `"natolambert/colloquium"` | GitHub 仓库 slug | | `url` | `https://github.com/<repo>` | 链接目标覆盖 | | `stars` | `auto` | 自动获取 GitHub star 数,设为 `false` 隐藏,或指定一个数值固定显示 | | `icon` | `true` | 显示/隐藏 GitHub 图标 | 因为它是一个普通的块级元素,你可以使用列、行、对齐工具或原始 HTML 包装器来放置它,而不必依赖特定的页脚行为。 ### 引用 将 `.bib` 文件添加到你的项目中,并在 frontmatter 中引用它: ``` --- bibliography: refs.bib citation_style: author-year # or "numeric" or "title-year" --- ``` 在幻灯片中使用 `[@key]` 进行引用: ``` The foundational work on RLHF [@christiano2017] introduced reward models. Multiple citations: [@christiano2017; @ouyang2022] ``` 系统会自动在末尾附加一张 **References** 幻灯片,其中仅包含已引用的文献。 | 键 | 默认值 | 描述 | |-----|---------|-------------| | `bibliography` | `""` | `.bib` 文件路径(相对于 Markdown 文件) | | `citation_style` | `"author-year"` | 引用格式:`author-year`、`numeric`、`title-year` | ## 键盘快捷键 | 按键 | 操作 | |-----|--------| | Right / Space / PgDn | 前进:下一个展示步骤,然后是下一张幻灯片 | | Left / PgUp | 后退:上一个展示步骤,然后是上一张幻灯片 | | Down / Up | 跳转到下一张 / 上一张幻灯片,并完全展示 | | 1–9 | 输入幻灯片页码以跳转并完全展示(按 Enter 提前确认,按 Esc 取消) | | Home | 第一张幻灯片 | | End | 最后一张幻灯片 | | C | 复制当前幻灯片的 Markdown 源码 | | F | 切换全屏 | | Escape | 取消输入的页码 / 关闭选择器 / 退出全屏(在全屏状态下,浏览器始终会在按 Esc 时退出全屏 — 这部分无法延迟执行) | 点击幻灯片计数器可打开幻灯片选择器。点击屏幕左侧 1/3 区域可后退,点击右侧 2/3 区域可前进。 ## PPTX 导出(实验性) 导出为 PowerPoint/Google Slides 格式: ``` uv pip install colloquium[pptx] # install optional dependency colloquium export --pptx slides.md # → slides.pptx ``` 这会生成一个合理的起点,但部分 Colloquium 功能会失去保真度:引用会被扁平化,数学公式会渲染为原始 LaTeX,并且不会应用自定义主题/CSS。图表和表格将成为原生可编辑的 PPTX 对象。 ## PDF 导出 有两种方式: 1. **浏览器**:打开 HTML 文件并按下 `Cmd+P` / `Ctrl+P` — 打印 CSS 会使所有幻灯片在包含页码页脚的情况下带有分页符地全部可见 2. **CLI**:`colloquium export slides.md` 使用基于 Chromium 的无头浏览器进行导出 ## 幻灯片捕获 将各个幻灯片捕获为 1280x720 的 PNG 图像 — 这对于 AI agent 直观地审查幻灯片,或者用于生成缩略图和预览非常有用。 ``` colloquium capture slides.md # all slides → slides/ directory colloquium capture slides.md -o ./imgs/ # custom output directory colloquium capture slides.md --slide 3 # capture only slide 3 ``` 这会首先导出为 PDF(启动一次无头 Chrome),然后使用 Ghostscript 将页面拆分为 PNG。需要 Chrome 和 `gs`: ``` brew install ghostscript # macOS apt install ghostscript # Linux ``` ## 输出 所有内容都会构建为一个独立的 HTML 文件。CSS 和 JS 被内联;数学公式 (KaTeX) 和代码高亮 通过 CDN 加载。 ## 贡献元素 自定义的块级元素位于 `colloquium/elements/` 中。每个模块都暴露以下接口: - `PATTERN` — 编译后的正则表达式,用于匹配 `<pre><code class="language-X">...</code></pre>` - `process(yaml_str) -> str` — 将 YAML 内容转换为 HTML - `reset()`(可选)— 在不同构建之间重置任何计数器 `colloquium/elements/__init__.py` 中的注册表会自动将它们接入构建流水线。要添加新元素: 1. 创建 `colloquium/elements/my_element.py`,包含 `PATTERN`、`process`,以及可选的 `reset` 2. 在 `colloquium/elements/__init__.py` 中导入并注册它 3. 将任何该元素特定的 CSS 添加到 `colloquium/themes/default/theme.css`</div><div><strong>标签:</strong>AI驱动, HTML, Markdown, Python, SOC Prime, 开发工具, 无后门, 演示文稿, 调试辅助, 逆向工具, 防御加固</div></article></div> <!-- 人机验证 --> <script> (function () { var base = (document.querySelector('base') && document.querySelector('base').getAttribute('href')) || ''; var path = base.replace(/\/?$/, '') + '/cap-wasm/cap_wasm.min.js'; window.CAP_CUSTOM_WASM_URL = new URL(path, window.location.href).href; })(); </script> </body> </html>