代码高亮实测:一次铺开 16 种语言

这篇是一次排版实测:把日常会写到的语言挨个放进代码块,看高亮配色、行内代码、表格、引用在正文里是不是都站得住。不是教程,就是一次「全部摆出来看一遍」。
统一用同一个例子:一组素材,找出最宽的那张。同样的意图,看不同语言各自长什么样。
脚本类
JavaScript
// 把一组素材按拍摄日期分组
export function groupByDate(shots) {
return shots.reduce((acc, shot) => {
const key = shot.takenAt.slice(0, 10);
(acc[key] ??= []).push(shot);
return acc;
}, {});
}
TypeScript
type Shot = {
id: string;
takenAt: string;
width: number;
tags: readonly string[];
};
export function widest(shots: Shot[], min = 2400): Shot | null {
return shots.filter((s) => s.width >= min).sort((a, b) => b.width - a.width)[0] ?? null;
}
Python
from dataclasses import dataclass
from pathlib import Path
@dataclass(frozen=True)
class Shot:
path: Path
width: int
def total_bytes(shots: list[Shot]) -> int:
"""统计一组素材的总大小。"""
return sum(s.path.stat().st_size for s in shots)
Ruby
Shot = Data.define(:name, :width)
shots = [
Shot.new(name: "a.webp", width: 2400),
Shot.new(name: "b.webp", width: 1600)
]
widest = shots.max_by(&:width)
puts "#{widest.name} #{widest.width}px"
PHP
<?php
declare(strict_types=1);
final class Shot
{
public function __construct(
public readonly string $name,
public readonly int $width,
) {}
}
$widest = fn (array $shots): ?Shot => array_reduce(
$shots,
fn (?Shot $carry, Shot $s) => $carry === null || $s->width > $carry->width ? $s : $carry,
);
编译型
Go
package main
import "fmt"
type Shot struct {
Name string
Width int
}
func main() {
shots := []Shot{{"a.webp", 2400}, {"b.webp", 1600}}
for _, s := range shots {
fmt.Printf("%-10s %dpx\n", s.Name, s.Width)
}
}
Rust
#[derive(Debug)]
struct Shot<'a> {
name: &'a str,
width: u32,
}
fn widest(shots: &[Shot]) -> Option<&Shot> {
shots.iter().max_by_key(|s| s.width)
}
fn main() {
let shots = vec![Shot { name: "a.webp", width: 2400 }];
println!("{:?}", widest(&shots));
}
Java
import java.util.List;
public record Shot(String name, int width) {
public static Shot widest(List<Shot> shots) {
return shots.stream()
.max((a, b) -> Integer.compare(a.width(), b.width()))
.orElseThrow();
}
}
C
#include <stdio.h>
typedef struct {
char name[64];
int width;
} shot_t;
int main(void) {
shot_t s = { .name = "a.webp", .width = 2400 };
printf("%s %dpx\n", s.name, s.width);
return 0;
}
Swift
struct Shot: Identifiable {
let id = UUID()
let name: String
let width: Int
}
let shots = [Shot(name: "a.webp", width: 2400)]
let widest = shots.max { $0.width < $1.width }
print(widest?.name ?? "—")
Kotlin
data class Shot(val name: String, val width: Int)
fun main() {
val shots = listOf(Shot("a.webp", 2400), Shot("b.webp", 1600))
shots.maxByOrNull { it.width }
?.let { println("${it.name} ${it.width}px") }
}
查询与数据
SQL
SELECT
s.album,
COUNT(*) AS shots,
ROUND(AVG(s.width), 0) AS avg_width
FROM shots AS s
WHERE s.taken_at >= DATE '2026-01-01'
GROUP BY s.album
HAVING COUNT(*) > 3
ORDER BY shots DESC
LIMIT 10;
JSON
{
"name": "koka-site",
"type": "module",
"scripts": {
"build": "astro build",
"preview": "astro preview"
},
"engines": { "node": ">=22" }
}
YAML
name: build
on:
push:
branches: [main]
jobs:
site:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci && npm run build
命令行与配置
Bash
#!/usr/bin/env bash
set -euo pipefail
# 把 originals/ 下的素材按年月归档
for f in originals/*.{jpg,webp}; do
[ -e "$f" ] || continue
ym=$(date -r "$f" +%Y-%m)
mkdir -p "archive/$ym"
mv "$f" "archive/$ym/"
done
Dockerfile
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
HTML
<figure class="shot">
<img src="/images/placeholder/meadow-field.webp" alt="开阔的草坡" loading="lazy" />
<figcaption>清晨,草坡上还压着一层雾。</figcaption>
</figure>
CSS
.shot {
display: grid;
gap: 0.5rem;
border-radius: var(--radius-lg);
background: var(--surface);
overflow: hidden;
}
@media (min-width: 60rem) {
.shot {
grid-template-columns: 2fr 1fr;
}
}
还有两个不太算「语言」的
diff
- font-size: clamp(2.5rem, 4.4vw, 3rem);
+ font-size: var(--text-4xl);
Markdown
## 小标题
- 列表项
- **加粗** / *斜体* / `行内代码`
> 引用一行。
行内代码
正文里的行内代码走另一套样式:npm run build、--text-4xl、/images/placeholder/、astro:content、z.coerce.date()。它们要和正文有区分,但不能跳出来抢注意力 —— 底色淡一档、圆角小一点就够了。
表格
| 语言 | 类型 | 常见场景 |
|---|---|---|
| JavaScript | 脚本 | 浏览器、构建脚本 |
| TypeScript | 脚本 | 有类型的 JS |
| Python | 脚本 | 自动化、数据处理 |
| Go | 编译 | 服务端、CLI |
| Rust | 编译 | 性能敏感、系统层 |
| SQL | 查询 | 取数、报表 |
| YAML | 配置 | CI、部署清单 |
引用与列表
高亮的意义不是「让代码变好看」,是让人在扫一眼的时候就能分清关键字、字符串和注释。 分不清这三样,再花哨的配色也是负担。
一份清单该有的样子:
- 有序列表用数字,步骤有先后时用。
- 无序列表用圆点,并列关系时用。
- 可以嵌套一层,但别嵌套三层。
- 嵌套超过两层,说明该拆成小标题了。
Markdown 全量功能演示
下面把所有常用语法挨个放一遍 —— 不是教学,是用来验渲染有没有漏、样式有没有崩。
标题层级
正文里能用到 h2 ~ h6(h1 是文章标题,不重复)。往下三级长这样:
四级标题
五级标题
六级标题
文本样式
粗体、斜体、粗斜体、删除线、行内代码,还有几个内联 HTML:高亮、按 ⌘ + K 打开、H2O、E = mc2。
链接
- 普通链接:Astro 文档
- 自动链接:https://astro.build
- 带 title 的:鼠标停一下
列表
无序,可以嵌套:
- 一级
- 二级
- 三级 —— 再往下就该拆成小标题了
- 二级
- 回到一级
有序,也可以嵌套:
- 先定路线
- 再看天气
- 下雨就换室内
- 起雾反而更好
- 最后订住宿
任务列表(GFM):
- 写正文
- 配图
- 校对
- 发出去
引用
单层引用。 换行仍然在同一段里。
外层引用
嵌套一层引用
回到外层
引用里也能放行内代码:npm run build。
表格
| 左对齐 | 居中 | 右对齐 |
|---|---|---|
| 短 | 中 | 1 |
| 长一点的内容 | 也还行 | 1234.56 |
| 再长一点的内容试试换行 | 居中 | 99999 |
代码块与超长行
这一行故意写得很长,用来验证会不会顶出容器:
ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1" -c:v libx264 -preset slow -crf 18 -c:a aac -b:a 192k output.mp4
再来一段没有空格、无法自然断行的:
https://example.com/a/very/long/path/that/never/breaks/anywhere/because/there/is/no/space/at/all/in/this/url?query=1&more=2
分隔线
上面是内容,下面是分隔线。
转义
不想被解析的字符前面加反斜杠:*这不是斜体*、`这不是代码`、[这不是链接]。
折叠块
点开看里面的内容
折叠里的正文,可以有段落、列表、代码:
- 一条
- 两条
以上就是全部。写代码的人真正在意的从来不是配色,是读起来省不省力。