Markdown文件導出為HTML的小程序
為什么做
最近把一些學習經驗記下來,總結成MarkDown文件,不知不覺已經有12篇了。
Sublime Text 的 MarkDown Preview 插件能夠將MarkDown語法轉換為HTML,并提供三種預覽方式:瀏覽器預覽、保存為HTML文件、輸出到Sublime的新標簽頁。
但有一個缺點是,我有12個MarkDown文件,想分別轉換為HTML文件,需要重復執行12次打開文件->Crtl+P調出命令面板->輸入MarkDown Preview->選擇Save To HTML->選擇保存路徑->確定
。
我突發奇想,Sublime是基于Python的,何不利用MarkDown Preview的API,寫一個Python腳本,進行批量轉換。這樣,無論是12篇,還是120篇,都可以通過一個命令輕松完成轉換,避免了重復勞動。
怎么做的
我通過Sublime的Preferences->Browse Packages找到了一個名為python-markdwon
的文件夾,似乎是用來支持MarkDown轉換的。
閱讀了其中的__init__.py
文件,了解到這個包可以將MarkDown轉換為HTML。它提供了兩個API:
html = markdown.markdown(your_text_string)
html = markdown.markdownFromFile(file_name)
如此簡單易用,就是它了!
經過測試,markdown.markdownFromFile()
這個函數對中文支持較差:如果文件內容含有漢字,轉換后的html字符串出現奇怪的亂碼。似乎可以提供附加參數指定編碼格式,但我決定不去偷這個懶(好吧,其實是懶得去研究源代碼)。
設計思路很簡單:
在指定文件夾內讀取所有.md文件:
for x in os.listdir('./input'): if os.path.splitext(x)[1]=='.md':...
對每個.md文件,其內容是一個字符串
with open('/path/file_name.md', 'r') as f:md = f.read()
利用
markdown.markdown()
轉換為HTML格式對字符串
html = markdown.markdown(md)
將HTML格式字符串寫入到.html文件內
with open('/path/file_name.html', 'w') as f:f.write(html)
當然,其中還要考慮路徑、字符編碼等問題。這里并沒有列出,詳細代碼可參看下文。
怎么用
我建立了這樣的文件結構:
.|---markdown||---input| |---1.md| |---2.md||---output| |---1.html| |---2.html||---run.py||---empty_output.py
markdown文件夾
是從Sublime插件目錄的python-markdown
直接復制過來的。
input文件夾
內放的是轉換前的MarkDown文件,目前只支持英文文件名。
output文件夾
里是自動生產的轉換后的HTML文件,與對應的MarkDown文件同名。
run.py
是執行的腳本文件,用來將MarkDown轉換為HTML。
empty_output.py
用來清空output文件夾的內容,但不刪除該文件夾。
運行步驟很簡單:
將MarkDown文件通通放入input文件夾下
命令行執行
python run.py
去output文件夾下找轉換后的文件
為什么只支持英文文件名呢?這個問題我也想解決,搜了一些博客,在MacOS下測試中文文件名都一切OK。但是換到了Windows下就翻臉不認人。還是我Python道行太淺,索性就只支持英文文件名吧。
做出了什么
這里貼一下run.py
和empty_output.py
的代碼。最核心的轉換算法python-markdown可以在GitHub上搜到。
整個程序的源碼可以在這里得到。
run.py
import osimport markdownimport codecsimport sysreload(sys)sys.setdefaultencoding('utf-8')input_dir = './input'ouput_dir = './output'input_file_type = '.md'ouput_file_type = '.html'print '\n'for full_input_file_name in os.listdir(input_dir):if os.path.splitext(full_input_file_name)[1]==input_file_type:print 'Converting ' + full_input_file_name + ' ...'file_name = os.path.splitext(full_input_file_name)[0]full_input_file_name = input_dir + '/' + full_input_file_namefull_ouput_file_name = ouput_dir + '/' + file_name + ouput_file_typewith codecs.open(full_input_file_name, 'r') as ifile:in_file_content = ifile.read()ou_file_content = markdown.markdown(in_file_content)with codecs.open(full_ouput_file_name, 'w', 'gbk') as ofile:ofile.write(ou_file_content)print '\nAll Done!'
empty_output.py
import osimport markdownimport codecsimport sysreload(sys)sys.setdefaultencoding('utf-8')ouput_dir = './output'print '\n'for file_name in os.listdir(ouput_dir):print 'Deleting ' + file_name + ' ...'full_file_name = ouput_dir + '/' + file_nameos.remove(full_file_name)print '\nAll Done!'