如何用Python實(shí)現(xiàn)簡單的Markdown轉(zhuǎn)換器
今天心血來潮,寫了一個(gè) Markdown 轉(zhuǎn)換器。
import os, re,webbrowser text = ''' # TextHeader ## Header1 List - 1 - 2 - 3 > **quote** 》 quote2 ## Header2 1. *斜體* 2. [@以茄之名](http://www.dbjr.com.cn/people/e4f87c3476a926c1e2ef51b4fcd18fa3) 3、  ## Header3 `*[文章地址](https://zhuanlan.zhihu.com/p/39742445)*` ·**code1**· - [x]是否點(diǎn)贊 '''
程序開頭先處理一些行內(nèi)的語法,比如 code、strong、i 等,用正則直接替換:
text = re.sub(re.compile('([\`·])([^`·]+)[\`·]'), r'<code>\2</code>', text)
text = re.sub(re.compile('\*\*([^\*]+)\*\*'), r'<strong>\1</strong>', text)
text = re.sub(re.compile('([^\*])\*([^\*]+)\*'), r'\1<i>\2</i>', text)
接著是復(fù)雜一點(diǎn)的圖片和鏈接:
text = re.sub(re.compile('([^\!])\[([^\]]+)\]\(([^)]+)\)'),
r'\1<a href="\3" rel="external nofollow" target="_blank">\2</a>', text)
text = re.sub(re.compile('\!\[([^\]]*)\]\(([^)]+)\)'),
r'<img src="\2" >', text)
接著就處理其他的語法,先把文本按每一行分開:
lines = text.split('\n')
html = ''
list_flag = ''
處理列表和待辦事項(xiàng)的問題:
for line in lines:
line = line.strip(' ')
if re.match('- \[[ x]\]', line):
print('matched')
p_html = ''
if re.match('- \[x\]', line):
p_html = ' checked="checked"'
line = re.sub('- \[[ x]\]', '', line)
html += '''<label class="cssCheckbox">
<input type="checkbox" %s />
<span></span>%s
</label>''' % (p_html, line)
因?yàn)橛行蛄斜砗蜔o序列表的區(qū)別是頭尾的ol和ul,所以要用 list_flag 變量來判斷
elif re.match('[\+\-\*] ', line):
if list_flag == '':
html += '<ul>\n'
list_flag = 'ul'
line = re.sub('[\+\-\*] ', '', line)
html += '<li>%s</li>\n' % (line)
elif re.match('[\d]+[.、] ', line):
if list_flag == '':
list_flag = 'ol'
html += '<ol>\n'
line = re.sub('[\d]+[.、] ', '', line)
html += '<li>%s</li>\n' % (line)
處理完后處理其他的語法:
else:
if list_flag != '':
html += '</%s>\n' % list_flag
list_flag = ''
if re.match('\#+', line):
well = re.match('\#+', line).group().count('#')
line = re.sub('\#+', '', line)
html += '<h%i>%s</h%i>\n' % (well, line, well)
elif re.match('[>》 ]', line):
line = re.sub('^\s*[>》 ]', '', line)
html += '<blockquote>%s</blockquote>\n' % (line)
# elif re.match('[>》 ]', line):
# line = re.sub('^\s*[>》 ]', '', line)
# html += '<blockquote>%s</blockquote>\n' % (line)
else:
html += line
這里我稍微修改了一點(diǎn),讓 > 和 》 都可以轉(zhuǎn)換成引用,主要是切換中英文標(biāo)點(diǎn)太難了。
然后就是添加 CSS,自己改了一點(diǎn)馬克飛象的進(jìn)去,因?yàn)樗囊米龅煤芷粒?/p>
with open('markdown.html', 'w', encoding='utf-8')as f:
f.write('''
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>body{
margin: 0 auto;
font-family: "ubuntu", "Tahoma", "Microsoft YaHei", arial,sans-serif;
color: #444444;
line-height: 1;
padding: 30px;
}
input[type='checkbox']+span::before {
content:' ';/*不換行空格*/
display: inline-block;
vertical-align: 0.2em;
width:0.8em;
height:0.8em;
margin-right: .2em;
border-radius:.2em;
background: silver;/*復(fù)選框的背景色*/
text-indent:0.15em;
line-height: 0.65;
}
input[type='checkbox'] {
/*隱藏掉原先實(shí)際的 checkbox 框,之所以沒用 display:none; 這種簡單直接的方式,是因?yàn)檫@種方法會把它從鍵盤 tab 鍵切換焦點(diǎn)的隊(duì)列中完全刪除*/
position: absolute;
clip:rect(0,0,0,0);
}
input[type='checkbox']:checked+span::before {
content:'\u221a'; /*對號的 Unicode字符*/
background: yellowgreen;/*對號的顏色*/
}
img {
max-width: 100%;
}
@media screen and (min-width: 1000px) {
body {
width: 842px;
margin: 10px auto;
}
}
h1, h2, h3, h4 {
color: #111111;
font-weight: 400;
margin-top: 1em;
}
h1, h2, h3, h4, h5 {
font-family: Georgia, Palatino, serif;
}
h1, h2, h3, h4, h5, dl{
margin-bottom: 16px;
padding: 0;
}
p {
margin-top: 8px;
margin-bottom: 3px;
}
h1 {
font-size: 48px;
line-height: 54px;
}
h2 {
font-size: 36px;
line-height: 42px;
}
h1, h2 {
border-bottom: 1px solid #EFEAEA;
padding-bottom: 10px;
}
h3 {
font-size: 24px;
line-height: 30px;
}
h4 {
font-size: 21px;
line-height: 26px;
}
h5 {
font-size: 18px;
line-height: 23px;
}
a {
color: #0099ff;
margin: 0 2px;
padding: 0;
vertical-align: baseline;
text-decoration: none;
}
a:hover {
text-decoration: none;
color: #ff6600;
}
a:visited {
/*color: purple;*/
}
ul, ol {
padding: 0;
padding-left: 18px;
margin: 0;
}
li {
line-height: 24px;
}
p, ul, ol {
font-size: 16px;
line-height: 24px;
}
ol ol, ul ol {
list-style-type: lower-roman;
}
code, pre {
font-family: Consolas, Monaco, Andale Mono, monospace;
background-color:#f7f7f7;
color: inherit;
}
code {
font-family: Consolas, Monaco, Andale Mono, monospace;
margin: 0 2px;
}
pre {
font-family: Consolas, Monaco, Andale Mono, monospace;
line-height: 1.7em;
overflow: auto;
padding: 6px 10px;
border-left: 5px solid #6CE26C;
}
pre > code {
font-family: Consolas, Monaco, Andale Mono, monospace;
border: 0;
display: inline;
max-width: initial;
padding: 0;
margin: 0;
overflow: initial;
line-height: 1.6em;
font-size: .95em;
white-space: pre;
background: 0 0;
}
code {
color: #666555;
}
aside {
display: block;
float: right;
width: 390px;
}
blockquote {
border-left-width: 10px;
background-color: rgba(102,128,153,0.05);
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
padding: 15px 20px;
}
blockquote cite {
font-size:14px;
line-height:20px;
color:#bfbfbf;
}
blockquote cite:before {
content: '\2014 \00A0';
}
blockquote p {
color: #666;
}
hr {
text-align: left;
color: #999;
height: 2px;
padding: 0;
margin: 16px 0;
background-color: #e7e7e7;
border: 0 none;
}
dl {
padding: 0;
}
dl dt {
padding: 10px 0;
margin-top: 16px;
font-size: 1em;
font-style: italic;
font-weight: bold;
}
dl dd {
padding: 0 16px;
margin-bottom: 16px;
}
dd {
margin-left: 0;
}
table {
*border-collapse: collapse; /* IE7 and lower */
border-spacing: 0;
width: 100%;
}
table {
border: solid #ccc 1px;
}
table thead {
background: #f7f7f7;
}
table thead tr:hover {
background: #f7f7f7
}
table tr:hover {
background: #fbf8e9;
-o-transition: all 0.1s ease-in-out;
-webkit-transition: all 0.1s ease-in-out;
-moz-transition: all 0.1s ease-in-out;
-ms-transition: all 0.1s ease-in-out;
transition: all 0.1s ease-in-out;
}
table td, .table th {
border-left: 1px solid #ccc;
border-top: 1px solid #ccc;
padding: 10px;
text-align: left;
}
table th {
border-top: none;
text-shadow: 0 1px 0 rgba(255,255,255,.5);
padding: 5px;
border-left: 1px solid #ccc;
}
table td:first-child, table th:first-child {
border-left: none;
}</style></head>''')
f.write(html)
f.write('</html>')
用 Chrome 打開網(wǎng)頁:
webbrowser.get('C:/Program Files (x86)/CentBrowser/Application/chrome.exe %s').open(
'file:///'+os.getcwd()+'/markdown.html')
話說這里也是個(gè)坑,系統(tǒng)自帶的 Edge 一直打開失敗,用那個(gè)注冊器注冊 Chrome 也沒辦法用 ,最后還是在外網(wǎng)找到了解決方案。
最后的效果:

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 獲取CSDN文章內(nèi)容并轉(zhuǎn)換為markdown文本的python
- Python3自動生成MySQL數(shù)據(jù)字典的markdown文本的實(shí)現(xiàn)
- python使用html2text庫實(shí)現(xiàn)從HTML轉(zhuǎn)markdown的方法詳解
- 解決python Markdown模塊亂碼的問題
- python導(dǎo)出chrome書簽到markdown文件的實(shí)例代碼
- python 自動化將markdown文件轉(zhuǎn)成html文件的方法
- 使用Python來開發(fā)Markdown腳本擴(kuò)展的實(shí)例分享
- python3處理word文檔實(shí)例分析
- Python word文本自動化操作實(shí)現(xiàn)方法解析
- Python操作word文檔插入圖片和表格的實(shí)例演示
- Python實(shí)現(xiàn)Word文檔轉(zhuǎn)換Markdown的示例
相關(guān)文章
python實(shí)現(xiàn)簡單點(diǎn)對點(diǎn)(p2p)聊天
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)簡單點(diǎn)對點(diǎn)p2p聊天,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
關(guān)于Python?Tkinter?復(fù)選框?->Checkbutton
這篇文章主要介紹了關(guān)于Python?Tkinter復(fù)選框Checkbutton,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09
Python基于React-Dropzone實(shí)現(xiàn)上傳組件的示例代碼
本文主要介紹了在React-Flask框架上開發(fā)上傳組件的技巧。文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
淺述python中argsort()函數(shù)的實(shí)例用法
本篇文章主要介紹了淺述python中argsort()函數(shù)的實(shí)例用法,詳細(xì)的介紹了argsort()函數(shù)的用法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03
opencv3/C++實(shí)現(xiàn)視頻背景去除建模(BSM)
今天小編就為大家分享一篇opencv3/C++實(shí)現(xiàn)視頻背景去除建模(BSM),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12
如何用python多次調(diào)用exe文件運(yùn)行不同的結(jié)果
有個(gè)C++項(xiàng)目是讀取配置參數(shù)文件并打印對應(yīng)的結(jié)果,后來需要多次修改配置文件并運(yùn)行,于是想到寫個(gè)python腳本執(zhí)行這一過程,今天通過本文給大家分享python多次調(diào)用exe文件運(yùn)行不同的結(jié)果,感興趣的朋友一起看看吧2023-05-05
詳解小白之KMP算法及python實(shí)現(xiàn)
在看子串匹配問題的時(shí)候,書上的關(guān)于KMP的算法的介紹總是理解不了??戳艘槐榇a總是很快的忘掉,后來決定好好分解一下KMP算法,算是給自己加深印象。感興趣的朋友跟隨小編一起看看吧2019-04-04
GPU狀態(tài)監(jiān)測?nvidia-smi?命令的用法詳解
這篇文章主要介紹了GPU狀態(tài)監(jiān)測?nvidia-smi?命令的用法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11

