如何用Python實現(xiàn)簡單的Markdown轉(zhuǎn)換器
今天心血來潮,寫了一個 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]是否點贊 '''
程序開頭先處理一些行內(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ù)雜一點的圖片和鏈接:
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 = ''
處理列表和待辦事項的問題:
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)
因為有序列表和無序列表的區(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
這里我稍微修改了一點,讓 > 和 》 都可以轉(zhuǎn)換成引用,主要是切換中英文標(biāo)點太難了。
然后就是添加 CSS,自己改了一點馬克飛象的進去,因為他的引用做得很漂亮:
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'] { /*隱藏掉原先實際的 checkbox 框,之所以沒用 display:none; 這種簡單直接的方式,是因為這種方法會把它從鍵盤 tab 鍵切換焦點的隊列中完全刪除*/ 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')
話說這里也是個坑,系統(tǒng)自帶的 Edge 一直打開失敗,用那個注冊器注冊 Chrome 也沒辦法用 ,最后還是在外網(wǎng)找到了解決方案。
最后的效果:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 獲取CSDN文章內(nèi)容并轉(zhuǎn)換為markdown文本的python
- Python3自動生成MySQL數(shù)據(jù)字典的markdown文本的實現(xiàn)
- python使用html2text庫實現(xiàn)從HTML轉(zhuǎn)markdown的方法詳解
- 解決python Markdown模塊亂碼的問題
- python導(dǎo)出chrome書簽到markdown文件的實例代碼
- python 自動化將markdown文件轉(zhuǎn)成html文件的方法
- 使用Python來開發(fā)Markdown腳本擴展的實例分享
- python3處理word文檔實例分析
- Python word文本自動化操作實現(xiàn)方法解析
- Python操作word文檔插入圖片和表格的實例演示
- Python實現(xiàn)Word文檔轉(zhuǎn)換Markdown的示例
相關(guān)文章
關(guān)于Python?Tkinter?復(fù)選框?->Checkbutton
這篇文章主要介紹了關(guān)于Python?Tkinter復(fù)選框Checkbutton,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09Python基于React-Dropzone實現(xiàn)上傳組件的示例代碼
本文主要介紹了在React-Flask框架上開發(fā)上傳組件的技巧。文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08淺述python中argsort()函數(shù)的實例用法
本篇文章主要介紹了淺述python中argsort()函數(shù)的實例用法,詳細的介紹了argsort()函數(shù)的用法,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-03-03opencv3/C++實現(xiàn)視頻背景去除建模(BSM)
今天小編就為大家分享一篇opencv3/C++實現(xiàn)視頻背景去除建模(BSM),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12如何用python多次調(diào)用exe文件運行不同的結(jié)果
有個C++項目是讀取配置參數(shù)文件并打印對應(yīng)的結(jié)果,后來需要多次修改配置文件并運行,于是想到寫個python腳本執(zhí)行這一過程,今天通過本文給大家分享python多次調(diào)用exe文件運行不同的結(jié)果,感興趣的朋友一起看看吧2023-05-05GPU狀態(tài)監(jiān)測?nvidia-smi?命令的用法詳解
這篇文章主要介紹了GPU狀態(tài)監(jiān)測?nvidia-smi?命令的用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11