Typora 主题 | 99% 还原 CCF NOI 系列赛事题面
使用 Typora 出模拟赛题的你,是否觉得可用的主题太丑,与 CCF 题面风格完全不符?
我(和 DeepSeek、DeepWiki)开发了一个 Typora 主题,几乎完全还原了 CCF NOI 系列赛事题面(大部分参数是我手动尝试并于官方 pdf 对比得到的)。
因为我觉得 Consolas 更好看,所以代码块使用了 Consolas 字体。
:::info[主题源码]
/* ========================================
名称: CCF 官方题目样式 + tuack 表格
基于: cnoi-statement-generator/templates/cnoi/typst/main.typ
======================================== */
/* ========== 全局重置 ========== */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* ========== 基础样式 ========== */
body {
font-family: "Times New Roman", "SimSun", "STSong", "宋体", serif;
font-size: 12pt;
line-height: 1.6;
font-weight: normal; /* ← 修复:0 → normal (400) */
color: #000000;
background: #ffffff;
margin: 0 auto;
padding: 2rem;
max-width: 850px;
text-align: justify;
}
/* ========== 标题 ========== */
h2 {
font-family: "SimHei", "Microsoft YaHei", "Helvetica Neue", "Arial", sans-serif;
font-size: 18pt;
font-weight: 500;
text-align: center;
margin: 1em 0 0.5em 0;
padding: 0;
border: none;
color: #000000;
}
h3 {
font-family: "SimHei", "Microsoft YaHei", "Helvetica Neue", "Arial", sans-serif;
font-size: 13pt;
font-weight: 500;
text-align: left;
margin: 1.25em 0 0.5em 0;
padding: 0 0 0 1em;
border: none;
color: #000000;
}
/* ========== 正文段落 ========== */
p {
margin: 0;
line-height: 1.6;
text-align: justify;
text-indent: 2em;
}
/* ========== 列表(通用) ========== */
ul, ol {
list-style: none;
padding-left: 0 !important;
margin: 0;
counter-reset: ol-counter;
}
li {
margin: 0 0 0 2em;
line-height: 1.6;
position: relative;
padding-left: 1em;
}
li p {
margin: 0 !important;
padding: 0 !important;
text-indent: 0 !important;
}
/* ========== 无序列表符号(按嵌套层级) ========== */
ul > li::before {
content: "•";
position: absolute;
left: 0;
top: 0;
}
ul ul > li::before { content: "–"; }
ul ul ul > li::before { content: "∗"; }
ul ul ul ul > li::before { content: "·"; }
/* ========== 有序列表编号 ========== */
ol > li {
counter-increment: ol-counter;
}
ol > li::before {
content: counter(ol-counter) ".";
position: absolute;
left: 0;
top: 0;
}
/* ========== 加粗(NOI 官方风格) ========== */
strong, b {
font-family: "SimHei", "Microsoft YaHei", "黑体", sans-serif;
font-weight: bold !important;
/* 着重号:仅对 CJK 字符视觉效果好 */
-webkit-text-emphasis: filled dot;
text-emphasis: filled dot;
-webkit-text-emphasis-position: under right;
text-emphasis-position: under right;
}
/* 加粗内的代码不加着重号 */
strong code, b code,
code strong, code b,
pre strong, pre b {
-webkit-text-emphasis: none !important;
text-emphasis: none !important;
font-family: "Consolas", "SimSun", "宋体", monospace;
}
/* ========== 内联代码 ========== */
code {
font-family: "Consolas", "SimSun", "宋体", monospace;
font-size: 12pt !important;
background-color: transparent;
padding: 0;
border-radius: 0;
color: #000000;
}
/* ========== 代码块 ========== */
pre {
background-color: transparent;
border: 0.4pt solid #0000ff;
border-radius: 0;
padding: 2pt 3pt 4pt 3pt; /* ← 修正:6pt-4pt=2pt, 9pt-4pt=5pt */
overflow-x: auto;
margin: 10pt 0;
font-size: 12pt !important;
line-height: 1.6; /* ← 修正:对应 Typst 每行 box inset 4.25pt×2 */
font-family: "Consolas", "SimSun", "宋体", monospace;
white-space: pre;
}
pre code {
background-color: transparent;
padding: 0;
color: #000000;
font-family: inherit;
font-size: inherit;
}
/* ========== 仅 cpp 有语法高亮 ========== */
pre[lang="cpp"] .cm-s-inner .cm-comment { color: #00ff00; font-style: italic; }
pre[lang="cpp"] .cm-s-inner .cm-string { color: #000000 !important; font-weight: bold !important; }
pre[lang="cpp"] .cm-s-inner .cm-keyword { color: #bf0040; font-weight: bold; }
pre[lang="cpp"] .cm-s-inner .cm-type,
pre[lang="cpp"] .cm-s-inner .cm-variable-3 { color: #bf0040; font-weight: bold; }
pre[lang="cpp"] .cm-s-inner .cm-meta { color: #bf0040; font-weight: bold; }
pre[lang="cpp"] .cm-s-inner .cm-operator { color: #000000; font-weight: normal; }
pre[lang="cpp"] .cm-s-inner .cm-def,
pre[lang="cpp"] .cm-s-inner .cm-variable,
pre[lang="cpp"] .cm-s-inner .cm-variable-2,
pre[lang="cpp"] .cm-s-inner .cm-builtin,
pre[lang="cpp"] .cm-s-inner .cm-atom,
pre[lang="cpp"] .cm-s-inner .cm-number { color: #000000; font-weight: normal; }
pre[lang="cpp"] .cm-s-inner .cm-string-2 { color: #000000; font-weight: normal; }
/* ========== 除 cpp 外所有语言全黑 ========== */
pre:not([lang="cpp"]):not([lang="c++"]) .cm-s-inner span {
color: #000000 !important;
font-weight: normal !important;
font-style: normal !important;
}
/* 行号 */
.CodeMirror-linenumber {
color: #808080;
font-size: 10pt;
}
/* ========== 数学公式 ========== */
.math {
font-family: "Times New Roman", "STIXGeneral", "Cambria Math", serif;
font-size: 1em;
}
.math-inline {
font-family: inherit;
vertical-align: middle !important;
line-height: 1.6 !important;
}
.math-display, .katex-display, .MathJax_Display {
margin: 0 !important;
overflow-x: auto;
text-align: center;
line-height: 1.6 !important;
}
.math, .katex, .MathJax,
.md-math-block, .md-inline-math,
.math-display, .katex-display {
text-indent: 0 !important;
}
/* ========== 链接 ========== */
a {
color: #2c7da0;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* =============================================
tuack 三线表(默认)
对应 Typst:
stroke: (x, y) => (
left: if x > 0 { .4pt },
bottom: 2pt,
top: if y == 0 { 2pt } else if y == 1 { 1.2pt } else { .4pt },
)
align: center + horizon
============================================= */
table {
border-collapse: collapse;
width: auto;
margin-left: auto !important;
margin-right: auto !important;
margin-top: 9pt;
margin-bottom: 6pt;
border-top: 2pt solid #000;
border-bottom: 2pt solid #000;
border-left: none;
border-right: none;
font-family: "Times New Roman", "SimSun", "STSong", "宋体", serif;
font-size: 12pt;
}
table th,
table td {
padding: 4pt 8pt;
text-align: center;
vertical-align: middle;
text-indent: 0;
border-left: none;
border-right: none;
border-top: none;
border-bottom: none;
}
/* 非首列左侧 0.4pt 竖线 */
table th + th,
table td + td {
border-left: 0.4pt solid #000;
}
/* 表头底部 1.2pt */
table thead th {
border-bottom: 1.2pt solid #000;
font-weight: bold;
}
/* 数据行间 0.4pt */
table tbody tr + tr td {
border-top: 0.4pt solid #000;
}
/* =============================================
等宽边框表(用 <div class="cnoi-info-table"> 包裹)
对应 Typst: #set table(stroke: 0.3pt)
============================================= */
.cnoi-info-table table {
border: 0.3pt solid #000;
}
.cnoi-info-table table th,
.cnoi-info-table table td {
border: 0.3pt solid #000;
text-align: left;
vertical-align: bottom;
}
.cnoi-info-table table th + th,
.cnoi-info-table table td + td {
border-left: 0.3pt solid #000;
}
.cnoi-info-table table thead th {
border-bottom: 0.3pt solid #000;
font-weight: normal;
}
.cnoi-info-table table tbody tr + tr td {
border-top: 0.3pt solid #000;
}
p:has(.md-inline-math-container),
p:has(.math-inline),
p:has(mjx-container) {
text-align: left !important;
}
/* ========== 打印 / PDF 导出 ========== */
@media print {
* {
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
@page {
size: A4;
margin: 1.6cm;
}
body {
margin: 0;
padding: 0;
max-width: none;
}
/* --- 分页控制 --- */
table, pre, figure {
page-break-inside: avoid;
break-inside: avoid;
}
h2, h3, h4, h5, h6 {
page-break-after: avoid;
break-after: avoid;
}
p {
orphans: 3;
widows: 3;
}
img {
page-break-inside: avoid;
break-inside: avoid;
}
/* --- 列表打印 --- */
ul, ol {
list-style: none;
padding-left: 0 !important;
margin: 0;
}
/* --- 数学公式打印 --- */
.math-display, .katex-display, .MathJax_Display {
margin: 0 !important;
overflow-x: auto;
text-align: center;
font-weight: 300 !important;
line-height: 1.6 !important;
}
/* --- 三线表线条加粗(解决 PDF 中线条不可区分) --- */
table {
border-top: 2.5pt solid #000 !important;
border-bottom: 2.5pt solid #000 !important;
}
table thead th {
border-bottom: 1.5pt solid #000 !important;
}
table tbody tr + tr td {
border-top: 0.75pt solid #000 !important;
}
table th + th,
table td + td {
border-left: 0.75pt solid #000 !important;
}
/* --- 等宽边框表打印 --- */
.cnoi-info-table table,
.cnoi-info-table table th,
.cnoi-info-table table td {
border-width: 0.5pt !important;
}
}
:::
使用教程:
- 在 Typora 中点击文件 -> 偏好设置 -> 外观 -> 打开主题文件夹;
- 新建一个名称为
noi-tuack.css的文件,将源码粘贴进去并保存; - 回到 Typora 页面,选择主题 -> Noi Tuack 即可。
题目名称需要使用二级标题,“题目描述”等需要使用三级标题。
目前已知的问题有:
有序列表会被视作无序列表,且无序列表多层嵌套符号不变(已修复)。- 加粗或者
\LaTeX 过高会导致行间距变大,从而可能导致列表符号与文本不对齐(暂无解决方案)。
排列游戏生成的 pdf:https://www.luogu.com.cn/problem/U674531。
注:本项目部分参考了 CNOI Statement Generator 中的数据,如有侵权请联系我删除。