<s> """<STR_LIT>""" <EOL> import __init__ as markdown <EOL> from __init__ import etree <EOL> import re <EOL> from string import ascii_lowercase , digits , punctuation <EOL> ID_CHARS = ascii_lowercase + digits + '<STR_LIT>' <EOL> IDCOUNT_RE = re . compile ( r'<STR_LIT>' ) <EOL> class HeaderIdProcessor ( markdown . blockprocessors . BlockProcessor ) : <EOL> """<STR_LIT>""" <EOL> RE = re . compile ( r"""<STR_LIT>""" , <EOL> re . VERBOSE ) <EOL> IDs = [ ] <EOL> def test ( self , parent , block ) : <EOL> return bool ( self . RE . search ( block ) ) <EOL> def run ( self , parent , blocks ) : <EOL> block = blocks . pop ( <NUM_LIT:0> ) <EOL> m = self . RE . search ( block ) <EOL> if m : <EOL> before = block [ : m . start ( ) ] <EOL> after = block [ m . end ( ) : ] <EOL> if before : <EOL> self . parser . parseBlocks ( parent , [ before ] ) <EOL> start_level , force_id = self . _get_meta ( ) <EOL> level = len ( m . group ( '<STR_LIT>' ) ) + start_level <EOL> if level > <NUM_LIT:6> : <EOL> level = <NUM_LIT:6> <EOL> h = markdown . etree . SubElement ( parent , '<STR_LIT>' % level ) <EOL> h . text = m . group ( '<STR_LIT>' ) . strip ( ) <EOL> if m . group ( '<STR_LIT:id>' ) : <EOL> h . set ( '<STR_LIT:id>' , self . _unique_id ( m . group ( '<STR_LIT:id>' ) ) ) <EOL> elif force_id : <EOL> h . set ( '<STR_LIT:id>' , self . _create_id ( m . group ( '<STR_LIT>' ) . strip ( ) ) ) <EOL> if after : <EOL> blocks . insert ( <NUM_LIT:0> , after ) <EOL> else : <EOL> message ( CRITICAL , "<STR_LIT>" ) <EOL> def _get_meta ( self ) : <EOL> """<STR_LIT>""" <EOL> level = int ( self . config [ '<STR_LIT>' ] [ <NUM_LIT:0> ] ) - <NUM_LIT:1> <EOL> force = self . _str2bool ( self . config [ '<STR_LIT>' ] [ <NUM_LIT:0> ] ) <EOL> if hasattr ( self . md , '<STR_LIT:Meta>' ) : <EOL> if self . md . Meta . has_key ( '<STR_LIT>' ) : <EOL> level = int ( self . md . Meta [ '<STR_LIT>' ] [ <NUM_LIT:0> ] ) - <NUM_LIT:1> <EOL> if self . md . Meta . has_key ( '<STR_LIT>' ) : <EOL> force = self . _str2bool ( self . md . Meta [ '<STR_LIT>' ] [ <NUM_LIT:0> ] ) <EOL> return level , force <EOL> def _str2bool ( self , s , default = False ) : <EOL> """<STR_LIT>""" <EOL> s = str ( s ) <EOL> if s . lower ( ) in [ '<STR_LIT:0>' , '<STR_LIT:f>' , '<STR_LIT:false>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:n>' ] : <EOL> return False <EOL> elif s . lower ( ) in [ '<STR_LIT:1>' , '<STR_LIT:t>' , '<STR_LIT:true>' , '<STR_LIT>' , '<STR_LIT:yes>' , '<STR_LIT:y>' ] : <EOL> return True <EOL> return default <EOL> def _unique_id ( self , id ) : <EOL> """<STR_LIT>""" <EOL> while id in self . IDs : <EOL> m = IDCOUNT_RE . match ( id ) <EOL> if m : <EOL> id = '<STR_LIT>' % ( m . group ( <NUM_LIT:1> ) , int ( m . group ( <NUM_LIT:2> ) ) + <NUM_LIT:1> ) <EOL> else : <EOL> id = '<STR_LIT>' % ( id , <NUM_LIT:1> ) <EOL> self . IDs . append ( id ) <EOL> return id <EOL> def _create_id ( self , header ) : <EOL> """<STR_LIT>""" <EOL> h = '<STR_LIT>' <EOL> for c in header . lower ( ) . replace ( '<STR_LIT:U+0020>' , '<STR_LIT:_>' ) : <EOL> if c in ID_CHARS : <EOL> h += c <EOL> elif c not in punctuation : <EOL> h += '<STR_LIT:+>' <EOL> return self . _unique_id ( h ) <EOL> class HeaderIdExtension ( markdown . Extension ) : <EOL> def __init__ ( self , configs ) : <EOL> self . config = { <EOL> '<STR_LIT>' : [ '<STR_LIT:1>' , '<STR_LIT>' ] , <EOL> '<STR_LIT>' : [ '<STR_LIT:True>' , '<STR_LIT>' ] <EOL> } <EOL> for key , value in configs : <EOL> self . setConfig ( key , value ) <EOL> def extendMarkdown ( self , md , md_globals ) : <EOL> md . registerExtension ( self ) <EOL> self . processor = HeaderIdProcessor ( md . parser ) <EOL> self . processor . md = md <EOL> self . processor . config = self . config <EOL> md . parser . blockprocessors [ '<STR_LIT>' ] = self . processor <EOL> def reset ( self ) : <EOL> self . processor . IDs = [ ] <EOL> def makeExtension ( configs = None ) : <EOL> return HeaderIdExtension ( configs = configs ) <EOL> if __name__ == "<STR_LIT:__main__>" : <EOL> import doctest <EOL> doctest . testmod ( ) </s>
