<s> """<STR_LIT>""" <EOL> from __future__ import absolute_import <EOL> from __future__ import unicode_literals <EOL> from . import Extension <EOL> from . . treeprocessors import Treeprocessor <EOL> from . . util import etree , parseBoolValue , AMP_SUBSTITUTE <EOL> from . headerid import slugify , unique , itertext , stashedHTML2text <EOL> import re <EOL> def order_toc_list ( toc_list ) : <EOL> """<STR_LIT>""" <EOL> def build_correct ( remaining_list , prev_elements = [ { '<STR_LIT>' : <NUM_LIT:1000> } ] ) : <EOL> if not remaining_list : <EOL> return [ ] , [ ] <EOL> current = remaining_list . pop ( <NUM_LIT:0> ) <EOL> if not '<STR_LIT>' in current . keys ( ) : <EOL> current [ '<STR_LIT>' ] = [ ] <EOL> if not prev_elements : <EOL> next_elements , children = build_correct ( remaining_list , [ current ] ) <EOL> current [ '<STR_LIT>' ] . append ( children ) <EOL> return [ current ] + next_elements , [ ] <EOL> prev_element = prev_elements . pop ( ) <EOL> children = [ ] <EOL> next_elements = [ ] <EOL> if current [ '<STR_LIT>' ] > prev_element [ '<STR_LIT>' ] : <EOL> prev_elements . append ( prev_element ) <EOL> prev_elements . append ( current ) <EOL> prev_element [ '<STR_LIT>' ] . append ( current ) <EOL> next_elements2 , children2 = build_correct ( remaining_list , prev_elements ) <EOL> children += children2 <EOL> next_elements += next_elements2 <EOL> else : <EOL> if not prev_elements : <EOL> next_elements . append ( current ) <EOL> prev_elements = [ current ] <EOL> next_elements2 , children2 = build_correct ( remaining_list , prev_elements ) <EOL> current [ '<STR_LIT>' ] . extend ( children2 ) <EOL> else : <EOL> remaining_list . insert ( <NUM_LIT:0> , current ) <EOL> next_elements2 , children2 = build_correct ( remaining_list , prev_elements ) <EOL> children . extend ( children2 ) <EOL> next_elements += next_elements2 <EOL> return next_elements , children <EOL> ordered_list , __ = build_correct ( toc_list ) <EOL> return ordered_list <EOL> class TocTreeprocessor ( Treeprocessor ) : <EOL> def iterparent ( self , root ) : <EOL> for parent in root . getiterator ( ) : <EOL> for child in parent : <EOL> yield parent , child <EOL> def add_anchor ( self , c , elem_id ) : <EOL> anchor = etree . Element ( "<STR_LIT:a>" ) <EOL> anchor . text = c . text <EOL> anchor . attrib [ "<STR_LIT>" ] = "<STR_LIT:#>" + elem_id <EOL> anchor . attrib [ "<STR_LIT:class>" ] = "<STR_LIT>" <EOL> c . text = "<STR_LIT>" <EOL> for elem in c . getchildren ( ) : <EOL> anchor . append ( elem ) <EOL> c . remove ( elem ) <EOL> c . append ( anchor ) <EOL> def add_permalink ( self , c , elem_id ) : <EOL> permalink = etree . Element ( "<STR_LIT:a>" ) <EOL> permalink . text = ( "<STR_LIT>" % AMP_SUBSTITUTE <EOL> if self . use_permalinks is True else self . use_permalinks ) <EOL> permalink . attrib [ "<STR_LIT>" ] = "<STR_LIT:#>" + elem_id <EOL> permalink . attrib [ "<STR_LIT:class>" ] = "<STR_LIT>" <EOL> permalink . attrib [ "<STR_LIT:title>" ] = "<STR_LIT>" <EOL> c . append ( permalink ) <EOL> def build_toc_etree ( self , div , toc_list ) : <EOL> if self . config [ "<STR_LIT:title>" ] : <EOL> header = etree . SubElement ( div , "<STR_LIT>" ) <EOL> header . attrib [ "<STR_LIT:class>" ] = "<STR_LIT>" <EOL> header . text = self . config [ "<STR_LIT:title>" ] <EOL> def build_etree_ul ( toc_list , parent ) : <EOL> ul = etree . SubElement ( parent , "<STR_LIT>" ) <EOL> for item in toc_list : <EOL> li = etree . SubElement ( ul , "<STR_LIT>" ) <EOL> link = etree . SubElement ( li , "<STR_LIT:a>" ) <EOL> link . text = item . get ( '<STR_LIT:name>' , '<STR_LIT>' ) <EOL> link . attrib [ "<STR_LIT>" ] = '<STR_LIT:#>' + item . get ( '<STR_LIT:id>' , '<STR_LIT>' ) <EOL> if item [ '<STR_LIT>' ] : <EOL> build_etree_ul ( item [ '<STR_LIT>' ] , li ) <EOL> return ul <EOL> return build_etree_ul ( toc_list , div ) <EOL> def run ( self , doc ) : <EOL> div = etree . Element ( "<STR_LIT>" ) <EOL> div . attrib [ "<STR_LIT:class>" ] = "<STR_LIT>" <EOL> header_rgx = re . compile ( "<STR_LIT>" ) <EOL> self . use_anchors = parseBoolValue ( self . config [ "<STR_LIT>" ] ) <EOL> self . use_permalinks = parseBoolValue ( self . config [ "<STR_LIT>" ] , False ) <EOL> if self . use_permalinks is None : <EOL> self . use_permalinks = self . config [ "<STR_LIT>" ] <EOL> used_ids = set ( ) <EOL> for c in doc . getiterator ( ) : <EOL> if "<STR_LIT:id>" in c . attrib : <EOL> used_ids . add ( c . attrib [ "<STR_LIT:id>" ] ) <EOL> toc_list = [ ] <EOL> marker_found = False <EOL> for ( p , c ) in self . iterparent ( doc ) : <EOL> text = '<STR_LIT>' . join ( itertext ( c ) ) . strip ( ) <EOL> if not text : <EOL> continue <EOL> if c . text and c . text . strip ( ) == self . config [ "<STR_LIT>" ] and not header_rgx . match ( c . tag ) and c . tag not in [ '<STR_LIT>' , '<STR_LIT:code>' ] : <EOL> for i in range ( len ( p ) ) : <EOL> if p [ i ] == c : <EOL> p [ i ] = div <EOL> break <EOL> marker_found = True <EOL> if header_rgx . match ( c . tag ) : <EOL> if not "<STR_LIT:id>" in c . attrib : <EOL> elem_id = stashedHTML2text ( text , self . markdown ) <EOL> elem_id = unique ( self . config [ "<STR_LIT>" ] ( elem_id , '<STR_LIT:->' ) , used_ids ) <EOL> c . attrib [ "<STR_LIT:id>" ] = elem_id <EOL> else : <EOL> elem_id = c . attrib [ "<STR_LIT:id>" ] <EOL> tag_level = int ( c . tag [ - <NUM_LIT:1> ] ) <EOL> toc_list . append ( { '<STR_LIT>' : tag_level , <EOL> '<STR_LIT:id>' : elem_id , <EOL> '<STR_LIT:name>' : text } ) <EOL> if self . use_anchors : <EOL> self . add_anchor ( c , elem_id ) <EOL> if self . use_permalinks : <EOL> self . add_permalink ( c , elem_id ) <EOL> toc_list_nested = order_toc_list ( toc_list ) <EOL> self . build_toc_etree ( div , toc_list_nested ) <EOL> prettify = self . markdown . treeprocessors . get ( '<STR_LIT>' ) <EOL> if prettify : prettify . run ( div ) <EOL> if not marker_found : <EOL> toc = self . markdown . serializer ( div ) <EOL> for pp in self . markdown . postprocessors . values ( ) : <EOL> toc = pp . run ( toc ) <EOL> self . markdown . toc = toc <EOL> class TocExtension ( Extension ) : <EOL> TreeProcessorClass = TocTreeprocessor <EOL> def __init__ ( self , configs = [ ] ) : <EOL> self . config = { "<STR_LIT>" : [ "<STR_LIT>" , <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ] , <EOL> "<STR_LIT>" : [ slugify , <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ] , <EOL> "<STR_LIT:title>" : [ None , <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ] , <EOL> "<STR_LIT>" : [ <NUM_LIT:0> , <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ] , <EOL> "<STR_LIT>" : [ <NUM_LIT:0> , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" ] <EOL> } <EOL> for key , value in configs : <EOL> self . setConfig ( key , value ) <EOL> def extendMarkdown ( self , md , md_globals ) : <EOL> tocext = self . TreeProcessorClass ( md ) <EOL> tocext . config = self . getConfigs ( ) <EOL> md . treeprocessors . add ( "<STR_LIT>" , tocext , "<STR_LIT>" ) <EOL> def makeExtension ( configs = { } ) : <EOL> return TocExtension ( configs = configs ) </s>
