臉被切到了怎麼辦!來自定義 markdown 語法吧
段落文字太長時,在句尾的顏文字很容易被換行,像這樣 (#°
Д°)
一秒便變成了一坨不知所云的亂碼。( ´•̥̥̥ ω •̥̥̥` )
原本解法是像這樣 <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
了!
對原理有興趣的讀者們,歡迎來看看這篇文章。◝( •ω• )◟
總結 🐟
- markdown-it 可自由擴展自定義語法
- 透過自定義語法讓顏文字不會被換行