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.pyempty_output.py的代码。最核心的转换算法python-markdown可以在GitHub上搜到。

整个程序的源码可以在这里得到。

run.py

    import os
    import markdown
    import codecs
    import sys
    
    reload(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_name
            full_ouput_file_name = ouput_dir + '/' + file_name + ouput_file_type
    
            with 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 os
    import markdown
    import codecs
    import sys
    
    reload(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_name
        os.remove(full_file_name)
        
    print '\nAll Done!'