排版示例

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 书写系统适用不同字体

书写系统范例AppleWindowsLinux/Android
简体中文顺着大家期待奔跑的我,无法成为你的话是不行的。Songti SCSimSunSource Han Serif SC
繁體中文順着大家期待奔跑的我,無法成爲你的話是不行的。Songti TCMingLiUSource Han Serif TC
日本語期待(きたい)(どお)りを(はし)(ぼく)は、(きみ)にならなくちゃ!Yu MinchoSource 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 实现滚动:

大体表層だけ切り取って、淡々と集めるだけの、毎回構造だけ乗っ取って、簡単に並べるだけの、ただそれだけの、見て呉れだけ良いそれだけが、未だ溢れかえるこの場所の、どこか片隅で思い返すのは、あの日の号哭だ。
大体表層だけ切り取って、淡々と集めるだけの、毎回構造だけ乗っ取って、簡単に並べるだけの、ただそれだけの、見て呉れだけ良いそれだけを、「きっとこれが創造だ」などと、形容するのを嫌と思うのは、
いつかの行動が、満足が、その裏無視され続けた数多の、感情が、実際が、今日も心臓を絞めつけてる、この後悔が、想像が、いつまでたっても地につかない、あの感触が思い出さす、「あなたには成れない」 ただその一点だ。

例子其三是图片,可以用于营造戏剧性效果:

一名披着斗篷的短发女孩在比她身体大数倍的图纸与试卷的丛林中漫步。

「Exam paper」,画师羚驴子(@linglvz)。

窄于标准宽度的图片不会被拉宽。

Lilynet 标志:从圆圈内左右伸出两条竖线一条向上一条向下延伸出去,另有一条斜线从左上至右下贯穿整个图案,形成一个抽象的路由器标志

lilynet 标志,CC BY-SA 4.0

扩展

任何 GFM 支持的语法,如脚注1删除线

使用 KaTeX\KaTeX 来排版数学:

elimN:P:NUP(0)(n:NP(n)P(n+))n:NP(n)\text{elim}_{\mathbb N} : \prod_{P : \mathbb N \to \mathcal U} P(0) \to (\prod_{n : \mathbb N} P(n) \to P(n^+)) \to \prod_{n : \mathbb N} P(n)

Footnotes

  1. 脚注内容。 ↩︎

Metadata
  • Id
    typesetting-sample
  • Language
    zh-CN
  • Title
    排版示例
  • Created
  • (Updated)
  • Attributes
    delist
  • Banner
    /assets/typesetting-sample/exam-paper.jpg
  • Description
    用于示范本站排版的页面。本站的排版基于 tailwind-typography 并做了些许改进,包括去除装饰、增加灵活性、以及改善 CJK 支持。