使用python转换markdown to html

起因

有很多编辑器可以直接将markdown转换成html,为什么还要自己写呢?因为我想写完markdown之后,即可以保存在笔记软件中(比如有道),又可以放到github进行版本管理,还可以发布到博客(比如博客园)。这些如果都操作一遍,是很繁琐的,所以必须交给脚本去做。

原材料

  • markdown2 or mistune
  • pygments

操作原理

  • 首先,我需要一个markdown的词法解析器,然后我需要html转换器。这个可以由markdown2或者mistune来完成。
  • 然后,我的笔记中有较多的代码,我需要代码高亮。这首先需要将markdown中的代码块提取出来,然后判断是哪种语言,然后进行着色。这部分可以由pyments完成

代码

使用mistune(源码很有学习价值)。需要自己引入pygments模块渲染代码块,官网有参考例子。

import mistune
import sys
import codecs
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import html

class HighlightRenderer(mistune.Renderer):
    def block_code(self, code, lang):
        if not lang:
            return ‘\n<pre><code>%s</code></pre>\n‘ %                 mistune.escape(code)
        lexer = get_lexer_by_name(lang, stripall=True)
        formatter = html.HtmlFormatter()
        return highlight(code, lexer, formatter)

def main(argv):
    name = argv[0]

    input_file = codecs.open(name, mode=‘r‘, encoding=‘utf-8‘)

    text = input_file.read()
    renderer = HighlightRenderer()
    markdown = mistune.Markdown(renderer=renderer)
    html = markdown(text)

    html_name = ‘%s.html‘ % (name[:-3])
    output_file = codecs.open(
        html_name, ‘w‘, encoding=‘utf-8‘, errors=‘xmlcharrefreplace‘)

    output_file.write(html)

if __name__ == "__main__":
    main(sys.argv[1:])

上面代码还不能使代码着色,因为没有指定css,还需要在生成的html头中加入css,不同的css文件可以在http://richleland.github.io/pygments-css/找到。

