1#!/usr/bin/env Python 2""" 3Definition List Extension for Python-Markdown 4============================================= 5 6Added parsing of Definition Lists to Python-Markdown. 7 8A simple example: 9 10 Apple 11 : Pomaceous fruit of plants of the genus Malus in 12 the family Rosaceae. 13 : An american computer company. 14 15 Orange 16 : The fruit of an evergreen tree of the genus Citrus. 17 18Copyright 2008 - [Waylan Limberg](http://achinghead.com) 19 20""" 21 22import markdown, re 23from markdown import etree 24 25 26class DefListProcessor(markdown.blockprocessors.BlockProcessor): 27 """ Process Definition Lists. """ 28 29 RE = re.compile(r'(^|\n)[ ]{0,3}:[ ]{1,3}(.*?)(\n|$)') 30 31 def test(self, parent, block): 32 return bool(self.RE.search(block)) 33 34 def run(self, parent, blocks): 35 block = blocks.pop(0) 36 m = self.RE.search(block) 37 terms = [l.strip() for l in block[:m.start()].split('\n') if l.strip()] 38 d, theRest = self.detab(block[m.end():]) 39 if d: 40 d = '%s\n%s' % (m.group(2), d) 41 else: 42 d = m.group(2) 43 #import ipdb; ipdb.set_trace() 44 sibling = self.lastChild(parent) 45 if not terms and sibling.tag == 'p': 46 # The previous paragraph contains the terms 47 state = 'looselist' 48 terms = sibling.text.split('\n') 49 parent.remove(sibling) 50 # Aquire new sibling 51 sibling = self.lastChild(parent) 52 else: 53 state = 'list' 54 55 if sibling and sibling.tag == 'dl': 56 # This is another item on an existing list 57 dl = sibling 58 if len(dl) and dl[-1].tag == 'dd' and len(dl[-1]): 59 state = 'looselist' 60 else: 61 # This is a new list 62 dl = etree.SubElement(parent, 'dl') 63 # Add terms 64 for term in terms: 65 dt = etree.SubElement(dl, 'dt') 66 dt.text = term 67 # Add definition 68 self.parser.state.set(state) 69 dd = etree.SubElement(dl, 'dd') 70 self.parser.parseBlocks(dd, [d]) 71 self.parser.state.reset() 72 73 if theRest: 74 blocks.insert(0, theRest) 75 76class DefListIndentProcessor(markdown.blockprocessors.ListIndentProcessor): 77 """ Process indented children of definition list items. """ 78 79 ITEM_TYPES = ['dd'] 80 LIST_TYPES = ['dl'] 81 82 def create_item(parent, block): 83 """ Create a new dd and parse the block with it as the parent. """ 84 dd = markdown.etree.SubElement(parent, 'dd') 85 self.parser.parseBlocks(dd, [block]) 86 87 88 89class DefListExtension(markdown.Extension): 90 """ Add definition lists to Markdown. """ 91 92 def extendMarkdown(self, md, md_globals): 93 """ Add an instance of DefListProcessor to BlockParser. """ 94 md.parser.blockprocessors.add('defindent', 95 DefListIndentProcessor(md.parser), 96 '>indent') 97 md.parser.blockprocessors.add('deflist', 98 DefListProcessor(md.parser), 99 '>ulist') 100 101 102def makeExtension(configs={}): 103 return DefListExtension(configs=configs) 104 105