純CSS實現markdown標題自動編號

# 問題的由來

第一次關注這個標題編號的問題應該回溯到本科畢業論文的時候了,當時還單獨涉獵過這個主題,`Word` 有個很好的特性`級聯標題`,一次設置好之后,后續只要設置標題樣式就能按照設置的標題編號方式自動編號,我們要做的只是將對應的標題設置成對應基本的標題樣式就好了,這個方法讓我愛不釋手,多年來一直沿用。完全解決了中途插入一章,一節等等導致的章節編號都需要人肉調整的問題,當然還有圖片的編號命名什么的,都是類似的。

直到后面開始用`markdown` 由于各個編輯器的切換,一直沒有一個好用的替代方案,所以幾年前我寫了一個小工具用命令行來做這事`rawbin-/markdown-clear`,這個工具解決了在`github`寫博客的問題,同時在解決博客的問題的基礎上解決了在各個平臺發文的問題,因為編號是用腳本寫上去的,所以用`markdown here`在各個平臺發文也就順理成章的轉成html就行了,也解決了這個階段的問題。

前兩天把拖欠幾個月的`全面認知`的總結寫了,突然不想用這個腳本來編號了,產生一個想法:能不能不人肉編號,自動編上?然后就有了下面的內容。

# 先搞起來解決問題

>>> 以下操作案例都是在macOS中產出,其他平臺可能有些許差別,換湯不換藥。

## 在`typora`中寫`markdown`自動編號

- 打開`typora`【偏好設置】

- 找到【外觀】=>【主題】=>【打開主題文件夾】

- 將如下代碼加入到打開目錄的`base.user.css` 中

```css

#writer {

? ? counter-reset: h1

}

h1 {

? ? counter-reset: h2

}

h2 {

? ? counter-reset: h3

}

h3 {

? ? counter-reset: h4

}

h4 {

? ? counter-reset: h5

}

h5 {

? ? counter-reset: h6

}

#writer h1:before {

? ? counter-increment: h1;

? ? content: counter(h1) ". "

}

#writer h2:before {

? ? counter-increment: h2;

? ? content: counter(h1) "." counter(h2) ". "

}

#writer h3:before {

? ? counter-increment: h3;

? ? content: counter(h1) "." counter(h2) "." counter(h3) ". "

}

#writer h4:before {

? ? counter-increment: h4;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". "

}

#writer h5:before {

? ? counter-increment: h5;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "

}

#writer h6:before{

? ? counter-increment: h6;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "

}

```

### 講道理

- 打開`typora`【偏好設置】

- 找到【通用】=>【高級 】=>【開啟調試模式】=>勾選

- 然后在非源碼模式下=>【右鍵】=>【檢查元素】,就可以看到為什么是`#write`了

- 這個后面還有用

## 在`github pages` 寫`markdown`博客自動編號

我用的是`jekyllbootstrap.com`的模板,比較簡單

- 打開任意一篇`rawbin-.github.io`中的文章,然后【右鍵】=>【檢查】

- 可以拿到兩個內容

? - 容器類為 `.content` ,嚴格點為`#wrap .content`

? - 樣式文件在`assets/themes/bootstrap3`,可以修改其下的`css/style.css`

- 將如下內容改到源代碼的`assets/themes/bootstrap3/css/style.css`中

```css

.content {

? ? counter-reset: h1

}

h1 {

? ? counter-reset: h2

}

h2 {

? ? counter-reset: h3

}

h3 {

? ? counter-reset: h4

}

h4 {

? ? counter-reset: h5

}

h5 {

? ? counter-reset: h6

}

.content h1:before {

? ? counter-increment: h1;

? ? content: counter(h1) ". "

}

.content h2:before {

? ? counter-increment: h2;

? ? content: counter(h1) "." counter(h2) ". "

}

.content h3:before {

? ? counter-increment: h3;

? ? content: counter(h1) "." counter(h2) "." counter(h3) ". "

}

.content h4:before {

? ? counter-increment: h4;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". "

}

.content h5:before {

? ? counter-increment: h5;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "

}

.content h6:before{

? ? counter-increment: h6;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "

}

```

## 在其他網頁編輯中自動編碼

比如各個博客平臺,各個自媒體平臺等,像我們常用的寫文檔的語雀都可以的。

這里面涉及到一款瀏覽器插件`markdown here`,可以在頁面富文本編輯器中將`markdown` 自動轉換為網頁,這也是我前面說到的這幾年在各個平臺發文的套路,寫好編號好標題`markdown`往編輯器里面一貼,然后一點 ,搞定。

### 簡單嘗試

- `markdown here` 有一個配置頁面,可以配置和調整css,并能預覽效果

- 簡單看了下是用`js`把類轉成了`style`屬性,并且不支持偽類

### 修改源碼

- 到`adam-p/markdown-here` 看到,已經兩年沒動代碼了

- 不管三七二十三先 `fork`一把到`rawbin-/markdown-here`,然后把代碼拉下來

- 先把css文件建起來`src/common/auto-number-title`,找容器類可以在`markdown here`的選項頁面找到`.markdown-here-wrapper`

