當在GitHub Pages上使用Minimal Mistakes作為Jekyll主題時,會遇到中文字數統計錯誤的問題,一整段話被統計為1個字。本篇文章將會簡單説明問題的來源和解決方案。
問題來源
Minimal Mistakes在_includes/page__meta.html中,使用了document.content | strip_html | number_of_words來計算文章字數(相關代碼),這一步將document.content去除HTML標籤,然後調用number_of_words函數計算字數。
number_of_words函數由Jekyll實現。GitHub Pages使用的Jekyll版本為3.9.0,根據其實現,計算字數的代碼僅僅為input.split.length,根據Ruby文檔,將會根據空格分割文本,然後輸出分割後的文本數量。也就是説,會根據空格的數量來確定字數。這樣的做法對於英文文章來説自然問題不大,但並不適合中文。
解決方案
解決這個問題有多種方案,前2個方案無法在GitHub Pages上獨立完成,需要搭配GitHub Action或其他CI;最後1種方案可以在純GitHub Pages的環境中使用。
如果修改了Minimal Mistakes的文件,將其放在自己倉庫下便可覆蓋默認文件。
自定義插件
這是最優雅的方法,通過自定義插件可以在不覆蓋Minimal Mistakes文件的情況下修復問題。
下載這個文件放置於_plugins/number_of_words.rb便可。
升級Jekyll
這是最簡單直接的方法,在4.1.0版本的Jekyll中,這個問題被修復了。
當然,除了升級以外還需要將_includes/page__meta.html中的number_of_words修改為number_of_words: "auto"或者number_of_words: "cjk"才能正常生效。
覆蓋主題文件
這個方法使用了Liquid模板引擎的語法,可以不依賴任何CI,直接在GitHub Pages上使用。
用以下代碼替換_includes/page__meta.html中的{% assign words = document.content | strip_html | number_of_words %}:
{% assign content0 = document.content | strip_html %}
{% assign content_size = content0 | size | minus: 1 %}
{% assign pre_is_letter = false %}
{% assign words = 0 %}
{% for i in (0..content_size) %}
{% assign character = content0 | slice: i %}
{% case character %}
{% when "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" %}
{% assign pre_is_letter = true %}
{% when "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" %}
{% assign pre_is_letter = true %}
{% when "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" %}
{% assign pre_is_letter = true %}
{% when " ", "\t", "\r", "\n", "!", ".", "?", ",", "!", "。", "?", ",", "/", "、", ":", ":", "(", "(", ")", ")", ";", ";", "_", "—", "-" %}
{% if pre_is_letter %}
{% assign words = words | plus: 1 %}
{% endif %}
{% assign pre_is_letter = false %}
{% else %}
{% if pre_is_letter %}
{% assign words = words | plus: 1 %}
{% endif %}
{% assign pre_is_letter = false %}
{% assign words = words | plus: 1 %}
{% endcase %}
{% endfor %}
這部分代碼是作者自己編寫的,歡迎多多交流。
感謝
最後特別感謝iBug引導了修復方向。