news 2026/10/15 18:53:50

Hydro 题目描述 Markdown 模板解析:从 problem_default.md 到题目编辑器的完整链路

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Hydro 题目描述 Markdown 模板解析:从 problem_default.md 到题目编辑器的完整链路
  • 后端
  • 前端
  • 教育

【免费下载链接】Hydro

项目地址:https://gitcode.com/hydro-dev/Hydro
点击查看免费下载

Hydro 是一个开源在线评测(Online Judge)系统,题目描述(Problem Statement)是 OJ 系统的核心内容载体。在 Hydro 中,packages/ui-default/templates/partials/problem_default.md是新建题目时预填在题目编辑器中的 Markdown 默认模板,本文以该模板为线索,从格式约定、编辑与存储、渲染与展示三个层面,完整拆解 Hydro 题目描述的编写规范与底层实现链路。

一、模板内容全解析:一份可直接落地的 A+B 题目描述

problem_default.md的完整内容如下:

# Background Special for beginners, ^_^ # Description Given two integers x and y, print the sum. # Format ## Input Two integers x and y, satisfying $0\leq x,y\leq 32767$ . ## Output One integer, the sum of x and y. # Samples ```input1 123 500
623

Limitation

1s, 1024KiB for each test case.

这份模板包含了 Hydro 题目描述的**全部核心段落**,共五个部分: 1. **Background(题目背景)**:用 `# Background` 一级标题标记,内容为对初学者的说明性文字; 2. **Description(题目描述)**:用 `# Description` 一级标题标记,描述问题本身,即"给定两个整数 x 和 y,输出它们的和"; 3. **Format(输入输出格式)**:用 `# Format` 一级标题标记,其下用 `## Input` 与 `## Output` 两个二级标题分别描述输入与输出格式。注意模板中使用了 `$0\leq x,y\leq 32767$` 这样的 **LaTeX 行内公式**,这是 Hydro 题目描述的重要特性; 4. **Samples(样例)**:用 `# Samples` 一级标题标记,下方是样例输入/输出的代码块,见下文"样例块规范"; 5. **Limitation(限制)**:用 `# Limitation` 一级标题标记,注明单点时限与内存限制,例如 `1s, 1024KiB for each test case`。 需要说明的是:**Hydro 的评测配置(如时间/内存限制的实际生效值)并非由题目描述中的 Limitation 段落决定,而是通过题目数据中的 `config.yaml` 文件配置**(详见 `packages/hydrooj/src/handler/problem.ts` 中 `ProblemConfigHandler` 对 `config.yaml` 的读取逻辑)。题目描述中的 Limitation 只是给做题人的阅读提示,评测机实际执行的限制以 [testdataConfig.ts](https://link.gitcode.com/i/2baac0ce815d9dbbe133aded957e6412) 解析的评测配置为准。从源码结构看,这两套机制各司其职:`config.yaml` 负责定义评测行为,`problem_default.md` 负责定义面向参赛者的描述文本。 ## 二、模板的触发场景:新建题目的默认预填内容 `problem_default.md` 并非在题目详情页渲染,而是**新建题目时的编辑器预填模板**。它的唯一引用点在 [problem_edit.html](https://link.gitcode.com/i/e4889dc5e8db78a97b9f558e15a628ba): ```html <textarea name="content" class="textbox hasjs--hide">```input1 123 500
623
`input1` 与 `output1` 中的数字 `1` 是**样例序号**,表示这是第 1 组样例(第 2 组则写作 `input2`/`output2`,以此类推)。这一约定并非随意设计,而是与 Hydro 的前端渲染逻辑深度绑定。 在 [highlighter.page.ts](https://link.gitcode.com/i/94764c8d1b07e6379328eb561c463576) 中,前端会通过正则 `language-input([0-9]+)` 识别样例输入块: 1. 提取代码块 class 中的编号 `id`; 2. 在页面中查找对应的 `pre.language-output${id}` 输出块; 3. 若输入与输出都找到,则把输入块标题改为 "Sample Input N"、输出块标题改为 "Sample Output N",并将两者放入同一行(`medium-6 columns`)左右并排展示; 4. 输入块上还会附加一个 "Fill to Pretest"(填入预测试)按钮,点击后将样例输入写入 Scratchpad 预测试(见 `SCRATCHPAD_PRETEST_DATA_CHANGE` 的 dispatch 逻辑)。 这套机制同时印证了题面样例渲染与 Scratchpad 联动的实战价值:**样例输入代码块上自动出现的"填入预测试"按钮,直接来源于 `inputN` 这一约定命名**。 此外,服务端提供了结构化构造题目内容的能力:在 [content.ts](https://link.gitcode.com/i/66a8423eac873fb13dd1ca17620052e3) 中,`buildContent()` 函数接受 `ProblemSource`(包含 `background`、`description`、`input`、`output`、`samples`、`hint`、`source` 等字段)并将其序列化为与 `problem_default.md` 完全同构的 Markdown,其中样例块正是生成 ` ```input${i+1} ` 与 ` ```output${i+1} ` 格式。这一实现从服务端代码层面印证了 `inputN/outputN` 是 Hydro 的**标准样例块规范**。 ## 四、LaTeX 公式:模板中的数学渲染能力 模板中的 `$0\leq x,y\leq 32767$` 展示了 Hydro 对数学公式的原生支持。该能力由 [markdown-it-katex.ts](https://link.gitcode.com/i/9c51163069bf07243562c412d5536962) 实现: - **行内公式**:`$...$`,如模板中的 `$0\leq x,y\leq 32767$`; - **公式块**:`$$...$$`,独占一段显示。 该插件基于 markdown-it 的 `inline`/`block` 规则编写(见源码 `function inline(state, silent)` 对 `$` 分隔符的解析),渲染输出通过 `md.renderer.rules.math_inline` 与 `math_block` 接管。在 [markdown.js](https://link.gitcode.com/i/fc6831758980daf35a7cd2c0654ff4bc) 中,`Katex` 作为插件注册到 Hydro 统一的 Markdown 渲染器中。注意该插件对 `$` 分隔符有严格的配对与转义检测(如 `$$` 与 `\$` 的处理),书写公式时需保证分隔符完整配对。 ## 五、从模板到页面的完整链路:题目描述的渲染管线 综合源码可以还原题目描述从编辑到展示的完整调用链: 1. **编辑/新建**:`GET /problem/create` 或 `GET /p/:pid/edit` 由 [ProblemCreateHandler / ProblemEditHandler](https://link.gitcode.com/i/371c517ff78a2d996b2e321169c6ae08) 处理,渲染 `problem_edit.html`;新建时编辑器预填 `partials/problem_default.md` 的内容。 2. **提交保存**:`POST` 请求携带 `title`、`content` 等字段,`content` 通过 `Types.Content` 类型校验(见 [problem.ts](https://link.gitcode.com/i/a51387b7861ab3277c7e32e223374a5b))。`ProblemCreateHandler.post` 调用 `problem.add()` 写入 `content`,`ProblemEditHandler.post` 调用 `problem.edit()` 更新 `content`(写入时设置 `html: false`,即按 Markdown 原文存储,[problem.ts](https://link.gitcode.com/i/892c63747f6b10f5fa48fe8269e7ec6b))。 3. **存储**:`content` 作为 `ProblemDoc` 的字段存储在数据库中(见 [model/problem.ts](https://link.gitcode.com/i/8252d63915348bce37562e90d38c3527) 中 `ProblemDoc` 文档结构及 `problem.add`/`problem.edit` 的实现),保持 Markdown 原文。 4. **详情展示**:`GET /p/:pid` 由 `ProblemDetailHandler` 处理,渲染 [problem_detail.html](https://link.gitcode.com/i/1ad4641ab7cb1f2570c60359723eb8d7)。服务端通过模板过滤器 `markdown` 将存储的 Markdown 渲染为 HTML(见 [template.ts](https://link.gitcode.com/i/3cee19da7c3949946faabf86cf9e02fe),其逻辑为 `ensureTag(html ? xss.process(s) : markdown.render(s))`——Markdown 内容走 `markdown.render()`,经过 [markdown-it-xss.ts](https://link.gitcode.com/i/2c2bb205a4f848928ba64cd308de57df) 的 XSS 防护处理)。 5. **前端增强**:页面加载后,[highlighter.page.ts](https://link.gitcode.com/i/c879fc2a460b6882d4ce12912911be98) 通过 PrismJS 对 `pre code` 进行语法高亮,并识别 `inputN`/`outputN` 样例块执行并排布局与"填入预测试"按钮注入。 其中步骤 4 的渲染管线由 [markdown.js](https://link.gitcode.com/i/9029a7f0f235fcbd9950d5d3e7527bd2) 中的 `Markdown` 类统一实现,注册了如下插件,这也正是题目描述中可用的完整语法集合: | 插件 | 功能 | 来源 | | --- | --- | --- | | `Media` | `@video`、`@youtube`、`@pdf` 媒体嵌入 | [markdown-it-media.ts](https://link.gitcode.com/i/4a6a35ec61870fa9fb31374d86e970b5) | | `Imsize` | `img` 指定图片尺寸 | [markdown-it-imsize.ts](https://link.gitcode.com/i/805a2069a09f650a9286ff5c3eb04c7e) | | `Footnote` | `[^1]` 脚注语法 | markdown-it-footnote | | `Mark` | `==Text==` 高亮标记 | markdown-it-mark | | `Anchor` + `TOC` | 标题锚点与目录生成 | markdown-it-anchor / markdown-it-table-of-contents | | `Katex` | `$...$` / `$$...$$` 数学公式 | [markdown-it-katex.ts](https://link.gitcode.com/i/9c51163069bf07243562c412d5536962) | | `MergeCells` | 表格单元格合并 | markdown-it-merge-cells | | `xssProtector` | 输出 HTML 前的 XSS 防护 | [markdown-it-xss.ts](https://link.gitcode.com/i/2c2bb205a4f848928ba64cd308de57df) | ## 六、实践建议:基于模板撰写高质量题目描述 以 `problem_default.md` 为骨架,编写 Hydro 题目描述时可遵循以下规范: 1. **段落结构保持模板约定**:`# Background`、`# Description`、`# Format`(含 `## Input` / `## Output`)、`# Samples`、`# Limitation` 五段式是 Hydro 社区通行的题目描述结构,也是前端目录(TOC)与样例识别逻辑依赖的标题层级。 2. **样例块务必使用 `inputN`/`outputN` 命名**:编号从 1 开始连续递增,输入与输出编号一一对应;只有这样才能触发前端"Sample Input N / Sample Output N"并排展示与"填入预测试"功能。 3. **善用 LaTeX 公式**:数据范围、数学定义优先用 `$...$` 行内公式书写,保持分隔符配对,避免未闭合的 `$`。 4. **区分题面提示与评测配置**:Limitation 段落仅面向做题人提示,真正的时限/内存以题目数据中的 `config.yaml` 为准;创建题目后需前往题目配置页(`/p/:pid/config`,由 `ProblemConfigHandler` 处理)维护评测配置。 5. **合理使用扩展语法**:图片(含尺寸控制)、视频、脚注、高亮等语法在题目描述中可用,但应以不干扰判题阅读为原则。 ## 结语 `problem_default.md` 看似只是一份简单的 A+B 示例模板,实则是 Hydro 题目描述体系的一面镜子:它定义了题目内容的段落骨架,其 `inputN/outputN` 样例块约定被前端渲染与 Scratchpad 预测试深度复用,LaTeX 公式能力来自 [markdown-it-katex.ts](https://link.gitcode.com/i/9c51163069bf07243562c412d5536962) 插件,而整条编辑—存储—渲染链路则贯穿 [problem.ts](https://link.gitcode.com/i/dfa6099657888db28a5050e5b9efcff6)(Handler)、[model/problem.ts](https://link.gitcode.com/i/8252d63915348bce37562e90d38c3527)(数据模型)与 [markdown.js](https://link.gitcode.com/i/d6c72d8d2bad7c789bb549defc78af0c)(渲染管线)。理解了这份模板,也就掌握了在 Hydro 上编写规范、可复用题目描述的全部关键约定。
  • 后端
  • 前端
  • 教育

【免费下载链接】Hydro

项目地址:https://gitcode.com/hydro-dev/Hydro
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 18:53:49

跨Dex调用故障复盘:适配层、动态路由与滑点保护实战

灰度升级进行到第12个小时&#xff0c;Neptune的跨Dex调用失败率从不足1%一路冲到接近20%。我对着监控面板愣了挺久&#xff0c;因为本地模拟实验全部通过&#xff0c;测试网跑了几小时也风平浪静。用户反馈区已经出现大量“网络异常&#xff0c;交易回滚”&#xff0c;技术群里…

作者头像 李华
网站建设 2026/10/15 18:53:40

MNIST深度学习入门:CNN图像分类训练与推理完整实践

简介&#xff1a;围绕MNIST手写数字识别任务&#xff0c;这份资源提供了一套基于TensorFlow的卷积神经网络完整项目&#xff0c;适合深度学习初学者或希望快速验证CNN效果的开发者。MNIST包含6万张训练样本与1万张测试样本&#xff0c;均为2828灰度手写数字图像&#xff0c;是图…

作者头像 李华
网站建设 2026/10/15 18:52:11

P961温控表程式控制详解:8段×2组与6组PID自动演算

简介&#xff1a;CAHO P961微处理器编程控制器的英文/繁简中文说明书PDF&#xff0c;面向工厂自动化、过程控制及机器人控制领域的设备调试、维护与编程人员。资料系统梳理控制器的构成单元与运行机制&#xff0c;涵盖微处理器、编程界面、输入输出接口及显示屏等模块&#xff…

作者头像 李华
网站建设 2026/10/15 18:49:51

Intel IPP 9.0实战:从原理到性能调优的完整指南

简介&#xff1a;Intel IPP 9.0 教程与库下载包&#xff0c;面向图像处理、信号处理、计算机视觉和数学运算等领域的 C/C 开发者&#xff0c;尤其适合希望借助多核 CPU 与 SSE、AVX2 指令集提升程序性能的团队。压缩包内共含 2058 个文件&#xff0c;以 1220 个 htm 教程页面和…

作者头像 李华