<style type = "text/css">
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #60a0b0; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #007020; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.highlight .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #007020 } /* Comment.Preproc */
.highlight .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
.highlight .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #808080 } /* Generic.Output */
.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0040D0 } /* Generic.Traceback */
.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #007020 } /* Keyword.Pseudo */
.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #902000 } /* Keyword.Type */
.highlight .m { color: #40a070 } /* Literal.Number */
.highlight .s { color: #4070a0 } /* Literal.String */
.highlight .na { color: #4070a0 } /* Name.Attribute */
.highlight .nb { color: #007020 } /* Name.Builtin */
.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
.highlight .no { color: #60add5 } /* Name.Constant */
.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #007020 } /* Name.Exception */
.highlight .nf { color: #06287e } /* Name.Function */
.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #bb60d5 } /* Name.Variable */
.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #40a070 } /* Literal.Number.Float */
.highlight .mh { color: #40a070 } /* Literal.Number.Hex */
.highlight .mi { color: #40a070 } /* Literal.Number.Integer */
.highlight .mo { color: #40a070 } /* Literal.Number.Oct */
.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
.highlight .sc { color: #4070a0 } /* Literal.String.Char */
.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
.highlight .sx { color: #c65d09 } /* Literal.String.Other */
.highlight .sr { color: #235388 } /* Literal.String.Regex */
.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
.highlight .ss { color: #517918 } /* Literal.String.Symbol */
.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
.highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */
</style>

所以完整的代码应该为:

import mistune
import sys
import codecs
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import html

class HighlightRenderer(mistune.Renderer):
    def block_code(self, code, lang):
        if not lang:
            return ‘\n<pre><code>%s</code></pre>\n‘ %                 mistune.escape(code)
        lexer = get_lexer_by_name(lang, stripall=True)
        formatter = html.HtmlFormatter()
        return highlight(code, lexer, formatter)

def main(argv):
    md_name = argv[0]

    with codecs.open(md_name, mode=‘r‘, encoding=‘utf-8‘) as mdfile:
        with codecs.open("friendly.css",mode = ‘r‘,encoding = ‘utf-8‘) as cssfile:
            md_text = mdfile.read()
            css_text = cssfile.read()
            renderer = HighlightRenderer()
            markdown = mistune.Markdown(renderer=renderer)
            html_text = markdown(md_text)

            html_name = ‘%s.html‘ % (md_name[:-3])
            with codecs.open(html_name, ‘w‘, encoding=‘utf-8‘, errors=‘xmlcharrefreplace‘) as output_file:
                output_file.write(css_text + html_text)

if __name__ == "__main__":
    if len(sys.argv) == 2:
        main(sys.argv[1:])
    else:
        print("Error:please specify markdown file path")

friendly.css文件中存放之前的css文件。

同样使用markdown2的代码如下:

import markdown2
import codecs
import sys

def main(argv):
    md_name = argv[0]

    with codecs.open(md_name, mode=‘r‘, encoding=‘utf-8‘) as mdfile:
        with codecs.open("friendly.css", mode=‘r‘, encoding=‘utf-8‘) as cssfile:
            md_text = mdfile.read()
            css_text = cssfile.read()

            extras = [‘code-friendly‘, ‘fenced-code-blocks‘, ‘footnotes‘]
            html_text = markdown2.markdown(md_text, extras=extras)

            html_name = ‘%s.html‘ % (md_name[:-3])
            with codecs.open(html_name, ‘w‘, encoding=‘utf-8‘, errors=‘xmlcharrefreplace‘) as output_file:
                output_file.write(css_text + html_text)

if __name__ == "__main__":
    if len(sys.argv) == 2:
        main(sys.argv[1:])
    else:
        print("Error:please specify markdown file path")
时间: 2024-11-07 23:45:18

使用python转换markdown to html的相关文章

python实现markdown文件字段批量替换

python实现markdown文件字段替换 需求 买了新域名后,七牛云的图床链接需要从xuetao.co替换到senup.cn,具体操作是要从本地众多markdown文件里面批量替换七牛云的图床地址,然而手动操作又太麻烦.因此,用python进行文件处理最合适了. 方法 #!/usr/bin/env python # -*- coding:utf-8 -*- import os import re import time def modify_md_content(top): for root

使用python转换编码格式

之前有写过一个使用powershell转换文档格式的方法,然而因为powershell支持不是很全,所以并不好用.这里使用python再做一个. 思路 检测源码格式,如果不是utf8,则进行转换,否则跳过 代码 import chardet import sys import codecs def findEncoding(s): file = open(s, mode='rb') buf = file.read() result = chardet.detect(buf) file.close

python转换excel成py文件

文件结构如下: originExcelFolder放用来转换的excel文件. targetPyFolder用来存放最后生产的py文件. setting.py用来配置excel表到py的对应关系. excel2py.py是主要的处理文件. Excel文件,A注意表名字,B注意sheet名字. 代码如下: setting.py #!/usr/bin/env python #-*- coding: utf-8 -*- # setting.py # 定义生成py表的格式 Dict ={ "studen

GDB 运行PYTHON 脚本+python 转换GDB调用栈到流程图

http://tromey.com/blog/?cat=17 http://blog.csdn.net/cnsword/article/details/16337031 http://blog.csdn.net/woohello/article/details/7326615 转换GDB调用栈到流程图 http://blog.csdn.net/HorkyChen/article/details/23307921 http://blog.csdn.net/horkychen/article/det

python 转换数字为钱数

目标: 输入一串数字,将其输出为几元几角几分 程序: #!/usr/bin/env python #coding:utf8 num_dict = {'1':'一','2':'二','3':'三','4':'四','5':'五', '6':'六','7':'七','8':'八','9':'九'} money_dict = {'-2':'分','-1':'角','0':'元','1':'十', '2':'百','3':'千','4':'万','8':'亿'} def trans(money): mo

Markdown入门基础

Markdown入门基础 最近准备开始强迫自己写博文,以治疗严重的拖延症,再不治疗就“病入骨髓,司命之所属,无奈何”了啊.正所谓“工欲善其事,必先利其器”,于是乎在写博文前,博主特地研究了下博文的写作方式,碰巧发现了Markdown这个神奇的东西.由于博主经常用Latex写东西,本身就对这类标记语言很有好感,再加上Markdown本身简单易学的特性,博主一下子就沉浸其中不能自拨了.作为一个准码农,写博文的方式怎么着也得跟编码有关,是不是?在网上找了几篇教程研究了下,发现这货虽然简单,但是文本编辑

Python代码样例列表

├─algorithm│       Python用户推荐系统曼哈顿算法实现.py│      NFA引擎,Python正则测试工具应用示例.py│      Python datetime计时程序的实现方法.py│      python du熊学斐波那契实现.py│      python lambda实现求素数的简短代码.py│      Python localtime()方法计算今天是一年中第几周.py│      Python math方法算24点代码详解.py│      Pyth

All Things Markdown

https://javachen.github.io/ 概述 特点 语法 编辑器 浏览器插件 实现版本 参考资料 概述 Markdown 是一种轻量级标记语言,创始人为约翰·格鲁伯(John Gruber)和亚伦·斯沃茨(Aaron Swartz).它允许人们"使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文档".这种语言吸收了很多在电子邮件中已有的纯文本标记的特性. 特点 兼容 HTML 要在Markdown中输写HTML区块元素,比如<div&g

[python][django学习篇[13]]增加markdown_1

1 进入虚拟环境,安装markdwon  python install markdown 2 修改视图函数detail def detail(request, pk): # get_object_or_404当传入的pk对应的post数据存在时,就会返回post数据否则返回404 # 需要导入 import markdwon post = get_object_or_404(Post, pk=pk) post.body = markdown.markdown(post.body, extensi