16516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru#!/usr/bin/env Python 26516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru""" 36516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste QueruDefinition List Extension for Python-Markdown 46516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru============================================= 56516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 66516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste QueruAdded parsing of Definition Lists to Python-Markdown. 76516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 86516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste QueruA simple example: 96516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 106516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru Apple 116516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru : Pomaceous fruit of plants of the genus Malus in 126516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru the family Rosaceae. 136516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru : An american computer company. 146516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 156516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru Orange 166516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru : The fruit of an evergreen tree of the genus Citrus. 176516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 186516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste QueruCopyright 2008 - [Waylan Limberg](http://achinghead.com) 196516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 206516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru""" 216516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 226516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queruimport markdown, re 236516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Querufrom markdown import etree 246516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 256516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 266516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queruclass DefListProcessor(markdown.blockprocessors.BlockProcessor): 276516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru """ Process Definition Lists. """ 286516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 296516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru RE = re.compile(r'(^|\n)[ ]{0,3}:[ ]{1,3}(.*?)(\n|$)') 306516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 316516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru def test(self, parent, block): 326516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru return bool(self.RE.search(block)) 336516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 346516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru def run(self, parent, blocks): 356516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru block = blocks.pop(0) 366516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru m = self.RE.search(block) 376516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru terms = [l.strip() for l in block[:m.start()].split('\n') if l.strip()] 386516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru d, theRest = self.detab(block[m.end():]) 396516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if d: 406516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru d = '%s\n%s' % (m.group(2), d) 416516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru else: 426516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru d = m.group(2) 436516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru #import ipdb; ipdb.set_trace() 446516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru sibling = self.lastChild(parent) 456516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if not terms and sibling.tag == 'p': 466516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # The previous paragraph contains the terms 476516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru state = 'looselist' 486516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru terms = sibling.text.split('\n') 496516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru parent.remove(sibling) 506516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # Aquire new sibling 516516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru sibling = self.lastChild(parent) 526516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru else: 536516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru state = 'list' 546516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 556516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if sibling and sibling.tag == 'dl': 566516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # This is another item on an existing list 576516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru dl = sibling 586516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if len(dl) and dl[-1].tag == 'dd' and len(dl[-1]): 596516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru state = 'looselist' 606516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru else: 616516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # This is a new list 626516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru dl = etree.SubElement(parent, 'dl') 636516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # Add terms 646516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru for term in terms: 656516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru dt = etree.SubElement(dl, 'dt') 666516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru dt.text = term 676516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru # Add definition 686516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru self.parser.state.set(state) 696516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru dd = etree.SubElement(dl, 'dd') 706516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru self.parser.parseBlocks(dd, [d]) 716516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru self.parser.state.reset() 726516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 736516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru if theRest: 746516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru blocks.insert(0, theRest) 756516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 766516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queruclass DefListIndentProcessor(markdown.blockprocessors.ListIndentProcessor): 776516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru """ Process indented children of definition list items. """ 786516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 796516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru ITEM_TYPES = ['dd'] 806516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru LIST_TYPES = ['dl'] 816516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 826516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru def create_item(parent, block): 836516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru """ Create a new dd and parse the block with it as the parent. """ 846516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru dd = markdown.etree.SubElement(parent, 'dd') 856516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru self.parser.parseBlocks(dd, [block]) 866516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 876516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 886516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 896516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queruclass DefListExtension(markdown.Extension): 906516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru """ Add definition lists to Markdown. """ 916516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 926516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru def extendMarkdown(self, md, md_globals): 936516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru """ Add an instance of DefListProcessor to BlockParser. """ 946516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru md.parser.blockprocessors.add('defindent', 956516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru DefListIndentProcessor(md.parser), 966516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru '>indent') 976516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru md.parser.blockprocessors.add('deflist', 986516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru DefListProcessor(md.parser), 996516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru '>ulist') 1006516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 1016516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 1026516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Querudef makeExtension(configs={}): 1036516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru return DefListExtension(configs=configs) 1046516b99bb74dfb7187a08f7090bf7ca22a006f15Jean-Baptiste Queru 105