排版示例
Markdown 内容的排版基于 @tailwindcss/typography。代码块的高亮由 shiki 提供。在此之上,添加的功能有:
样式微调
整体使用偏暖色:文字为 stone-800,背景为 stone-100。
行内代码(inline code)不作加粗且不在前后特别加分隔符,惟字体改为等宽(M PLUS 1 Code)。
链接是深蓝色的且不作加粗。具体色调是 sky-900;鼠标悬浮会使下划线消失作为反馈。在 CJK 页面上,下划线往下调整 2px 以不至于与文字重合。
代码块语言
指针悬停时,在代码块的左上角显示使用的编程语言。
runState :: s -> Eff (State s : es) a -> Eff es (s, a)
runState s0 m = unsafelyEliminateIOE do
ref <- liftIO $ newIORef s0
reinterpret m \case
Get -> liftIO $ readIORef
Put s1 -> liftIO $ writeIORef ref s1
不足之处:如果代码宽度超过容器宽度而溢出,横向滚动时语言标记会随之滚走。若想修复这个问题需要更改 Markdown → HTML 的编译方法(在 <pre> 外多加一层 containing block)。
在标题中,使用比例字形和标点(palt)。
如你所见,从一级到四级标题都是如此。因为字小,正文不做此适用,否则排版显得拥挤。
对不同的 CJK 书写系统适用不同字体
| 书写系统 | 范例 | Apple | Windows | Linux/Android |
|---|---|---|---|---|
| 简体中文 | 顺着大家期待奔跑的我,无法成为你的话是不行的。 | Songti SC | SimSun | Source Han Serif SC |
| 繁體中文 | 順着大家期待奔跑的我,無法成爲你的話是不行的。 | Songti TC | MingLiU | Source Han Serif TC |
| 日本語 | 期待通りを走る僕は、君にならなくちゃ! | Yu Mincho | Source Han Serif JP | |
通过 CSS 的 :lang() 选择器实现。为了不引入更多的 web 字体,转而使用了一系列的系统自带字体。
超宽元素
有时候使元素超出文章的正常宽度,即 min(36em, 100%),是对阅读体验有益的。我修改了 CSS 使得将内容封入 <figure> 元素可以达成这个效果。此时,内容总能够占据全部的屏幕宽度。(感谢 Eana Hufwe 的网站首先实现了这个技术。)
例子其一是代码块(请不要在现实中这样排版你的代码):
export default procedure
.input(
z.object({
userUuid: z.uuid(),
page: z.int().min(1, 'Page must be at least 1'),
pageSize: z.int().min(1, 'Page size must be at least 1').max(100, 'Page size cannot exceed 100'),
}),
)
.query(async ({ ctx, input }): Promise<Page<MessageView>> => {
const [user] = await ctx.db.select({ id: users.id }).from(users).where(eq(users.uuid, input.userUuid))
if (!user) x404('User not found')
const [{ msgCount }] = await ctx.db.select({ msgCount: count() }).from(receivedMessages).innerJoin(messages, eq(receivedMessages.message, messages.id)).where(and(eq(receivedMessages.recipient, user.id), publishedCondition))
const entries = await ctx.db.select().from(receivedMessages).innerJoin(messages, eq(receivedMessages.message, messages.id)).where(and(eq(receivedMessages.recipient, user.id), publishedCondition)).orderBy(desc(messages.pinned), desc(messages.publishedAt)).offset(input.pageSize * (input.page - 1)).limit(input.pageSize)
return {
items: entries.map((entry) => unsafeEncodeMessage(entry.message)),
total: msgCount,
page: input.page,
pageSize: input.pageSize,
}
})例子其二是表格。封入 <figure> 的表格甚至不需要遵守屏幕宽度,因为它们可以用 white-space: no-wrap 溢出父元素,进而通过 overflow-y: auto 实现滚动:
| 大体表層だけ切り取って、 | 淡々と集めるだけの、 | 毎回構造だけ乗っ取って、 | 簡単に並べるだけの、ただそれだけの、 | 見て呉れだけ良いそれだけが、 | 未だ溢れかえるこの場所の、 | どこか片隅で思い返すのは、 | あの日の号哭だ。 |
|---|---|---|---|---|---|---|---|
| 大体表層だけ切り取って、 | 淡々と集めるだけの、 | 毎回構造だけ乗っ取って、 | 簡単に並べるだけの、ただそれだけの、 | 見て呉れだけ良いそれだけを、 | 「きっとこれが創造だ」などと、 | 形容するのを嫌と思うのは、 | |
| いつかの行動が、満足が、 | その裏無視され続けた数多の、 | 感情が、実際が、 | 今日も心臓を絞めつけてる、 | この後悔が、想像が、 | いつまでたっても地につかない、 | あの感触が思い出さす、 | 「あなたには成れない」 ただその一点だ。 |
例子其三是图片,可以用于营造戏剧性效果:

窄于标准宽度的图片不会被拉宽。
扩展
任何 GFM 支持的语法,如脚注1与删除线。
使用 来排版数学:
Footnotes
-
脚注内容。 ↩︎