「Javascript」解析markdown為html——引用篇

1 前言
在建設自己的博客時,由于沒有實力置辦服務器和云服務器,而且也沒有這個必要。所以我想通過 github pages 托管自己的靜態網頁,但是對于靜態網站來說,數據的修改比較麻煩。截止今天,根據我的一些思路,用 javascript 將網站盡可能地動態化,對于數據修改可以達到 ”更新一處,處處更新” 的效果。并且選擇用 markdown 文本來存儲博客,在瀏覽器實時渲染,這是我的個人博客(點這里),歡迎訪問。網上看到的 js 庫雖然很強大,但是需要我調整 css 樣式以達到想要的效果,所以我選擇自己實現,這樣我自己熟悉生成的 html 文本,方便調整樣式。下文記錄將 markdown 引用塊解析為html引用塊標簽的實現方法。
2 分析
2.1 markdown中的引用塊
在 markdown 中,引用塊是通過符號 “>” 加空格進行標記,而且引用中還可以嵌套引用。如下代碼:
> 魯迅沒有說過
> 魯迅說過
>> 魯迅說過這一句
>> 魯迅還說過這一句
> 好像魯迅沒說過
markdown 的效果如下:

2.2 html中的引用塊
在html中,引用塊需要用標簽
<blockquote></blockquote>
包裹。比如:
<blockquot>
<p>
魯迅沒有說過
</p>
<p>
魯迅說過
</p>
<blockquot>
<p>
魯迅說過這一句
</p>
<p>
魯迅還說過這一句
</p>
</blockquot>
<p>
好像魯迅沒說過
</p>
</blockquot>
效果如下:
魯迅沒有說過
魯迅說過
魯迅說過這一句
魯迅還說過這一句
好像魯迅沒說過
2.3 分析對應關系
從中可以看出對應關系,連續的 “>” 符號表示這是一個連續的引用塊,多個 “>” 表示多級引用。對于一個連續的引用塊,使用 blockquote 標簽包裹,引用的一行可以使用 p 標簽標記。
3 代碼
/* 解析引用塊 */
// 假設 markdown 格式的引用塊為:
var md_quote = "> 魯迅沒有說過\n> 魯迅說過\n>> 魯迅說過這一句\n>> 魯迅還說過這一句\n> 好像魯迅沒說過";
function parsequoteblock(string) {//傳入一段 markdown 引用塊格式的字符串
var quote_html = "<blockquote>";//先使用一個 blockquote 標簽標記開始
var lines = string.split("\n");//將其分割成行
var i = 0;
var subquote = ""; // 用于記錄次級引用
while (i < lines.length - 1) {
if (lines[i].match(/^(>\x20?){2}/g) != null) { // 判斷二級及更高級次的引用
while (lines[i].match(/^(>\x20?){2}/g) != null) { //將次級引用拼接到一起
subquote += lines[i].replace(/^\>/g, ""); //拼接時去掉開頭的引用標記字符
i++;
}
quote_html += parsequoteblock(subquote); //遞歸調用,解析次級引用塊
}
else if (lines[i].match(/^(>\x20?){1}.+/g) != null) { //保證有內容再包裹為 p 標簽,防止空內容的 p 標簽出現
quote_html += "<p>" + replaceSpecialstyle(replaceSpecialsymbol(lines[i].slice(2, lines[i].length))) + "</p>";//將一行文字用 p 標簽包裹
i++;
}
else {
i++;
}
}
quote_html += "</blockquote>";//封閉 blockquote 標簽
return quote_html;//返回解析的字符串
}
4 總結
由于 markdown 編輯器的格式稍有不同,比如在 typora 中,次級引用格式是
> > 字符串
即兩個標記字符間也是有空格的。一開始方法是在判斷次級引用的地方判斷第二個字符是不是 > ,后來發現了格式上的小差異,遂改用正則匹配。我發現正則在大多數時候都是匹配字符串的最佳選擇(不接受反駁,我就愛正則),為了方便測試,我在自己的博客中簡單做了一個測試工具(點這里),歡迎使用。
由于正則表達式的使用,把原先的格式差異在一定程度上避免掉了,至于更多 markdown 編輯器的格式是否適用,有待進一步驗證。
浙公網安備 33010602011771號