Skip to content

臉被切到了怎麼辦!來自定義 markdown 語法吧

markdown-it-custom-syntax

段落文字太長時,在句尾的顏文字很容易被換行,像這樣 (#°
Д°)

一秒便變成了一坨不知所云的亂碼。( ´•̥̥̥ ω •̥̥̥` )

原本解法是像這樣 <span class="text-nowrap">(>'-'<)</span>,把顏文字用 HTML 包起來。

有效,但是實在不夠懶人優雅。( ・ิω・ิ)

既然此部落格基於 markdown 寫作,那麼就來調整一下 markdown-it 吧!◝(≧∀≦)◟

自定義語法

markdown-it 設計之初就考慮到了擴展性,自定義語法小菜一碟。

查了一圈 markdown 還沒被使用的符號,看起來 % 還不錯,所以預計使用 % 符號建立一個決不換行的區塊。

也就是 %(>'-'<)% 自動變為 <span class="text-nowrap">(>'-'<)</span>

首先建立一個 plugin。

.vitepress\plugin\markdown-it-nowrap.ts

ts
import type MarkdownIt from 'markdown-it'

const RULE_NAME = 'nowrap_span'
const MARKER = '%'

/** 使用 MARKER 包圍文字,即可建立不換行的元素
 * https://vitepress.dev/guide/markdown#advanced-configuration
 *
 * @param md
 */
export function markdownItNowrap(md: MarkdownIt) {
  /** 解析 % 區塊
   *
   * 顏文字僅用於 inline 內容,所以註冊在 inline ruler 之前
   */
  md.inline.ruler.before('emphasis', RULE_NAME, (state, silent) => {
    const start = state.pos
    const markerLength = MARKER.length

    // 如果不是 %,直接跳過
    if (state.src.slice(start, start + markerLength) !== MARKER) {
      return false
    }

    const end = state.src.indexOf(MARKER, start + markerLength)
    if (end === -1) {
      return false
    }

    if (!silent) {
      const token = state.push(RULE_NAME, '', 0)
      token.content = state.src.slice(start + markerLength, end).trim()
    }

    state.pos = end + markerLength
    return true
  })

  /** 渲染自定義區塊內容 */
  md.renderer.rules[RULE_NAME] = (tokens, idx) => {
    if (!tokens[idx]?.content) {
      return ''
    }

    return `<span class="text-nowrap">${tokens[idx].content}</span>`
  }
}

接著依照文件指示,在 vitepress 使用 plugin。

.vitepress\config.mts

ts
// ...

// https://vitepress.dev/reference/site-config
export default ({ mode }: { mode: string }) => {
  // ...

  return withMermaid({
    title: '鱈魚的魚缸',
    // ...

    markdown: {
      lineNumbers: true,
      config(md) {
        md.use((md) => markdownItBaseImg(md, mode))
        md.use(markdownItNowrap) 
      },
    },

    // ...
  })
}

完工!

現在被 % 包圍的文字都會自動變成帶有 text-nowrap class 的 span 了!

nowrap-span

對原理有興趣的讀者們,歡迎來看看這篇文章◝( •ω• )◟

總結 🐟

  • markdown-it 可自由擴展自定義語法
  • 透過自定義語法讓顏文字不會被換行