美文网首页
造轮子: 优雅的将 Markdown 转 Html(利用正则表达

造轮子: 优雅的将 Markdown 转 Html(利用正则表达

作者: linheimx | 来源:发表于2017-08-30 22:17 被阅读316次

    前言

    Markdown语法简单,老衲最近又闲的蛋疼,索性用Python写个转换工具,特记录如下。

    Markdown 简单明了,我们写的文档,在浏览器中可以展现出有格式化的文档
    那么这个格式化的文档是怎么来的?

    我们写出的文档最终要显示到浏览器上,Html可以轻松的组织文档的结构,将Markdown转换成Html,是个不错的选择。

    下面我选取几个常用的语法,写出转换思路,供大家参考。

    核心思想

    利用正则表达式,筛选出我们想要的目标,将该目标替换成Html的语法。


    语法:标题

    语法形式如下:

    # 这是 H1
    
    ## 这是 H2
    
    ### 这是 H3
    
    

    用正则表达式来描述:
    (#{1,6})\s*(.*?)\s*$
    替换成html标签:

    def process_header(text: str):
        pat = re.compile(r"^(#{1,6})\s*(.*?)\s*$", re.M)
    
        def rep(match):
            tags = match.group(1)  # type:str
            content = match.group(2)
    
            tag_start = '<h{}>'.format(str(len(tags)))
            tag_end = '</h{}>'.format(str(len(tags)))
            return tag_start + content + tag_end
    
        return pat.sub(repl=rep, string=text)
    

    语法:强调

    语法形式如下:

    *single asterisks*
    
    _single underscores_
    
    **double asterisks**
    
    __double underscores__
    

    用正则表达式来描述:
    ([*|_]{1,2})(.*)\1$
    替换成html标签:

    def process_emphasize(text: str):
        pat = re.compile(r"([*|_]{1,2})(.*)\1", re.DOTALL)
    
        def rep(match):
            tags = match.group(1)  # type:str
            content = match.group(2)
    
            if len(tags) == 2:
                t = 'strong'
            elif len(tags) == 1:
                t = 'em'
    
            tag_start = '<{}>'.format(t)
            tag_end = '</{}>'.format(t)
            return tag_start + content + tag_end
    
        return pat.sub(repl=rep, string=text)
    
    

    语法:列表

    语法形式如下:

    *   Red
    *   Green
    *   Blue
    --------------
    +   Red
    +   Green
    +   Blue
    -------------
    -   Red
    -   Green
    -   Blue
    -------------
    1.  Bird
    2.  McHale
    3.  Parish
    

    用正则表达式来描述:

    (
        ([\s\t]*)([*|+|-]|\d+[.])[\s]+      # start
        (?s:.+?)  
        (\Z|       # end  (End of input)
        (?=(\n\s*\n*)+(?!([\s\t]*)([*|+|-]|\d+[.])[\s]))  # end  (下一段 非序列标志)  
        )                         
    ) 
    

    替换成html标签:

    def process_list(text: str):
        pat = re.compile(r"""
            (
                ([\s\t]*)([*|+|-]|\d+[.])[\s]+      # start
                (?s:.+?)  
                (\Z|       # end  (End of input)
                (?=(\n\s*\n*)+(?!([\s\t]*)([*|+|-]|\d+[.])[\s]))  # end  (下一段 非序列标志)  (?!([\s\t]*)([*|+|-]|\d+[.])[\s])
                )                         
            )   
            """, re.M | re.X)
    
        def rep(match):
            m_tag = match.group(3)
            if len(m_tag) == 1:
                h_tag = 'ul'
            else:
                h_tag = 'ol'
            result = process_list_one(match.group(1))
            return "<{tag}>{result}</{tag}>".format(tag=h_tag, result=result)
    
        return pat.sub(repl=rep, string=text)
    
    ----------------------------------------------------
    def process_list_one(text: str):
        pat = re.compile(r"""
                (
                    ([\s\t]*)([*|+|-]|\d+[.])[\s]+      # start
                    ((?s:.+?))  
                    ((?=([\s\t]*)([*|+|-]|\d+[.])[\s]+)| # end
                     \Z| 
                    (?=(\n\s*\n*)+) 
                    )                          
                )   
                """, re.M | re.X)
    
        def rep(match):
            return "<{tag}>{content}</{tag}>".format(tag='li', content=match.group(4))
    
        return pat.sub(repl=rep, string=text)
    
    

    引用

    相关文章

      网友评论

          本文标题:造轮子: 优雅的将 Markdown 转 Html(利用正则表达

          本文链接:https://www.haomeiwen.com/subject/wdqfjxtx.html