```css

.markdown-here-wrapper {

? ? counter-reset: h1

}

.markdown-here-wrapper h1 {

? ? counter-reset: h2

}

.markdown-here-wrapper h2 {

? ? counter-reset: h3

}

.markdown-here-wrapper h3 {

? ? counter-reset: h4

}

.markdown-here-wrapper h4 {

? ? counter-reset: h5

}

.markdown-here-wrapper h5 {

? ? counter-reset: h6

}

.markdown-here-wrapper h1:before {

? ? counter-increment: h1;

? ? content: counter(h1) ". "

}

.markdown-here-wrapper h2:before {

? ? counter-increment: h2;

? ? content: counter(h1) "." counter(h2) ". "

}

.markdown-here-wrapper h3:before {

? ? counter-increment: h3;

? ? content: counter(h1) "." counter(h2) "." counter(h3) ". "

}

.markdown-here-wrapper h4:before {

? ? counter-increment: h4;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". "

}

.markdown-here-wrapper h5:before {

? ? counter-increment: h5;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "

}

.markdown-here-wrapper h6:before{

? ? counter-increment: h6;

? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "

}

```

- 然后修改一下注入配置,允許加載這個樣式文件,并引入這個樣式問題

- 剩下的有錯改錯就好了

### 最終產出和應用

- 克隆`rawbin-/markdown-here`

- 打開Chrome 設置三個點=>【更多工具】=>【擴展程序】

- 打開【開發者模式】

- 選擇【加載已解壓的擴展程序】=>選擇克隆代碼下的`src`目錄即可安裝并加載插件

- 將插件固定在插件欄方便使用

- `auto-number-title.scss`內容如下

```scss

.markdown-here-wrapper {

? ? counter-reset: h1;

? ? h1 {

? ? ? ? counter-reset: h2;

? ? ? ? &:before {

? ? ? ? ? ? counter-increment: h1;

? ? ? ? ? ? content: counter(h1) ". ";

? ? ? ? }

? ? }

? ? h2 {

? ? ? ? counter-reset: h3;

? ? ? ? &:before {

? ? ? ? ? ? counter-increment: h2;

? ? ? ? ? ? content: counter(h1) "." counter(h2) ". "

? ? ? ? }

? ? }

? ? h3 {

? ? ? ? counter-reset: h4;

? ? ? ? &:before {

? ? ? ? ? ? counter-increment: h3;

? ? ? ? ? ? content: counter(h1) "." counter(h2) "." counter(h3) ". "

? ? ? ? }

? ? }

? ? h4 {

? ? ? ? counter-reset: h5;

? ? ? ? &:before {

? ? ? ? ? ? counter-increment: h4;

? ? ? ? ? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". "

? ? ? ? }

? ? }

? ? h5 {

? ? ? ? counter-reset: h6;

? ? ? ? &:before {

? ? ? ? ? ? counter-increment: h5;

? ? ? ? ? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "

? ? ? ? }

? ? }

? ? h6:before{

? ? ? ? counter-increment: h6;

? ? ? ? content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "

? ? }

}

```

# 再來簡單講一下道理

## CSS 自動編號

- 不是一個新特性,或者說是一個老特性了,出現在`CSS 2.1`中,搜索`site:w3.org css automatic numbering` 可以找到,當然截止今天后來的版本(`CSS 3`, `CSS 2.2`)都有這個特性,從`caniuse`上可以看到,`IE8`及以上兼容,很棒吧

- 簡單說明

? - `counter-reset` 重置

? - `counter-increment` ++

? - `counter()` 取值

? - 配合`before`和`after`來做

? - 還有更多的玩法,參見 `CSS The Defiiniitiive Guide 4th` ,這里有翻譯`gdut-yy/CSS-The-Definitive-Guide-4th-zh`

## Chrome插件或擴展開發

- 這個 我也沒實際搞過,原來看了看書

- 可參考的資料

? - 官方文檔

? - `sxei/chrome-plugin-demo` 或者搜索`Chrome插件 全攻略`

? - 《Chrome擴展及應用開發》,這個就是我原來看的那本老書

# 還是有些問題沒解決

- 上面的操作方式必須要`h1`到`h6`依次排開,不然會很好看

- 如果標題本身就編號了的,就有點糟糕了

- 這倆問題在我`github`的博客里面都能看到,解決辦法可以是運行下``

## 順便探索下`CSS`其他可變的內容

### CSS變量或者說自定義屬性

- 這個IE不兼容,其他瀏覽器高版本兼容

```

:root{

--var-test:xxx

}

.body{

--var-test:ooo;

prop-test:var(--var-test)

}

```

### attr()

- 這個`caniuse`也有些說不清楚,主體兼容也是從`IE8`開始的,需要自己總結

- 強大的地方是可以讀取屬性值,賦給另外的屬性,也就是可以來個屬性聯動

## 看起來純CSS的解決方案就到此告一段落了

- 如果能有腳本參與,就自由了

- `attr()` 配合偽類來做展示,是一個JS和CSS通信的一個比較好的方式

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,604評論 2 380