← 返回博客

代码高亮实测:一次铺开 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、部署清单

引用与列表

高亮的意义不是「让代码变好看」,是让人在扫一眼的时候就能分清关键字、字符串和注释。 分不清这三样,再花哨的配色也是负担。

一份清单该有的样子:

  1. 有序列表用数字,步骤有先后时用。
  2. 无序列表用圆点,并列关系时用。
    • 可以嵌套一层,但别嵌套三层。
    • 嵌套超过两层,说明该拆成小标题了。

Markdown 全量功能演示

下面把所有常用语法挨个放一遍 —— 不是教学,是用来验渲染有没有漏、样式有没有崩。

标题层级

正文里能用到 h2 ~ h6(h1 是文章标题,不重复)。往下三级长这样:

四级标题

五级标题
六级标题

文本样式

粗体、斜体、粗斜体、删除线、行内代码,还有几个内联 HTML:高亮、按 ⌘ + K 打开、H2O、E = mc2。

链接

列表

无序,可以嵌套:

  • 一级
    • 二级
      • 三级 —— 再往下就该拆成小标题了
  • 回到一级

有序,也可以嵌套:

  1. 先定路线
  2. 再看天气
    1. 下雨就换室内
    2. 起雾反而更好
  3. 最后订住宿

任务列表(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

分隔线

上面是内容,下面是分隔线。


转义

不想被解析的字符前面加反斜杠:*这不是斜体*、`这不是代码`、[这不是链接]。

折叠块

点开看里面的内容

折叠里的正文,可以有段落、列表、代码:

  • 一条
  • 两条

以上就是全部。写代码的人真正在意的从来不是配色,是读起来省不省力。