前言
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)