mark down, word up
翻譯這篇文章的時候:https://zhuanlan.zhihu.com/p/30424780,我就在想如果能把markdown的一些特性引入word該多好,尤其是,把word裡面無比讓人蛋疼的自動編號功能給搞定該多好。
弄過畢業論文的同學都知道當文章有三級以上的標題的時候,讓編號能夠保持一致要有多麼的困難,尤其是當你不斷修改文章以後,編號必然會亂起來,然後你就要從頭到尾的修改……
有人說你可以用自動編號啊。嗯,但是自動編號並不是那麼自動呢,該連續編號的時候它不連續,該重新從1開始計數的時候它非要延續之前的編號,比如1.1,1.2,1.3,2.4,2.5,2.6,你特么是智障么?
人家markdown在這一塊就做的很好,你是一級標題,就在這一行最前面加一個#,二級標題就在最前面加2個#,三級3個#,以此類推。所以我一直想用python寫一段程序,識別一段文字裡面的#標識符,然後把標題的級別做進去。也就是把下面這一段文字:
# title main## title 1lorem blablabla### title 1.1lbalkphpa### title 1.2alkhlkhlkajhsdl## title 2ballkhalsdjfa## title 3 bla;lhakhladsf ### title 3.1### title 3.2### title 3.3## title 4
按照標題的上下級關聯形成樹結構。沒怎麼學過樹圖的實現,不過在DOM裡面大概有那麼一點點感覺,一時間也沒找到合適的庫,就自己寫一個好了。
class titleElem: def __init__(self,txt): self.lvl = 0 self.seq = 0 self.txt = txt self.children = [] self.parent = None self.breadScrum = (0,) def desc(self): desc = """title text:{0}title lvl:{1}, seq:{2}subtitle number:{3}breadScrum:{4}parent text:{5}siblings number:{6} """.format( self.txt, self.lvl, self.seq, len(self.children), self.breadScrum, self.parent.txt, len(self.getSiblings()) ) return desc def forceSet(self,lvl=0,seq=0): self.lvl = lvl self.seq = seq def addChild(self,child): child.parent = self self.children.append(child) child.updateSeq() def updateSeq(self): siblings = self.getSiblings() if len(siblings) == 1 or len(siblings) == 0: self.seq += 1 else: self.seq = siblings[siblings.index(self)-1].seq + 1 self.breadScrum = self.parent.breadScrum + (self.seq,) def getSiblings(self): assert self.parent != None,"no parent" return list(filter( lambda e:e.lvl<99, self.parent.children )) # filter out plain text
這個titleElem類是樹的節點,各個節點依靠addChild實現父子關係的建立。lvl是標題的級別,seq是標題的排列序號。文本這種非標題lvl被設置成99,表示最低級別。
import docx,refrom titleElem import titleElemfsrc = docx.Document(test.docx)paragraphs = fsrc.paragraphstxts = []reTtl = re.compile(r^(#+)s)rootEle = titleElem("root node")# how we going to do:# 1. from paragraphs get txt, using txts generate titleElem# 2. link paragraphs with txt with index, paragraphs[i] <> txts[i]# 3. construct hierachy in titleElems# 4. modify txt in titleElems with breadscrum update# 5. update txt in paragraph according to dict# 6. output modified docx with fsrc.save(xxx.docx)# init > addChild > updateSeqnibaba = rootEledef findNiBa(nibaba,e): assert nibaba.parent != None or nibaba.lvl == 0, "findNiBa got para with no parent:{0}".format(nibaba.desc()) if nibaba.lvl < e.lvl: nibaba.addChild(e) nibaba = e return nibaba elif nibaba.lvl == e.lvl: nibaba.parent.addChild(e) nibaba = e return nibaba else: return findNiBa(nibaba.parent,e)for i in range(len(paragraphs)): e = titleElem(paragraphs[i].text) mo = reTtl.search(e.txt) if mo != None: e.lvl = len(mo.group(1)) else: e.lvl = 99 # 如果屬於文本,作為最低級別,0是最高級別(root),1是一級標題,99就是最低級別了 nibaba = findNiBa(nibaba,e) txts.append(e)for i in range(len(txts)): if txts[i].lvl<99: print(txts[i].desc()) print(i)for e in txts[2].getSiblings(): print(e.desc())
這裡用了前面提到的docx庫。docx庫會把word文檔的所有段落存進paragraphs列表中,遍歷列表,按照標題級別逐個將各段串聯起來。
推薦閱讀:
※markdown中插入圖片怎麼定義圖片的大小或比例?
※Markdown 格式如何轉換成 Word?
※作業部落出品的Cmd Markdown 編輯閱讀器怎麼樣?有沒有同類型的更好的呢?
※如何用Markdown寫論文?
※Mac升級到sierra後,Mou不再兼容,有什麼好的工具可以替代?
TAG:Python | MicrosoftWord | Markdown |