signature:
def adjacency ( graph , directed = False , reversed = False , stochastic = False , heuristic = None ) :
    """An edge weight map indexed by node id ' s .
 A dictionary indexed by node id1 ' s in which each value is a
 dictionary of connected node id2 ' s linking to the edge weight .
 If directed , edges go from id1 to id2 , but not the other way .
 If stochastic , all the weights for the neighbors of a given node sum to 1.
 A heuristic can be a function that takes two node id ' s and returns
 and additional cost for movement between the two nodes ."""

implementation:
v = { }
for n in graph . nodes :
    v [ n . id ] = { }
for e in graph . edges :
    id1 = e . node1 . id
    id2 = e . node2 . id
    if reversed :
        id1 , id2 = id2 , id1
    # if not v . has _ key ( id1 ) : v [ id1 ] = { }
    # if not v . has _ key ( id2 ) : v [ id2 ] = { }
    v [ id1 ] [ id2 ] = 1.0 - e . weight * 0.5
    if heuristic :
        v [ id1 ] [ id2 ] += heuristic ( id1 , id2 )
    if not directed :
        v [ id2 ] [ id1 ] = v [ id1 ] [ id2 ]
if stochastic :
    for id1 in v :
        d = sum ( v [ id1 ] . values ( ) )
        for id2 in v [ id1 ] :
            v [ id1 ] [ id2 ] /= d
return v


signature:
def brandes_betweenness_centrality ( graph , normalized = True ) :
    """Betweenness centrality for nodes in the graph .
 Betweenness centrality is a measure of the number of shortests paths that pass through a node .
 Nodes in high - density areas will get a good score .
 The algorithm is Brandes ' betweenness centrality ,
 from NetworkX 0.35.1 : Aric Hagberg , Dan Schult and Pieter Swart ,
 based on Dijkstra ' s algorithm for shortest paths modified from Eppstein .
 https : / / networkx . lanl . gov / wiki"""

implementation:
G = graph . keys ( )
W = adjacency ( graph )
betweenness = dict . fromkeys ( G , 0.0 )
# b [ v ] = 0 for v in G
for s in G :
    S = [ ]
    P = { }
    for v in G :
        P [ v ] = [ ]
    sigma = dict . fromkeys ( G , 0 )
    # sigma [ v ] = 0 for v in G
    D = { }
    sigma [ s ] = 1
    seen = { s : 0 }
    Q = [ ]
    # use Q as heap with ( distance , node id ) tuples
    heapq . heappush ( Q , ( 0 , s , s ) )
    while Q :
        ( dist , pred , v ) = heapq . heappop ( Q )
        if v in D :
            continue
            # already searched this node
        sigma [ v ] = sigma [ v ] + sigma [ pred ]
        # count paths
        S . append ( v )
        D [ v ] = seen [ v ]
        for w in graph [ v ] . links :
            w = w . id
            vw_dist = D [ v ] + W [ v ] [ w ]
            if w not in D and ( w not in seen or vw_dist < seen [ w ] ) :
                seen [ w ] = vw_dist
                heapq . heappush ( Q , ( vw_dist , v , w ) )
                P [ w ] = [ v ]
            elif vw_dist == seen [ w ] : # handle equal paths
                sigma [ w ] = sigma [ w ] + sigma [ v ]
                P [ w ] . append ( v )
    delta = dict . fromkeys ( G , 0 )
    while S :
        w = S . pop ( )
        for v in P [ w ] :
            delta [ v ] = delta [ v ] + ( float ( sigma [ v ] ) / float ( sigma [ w ] ) ) * ( 1.0 + delta [ w ] )
        if w != s :
            betweenness [ w ] = betweenness [ w ] + delta [ w ]
    if normalized : # Normalize between 0.0 and 1.0.
        m = max ( betweenness . values ( ) )
        if m == 0 :
            m = 1
    else :
        m = 1
    betweenness = dict ( [ ( id , w / m ) for id , w in betweenness . iteritems ( ) ] )
    return betweenness


signature:
def eigenvector_centrality ( graph , normalized = True , reversed = True , rating = { } , start = None , iterations = 100 , tolerance = 0.0001 ) :
    """Eigenvector centrality for nodes in the graph ( like Google ' s PageRank ) .
 Eigenvector centrality is a measure of the importance of a node in a directed network .
 It rewards nodes with a high potential of ( indirectly ) connecting to high - scoring nodes .
 Nodes with no incoming connections have a score of zero .
 If you want to measure outgoing connections , reversed should be False .
 The eigenvector calculation is done by the power iteration method .
 It has no guarantee of convergence .
 A starting vector for the power iteration can be given in the start dict .
 You can adjust the importance of a node with the rating dictionary ,
 which links node id ' s to a score .
 The algorithm is adapted from NetworkX , Aric Hagberg ( hagberg @ lanl . gov ) :
 https : / / networkx . lanl . gov / attachment / ticket / 119 / eigenvector _ centrality . py"""

implementation:
G = graph . keys ( )
W = adjacency ( graph , directed = True , reversed = reversed )
def _normalize ( x ) :
    s = sum ( x . values ( ) )
    if s != 0 :
        s = 1.0 / s
    for k in x :
        x [ k ] *= s
x = start
if x is None :
    x = dict ( [ ( n , random ( ) ) for n in G ] )
_normalize ( x )
# Power method : y = Ax multiplication .
for i in range ( iterations ) :
    x0 = x
    x = dict . fromkeys ( x0 . keys ( ) , 0 )
    for n in x :
        for nbr in W [ n ] :
            r = 1
            if rating . has_key ( n ) :
                r = rating [ n ]
            x [ n ] += 0.01 + x0 [ nbr ] * W [ n ] [ nbr ] * r
    _normalize ( x )
    e = sum ( [ abs ( x [ n ] - x0 [ n ] ) for n in x ] )
    if e < len ( graph . nodes ) * tolerance :
        if normalized : # Normalize between 0.0 and 1.0.
            m = max ( x . values ( ) )
            if m == 0 :
                m = 1
            x = dict ( [ ( id , w / m ) for id , w in x . iteritems ( ) ] )
        return x
# raise NoConvergenceError
warn ( "node weight is 0 because eigenvector_centrality() did not converge." , Warning )
return dict ( [ ( n , 0 ) for n in G ] )


signature:
def examples_menu ( root_dir = None , depth = 0 ) :
    """: return : xml for menu , [ ( bot _ action , label ) , . . . ] , [ ( menu _ action , label ) , . . . ]"""

implementation:
# pre 3.12 menus
examples_dir = ide_utils . get_example_dir ( )
if not examples_dir :
    return "" , [ ] , [ ]
root_dir = root_dir or examples_dir
file_tmpl = '<menuitem name="{name}" action="{action}"/>'
dir_tmpl = '<menu name="{name}" action="{action}">{menu}</menu>'
file_actions = [ ]
submenu_actions = [ ]
xml = ""
for fn in sorted ( os . listdir ( root_dir ) ) :
    path = os . path . join ( root_dir , fn )
    rel_path = path [ len ( examples_dir ) : ]
    if os . path . isdir ( path ) :
        action = 'ShoebotExampleMenu {0}' . format ( rel_path )
        label = fn . capitalize ( )
        sm_xml , sm_file_actions , sm_menu_actions = examples_menu ( os . path . join ( root_dir , fn ) , depth + 1 )
        submenu_actions . extend ( sm_menu_actions )
        file_actions . extend ( sm_file_actions )
        submenu_actions . append ( ( action , label ) )
        xml += dir_tmpl . format ( name = fn , action = action , menu = sm_xml )
    elif os . path . splitext ( path ) [ 1 ] in [ '.bot' , '.py' ] and not fn . startswith ( '_' ) :
        action = 'ShoebotExampleOpen {0}' . format ( rel_path )
        label = ide_utils . make_readable_filename ( fn )
        xml += file_tmpl . format ( name = fn , action = action )
        file_actions . append ( ( action , label ) )
return xml , file_actions , submenu_actions


signature:
def mk_examples_menu ( text , root_dir = None , depth = 0 ) :
    """: return : base _ item , rel _ paths"""

implementation:
# 3.12 + menus
examples_dir = ide_utils . get_example_dir ( )
if not examples_dir :
    return None , [ ]
root_dir = root_dir or examples_dir
file_actions = [ ]
menu = Gio . Menu . new ( )
base_item = Gio . MenuItem . new_submenu ( text , menu )
for fn in sorted ( os . listdir ( root_dir ) ) :
    path = os . path . join ( root_dir , fn )
    rel_path = path [ len ( examples_dir ) : ]
    if os . path . isdir ( path ) :
        label = fn . capitalize ( )
        item , sm_file_actions = mk_examples_menu ( label , os . path . join ( root_dir , fn ) )
        menu . append_item ( item )
        file_actions . extend ( sm_file_actions )
    elif os . path . splitext ( path ) [ 1 ] in [ '.bot' , '.py' ] and not fn . startswith ( '_' ) :
        label = ide_utils . make_readable_filename ( fn )
        # the only way I could work out to attach the data to the menu item is in the name : /
        action_name = "win.open_example__%s" % encode_relpath ( rel_path )
        menu . append ( label , action_name )
        file_actions . append ( rel_path )
return base_item , file_actions


signature:
def get_child_by_name ( parent , name ) :
    """Iterate through a gtk container , ` parent ` ,
 and return the widget with the name ` name ` ."""

implementation:
# http : / / stackoverflow . com / questions / 2072976 / access - to - widget - in - gtk
def iterate_children ( widget , name ) :
    if widget . get_name ( ) == name :
        return widget
    try :
        for w in widget . get_children ( ) :
            result = iterate_children ( w , name )
            if result is not None :
                return result
            else :
                continue
    except AttributeError :
        pass
return iterate_children ( parent , name )


signature:
def venv_has_script ( script ) :
    """: param script : script to look for in bin folder"""

implementation:
def f ( venv ) :
    path = os . path . join ( venv , 'bin' , script )
    if os . path . isfile ( path ) :
        return True
return f


signature:
def is_venv ( directory , executable = 'python' ) :
    """: param directory : base directory of python environment"""

implementation:
path = os . path . join ( directory , 'bin' , executable )
return os . path . isfile ( path )


signature:
def vw_envs ( filter = None ) :
    """: return : python environments in ~ / . virtualenvs
 : param filter : if this returns False the venv will be ignored
 > > > vw _ envs ( filter = venv _ has _ script ( ' pip ' ) )"""

implementation:
vw_root = os . path . abspath ( os . path . expanduser ( os . path . expandvars ( '~/.virtualenvs' ) ) )
venvs = [ ]
for directory in os . listdir ( vw_root ) :
    venv = os . path . join ( vw_root , directory )
    if os . path . isdir ( os . path . join ( venv ) ) :
        if filter and not filter ( venv ) :
            continue
        venvs . append ( venv )
return sorted ( venvs )


signature:
def sbot_executable ( ) :
    """Find shoebot executable"""

implementation:
gsettings = load_gsettings ( )
venv = gsettings . get_string ( 'current-virtualenv' )
if venv == 'Default' :
    sbot = which ( 'sbot' )
elif venv == 'System' : # find system python
    env_venv = os . environ . get ( 'VIRTUAL_ENV' )
    if not env_venv :
        return which ( 'sbot' )
    # First sbot in path that is not in current venv
    for p in os . environ [ 'PATH' ] . split ( os . path . pathsep ) :
        sbot = '%s/sbot' % p
        if not p . startswith ( env_venv ) and os . path . isfile ( sbot ) :
            return sbot
else :
    sbot = os . path . join ( venv , 'bin/sbot' )
    if not os . path . isfile ( sbot ) :
        print ( 'Shoebot not found, reverting to System shoebot' )
        sbot = which ( 'sbot' )
return os . path . realpath ( sbot )


signature:
def _description ( self ) :
    """Returns the meta description in the page ."""

implementation:
meta = self . find ( "meta" , { "name" : "description" } )
if isinstance ( meta , dict ) and meta . has_key ( "content" ) :
    return meta [ "content" ]
else :
    return u""


signature:
def _keywords ( self ) :
    """Returns the meta keywords in the page ."""

implementation:
meta = self . find ( "meta" , { "name" : "keywords" } )
if isinstance ( meta , dict ) and meta . has_key ( "content" ) :
    keywords = [ k . strip ( ) for k in meta [ "content" ] . split ( "," ) ]
else :
    keywords = [ ]
return keywords


signature:
def links ( self , external = True ) :
    """Retrieves links in the page .
 Returns a list of URL ' s .
 By default , only external URL ' s are returned .
 External URL ' s starts with http : / / and point to another
 domain than the domain the page is on ."""

implementation:
domain = URLParser ( self . url ) . domain
links = [ ]
for a in self ( "a" ) :
    for attribute , value in a . attrs :
        if attribute == "href" :
            if not external or ( value . startswith ( "http://" ) and value . find ( "http://" + domain ) < 0 ) :
                links . append ( value )
return links


signature:
def sorted ( list , cmp = None , reversed = False ) :
    """Returns a sorted copy of the list ."""

implementation:
list = [ x for x in list ]
list . sort ( cmp )
if reversed :
    list . reverse ( )
return list


signature:
def unique ( list ) :
    """Returns a copy of the list without duplicates ."""

implementation:
unique = [ ] ;
[ unique . append ( x ) for x in list if x not in unique ]
return unique


signature:
def flatten ( node , distance = 1 ) :
    """Recursively lists the node and its links .
 Distance of 0 will return the given [ node ] .
 Distance of 1 will return a list of the node and all its links .
 Distance of 2 will also include the linked nodes ' links , etc ."""

implementation:
# When you pass a graph it returns all the node id ' s in it .
if hasattr ( node , "nodes" ) and hasattr ( node , "edges" ) :
    return [ n . id for n in node . nodes ]
all = [ node ]
if distance >= 1 :
    for n in node . links :
        all += n . flatten ( distance - 1 )
return unique ( all )


signature:
def subgraph ( graph , id , distance = 1 ) :
    """Creates the subgraph of the flattened node with given id ( or list of id ' s ) .
 Finds all the edges between the nodes that make up the subgraph ."""

implementation:
g = graph . copy ( empty = True )
if isinstance ( id , ( FunctionType , LambdaType ) ) : # id can also be a lambda or function that returns True or False
# for each node in the graph . We take the id ' s of nodes that pass .
    id = [ node . id for node in filter ( id , graph . nodes ) ]
if not isinstance ( id , ( list , tuple ) ) :
    id = [ id ]
for id in id :
    for n in flatten ( graph [ id ] , distance ) :
        g . add_node ( n . id , n . r , n . style , n . category , n . label , ( n == graph . root ) , n . __dict__ )
for e in graph . edges :
    if g . has_key ( e . node1 . id ) and g . has_key ( e . node2 . id ) :
        g . add_edge ( e . node1 . id , e . node2 . id , e . weight , e . length , e . label , e . __dict__ )
# Should we look for shortest paths between nodes here ?
return g


signature:
def clique ( graph , id ) :
    """Returns the largest possible clique for the node with given id ."""

implementation:
clique = [ id ]
for n in graph . nodes :
    friend = True
    for id in clique :
        if n . id == id or graph . edge ( n . id , id ) == None :
            friend = False
            break
    if friend :
        clique . append ( n . id )
return clique


signature:
def cliques ( graph , threshold = 3 ) :
    """Returns all the cliques in the graph of at least the given size ."""

implementation:
cliques = [ ]
for n in graph . nodes :
    c = clique ( graph , n . id )
    if len ( c ) >= threshold :
        c . sort ( )
        if c not in cliques :
            cliques . append ( c )
return cliques


signature:
def partition ( graph ) :
    """Splits unconnected subgraphs .
 For each node in the graph , make a list of its id and all directly connected id ' s .
 If one of the nodes in this list intersects with a subgraph ,
 they are all part of that subgraph .
 Otherwise , this list is part of a new subgraph .
 Return a list of subgraphs sorted by size ( biggest - first ) ."""

implementation:
g = [ ]
for n in graph . nodes :
    c = [ n . id for n in flatten ( n ) ]
    f = False
    for i in range ( len ( g ) ) :
        if len ( intersection ( g [ i ] , c ) ) > 0 :
            g [ i ] = union ( g [ i ] , c )
            f = True
            break
    if not f :
        g . append ( c )
# If 1 is directly connected to 2 and 3,
# and 4 is directly connected to 5 and 6 , these are separate subgraphs .
# If we later find that 7 is directly connected to 3 and 6,
# it will be attached to [ 1 , 2 , 3 ] yielding
# [1 , 2 , 3 , 6 , 7 ] and [ 4 , 5 , 6 ] .
# These two subgraphs are connected and need to be merged .
merged = [ ]
for i in range ( len ( g ) ) :
    merged . append ( g [ i ] )
    for j in range ( i + 1 , len ( g ) ) :
        if len ( intersection ( g [ i ] , g [ j ] ) ) > 0 :
            merged [ - 1 ] . extend ( g [ j ] )
            g [ j ] = [ ]
g = merged
g = [ graph . sub ( g , distance = 0 ) for g in g ]
g . sort ( lambda a , b : len ( b ) - len ( a ) )
return g


signature:
def render ( self , size , frame , drawqueue ) :
    '''Calls implmentation to get a render context ,
 passes it to the drawqueues render function
 then calls self . rendering _ finished'''

implementation:
r_context = self . create_rcontext ( size , frame )
drawqueue . render ( r_context )
self . rendering_finished ( size , frame , r_context )
return r_context


signature:
def batch ( vars , oldvars , ns ) :
    """Context manager to only update listeners
 at the end , in the meantime it doesn ' t
 matter what intermediate state the vars
 are in ( they can be added and removed )
 > > > with VarListener . batch ( )
 . . . pass"""

implementation:
snapshot_vars = dict ( vars )
with VarListener . disabled ( ) :
    yield
added_vars = set ( oldvars . keys ( ) ) - set ( snapshot_vars . keys ( ) )
deleted_vars = set ( snapshot_vars . keys ( ) ) - set ( oldvars . keys ( ) )
existing_vars = set ( vars . keys ( ) ) - added_vars - deleted_vars
for name in existing_vars :
    old_var = snapshot_vars [ name ]
    new_var = vars [ name ]
    if old_var . type != new_var . type or old_var . min != new_var . min or old_var . max != new_var . max :
        deleted_vars . add ( name )
        added_vars . add ( name )
        if old_var . type == new_var . type :
            new_var . value = old_var . value
for listener in VarListener . listeners :
    for name in deleted_vars :
        listener . var_deleted ( snapshot_vars [ name ] )
        if ns . get ( name ) is snapshot_vars [ name ] . value :
            del ns [ name ]
    for name in added_vars :
        listener . var_added ( vars [ name ] )


signature:
def hexDump ( bytes ) :
    """Useful utility ; prints the string in hexadecimal"""

implementation:
for i in range ( len ( bytes ) ) :
    sys . stdout . write ( "%2x " % ( ord ( bytes [ i ] ) ) )
    if ( i + 1 ) % 8 == 0 :
        print repr ( bytes [ i - 7 : i + 1 ] )
if ( len ( bytes ) % 8 != 0 ) :
    print string . rjust ( "" , 11 ) , repr ( bytes [ i - len ( bytes ) % 8 : i + 1 ] )


signature:
def readLong ( data ) :
    """Tries to interpret the next 8 bytes of the data
 as a 64 - bit signed integer ."""

implementation:
high , low = struct . unpack ( ">ll" , data [ 0 : 8 ] )
big = ( long ( high ) << 32 ) + low
rest = data [ 8 : ]
return ( big , rest )


signature:
def OSCBlob ( next ) :
    """Convert a string into an OSC Blob ,
 returning a ( typetag , data ) tuple ."""

implementation:
if type ( next ) == type ( "" ) :
    length = len ( next )
    padded = math . ceil ( ( len ( next ) ) / 4.0 ) * 4
    binary = struct . pack ( ">i%ds" % ( padded ) , length , next )
    tag = 'b'
else :
    tag = ''
    binary = ''
return ( tag , binary )


signature:
def OSCArgument ( next ) :
    """Convert some Python types to their
 OSC binary representations , returning a
 ( typetag , data ) tuple ."""

implementation:
if type ( next ) == type ( "" ) :
    OSCstringLength = math . ceil ( ( len ( next ) + 1 ) / 4.0 ) * 4
    binary = struct . pack ( ">%ds" % ( OSCstringLength ) , next )
    tag = "s"
elif type ( next ) == type ( 42.5 ) :
    binary = struct . pack ( ">f" , next )
    tag = "f"
elif type ( next ) == type ( 13 ) :
    binary = struct . pack ( ">i" , next )
    tag = "i"
else :
    binary = ""
    tag = ""
return ( tag , binary )


signature:
def parseArgs ( args ) :
    """Given a list of strings , produces a list
 where those strings have been parsed ( where
 possible ) as floats or integers ."""

implementation:
parsed = [ ]
for arg in args :
    print arg
    arg = arg . strip ( )
    interpretation = None
    try :
        interpretation = float ( arg )
        if string . find ( arg , "." ) == - 1 :
            interpretation = int ( interpretation )
    except : # Oh - it was a string .
        interpretation = arg
        pass
    parsed . append ( interpretation )
return parsed


signature:
def decodeOSC ( data ) :
    """Converts a typetagged OSC message to a Python list ."""

implementation:
table = { "i" : readInt , "f" : readFloat , "s" : readString , "b" : readBlob }
decoded = [ ]
address , rest = readString ( data )
typetags = ""
if address == "#bundle" :
    time , rest = readLong ( rest )
    # decoded . append ( address )
    # decoded . append ( time )
    while len ( rest ) > 0 :
        length , rest = readInt ( rest )
        decoded . append ( decodeOSC ( rest [ : length ] ) )
        rest = rest [ length : ]
elif len ( rest ) > 0 :
    typetags , rest = readString ( rest )
    decoded . append ( address )
    decoded . append ( typetags )
    if typetags [ 0 ] == "," :
        for tag in typetags [ 1 : ] :
            value , rest = table [ tag ] ( rest )
            decoded . append ( value )
    else :
        print "Oops, typetag lacks the magic ,"
return decoded


signature:
def append ( self , argument , typehint = None ) :
    """Appends data to the message ,
 updating the typetags based on
 the argument ' s type .
 If the argument is a blob ( counted string )
 pass in ' b ' as typehint ."""

implementation:
if typehint == 'b' :
    binary = OSCBlob ( argument )
else :
    binary = OSCArgument ( argument )
self . typetags = self . typetags + binary [ 0 ]
self . rawAppend ( binary [ 1 ] )


signature:
def getBinary ( self ) :
    """Returns the binary message ( so far ) with typetags ."""

implementation:
address = OSCArgument ( self . address ) [ 1 ]
typetags = OSCArgument ( self . typetags ) [ 1 ]
return address + typetags + self . message


signature:
def handle ( self , data , source = None ) :
    """Given OSC data , tries to call the callback with the
 right address ."""

implementation:
decoded = decodeOSC ( data )
self . dispatch ( decoded , source )


signature:
def dispatch ( self , message , source = None ) :
    """Sends decoded OSC data to an appropriate calback"""

implementation:
msgtype = ""
try :
    if type ( message [ 0 ] ) == str : # got a single message
        address = message [ 0 ]
        self . callbacks [ address ] ( message )
    elif type ( message [ 0 ] ) == list :
        for msg in message :
            self . dispatch ( msg )
except KeyError , key :
    print 'address %s not found, %s: %s' % ( address , key , message )
    pprint . pprint ( message )
except IndexError , e :
    print '%s: %s' % ( e , message )
    pass
except None , e :
    print "Exception in" , address , "callback :" , e
return


signature:
def add ( self , callback , name ) :
    """Adds a callback to our set of callbacks ,
 or removes the callback with name if callback
 is None ."""

implementation:
if callback == None :
    del self . callbacks [ name ]
else :
    self . callbacks [ name ] = callback


signature:
def find_example_dir ( ) :
    """Find examples dir . . a little bit ugly . ."""

implementation:
# Replace % s with directory to check for shoebot menus .
code_stub = textwrap . dedent ( """
    from pkg_resources import resource_filename, Requirement, DistributionNotFound
    try:
        print(resource_filename(Requirement.parse('shoebot'), '%s'))
    except DistributionNotFound:
        pass

    """ )
# Needs to run in same python env as shoebot ( may be different to gedits )
code = code_stub % 'share/shoebot/examples'
cmd = [ "python" , "-c" , code ]
p = subprocess . Popen ( cmd , stdout = subprocess . PIPE , stderr = subprocess . PIPE )
output , errors = p . communicate ( )
if errors :
    print ( 'Shoebot experienced errors searching for install and examples.' )
    print ( 'Errors:\n{0}' . format ( errors . decode ( 'utf-8' ) ) )
    return None
else :
    examples_dir = output . decode ( 'utf-8' ) . strip ( )
    if os . path . isdir ( examples_dir ) :
        return examples_dir
    # If user is running ' setup . py develop ' then examples could be right here
    # code = " from pkg _ resources import resource _ filename , Requirement ; print resource _ filename ( Requirement . parse ( ' shoebot ' ) , ' examples / ' ) "
    code = code_stub % 'examples/'
    cmd = [ "python" , "-c" , code ]
    p = subprocess . Popen ( cmd , stdout = subprocess . PIPE )
    output , errors = p . communicate ( )
    examples_dir = output . decode ( 'utf-8' ) . strip ( )
    if os . path . isdir ( examples_dir ) :
        return examples_dir
    if examples_dir :
        print ( 'Shoebot could not find examples at: {0}' . format ( examples_dir ) )
    else :
        print ( 'Shoebot could not find install dir and examples.' )


signature:
def run ( self ) :
    """The body of the tread : read lines and put them on the queue ."""

implementation:
try :
    for line in iter ( self . _fd . readline , False ) :
        if line is not None :
            if self . _althandler :
                if self . _althandler ( line ) : # If the althandler returns True
                # then don ' t process this as usual
                    continue
        self . _queue . put ( line )
        if not line :
            time . sleep ( 0.1 )
except ValueError : # This can happen if we are closed during readline - TODO - better fix .
    if not self . _fd . closed :
        raise


signature:
def eof ( self ) :
    """Check whether there is no more content to expect ."""

implementation: return ( not self . is_alive ( ) ) and self . _queue . empty ( ) or self . _fd . closed


signature:
def live_source_load ( self , source ) :
    """Send new source code to the bot
 : param source :
 : param good _ cb : callback called if code was good
 : param bad _ cb : callback called if code was bad ( will get contents of exception )
 : return :"""

implementation:
source = source . rstrip ( '\n' )
if source != self . source :
    self . source = source
    b64_source = base64 . b64encode ( bytes ( bytearray ( source , "ascii" ) ) )
    self . send_command ( CMD_LOAD_BASE64 , b64_source )


signature:
def send_command ( self , cmd , * args ) :
    """: param cmd :
 : param args :
 : return :"""

implementation:
# Test in python 2 and 3 before modifying ( gedit2 + 3)
if True : # Create a CommandResponse using a cookie as a unique id
    cookie = str ( uuid . uuid4 ( ) )
    response = CommandResponse ( cmd , cookie , None , info = [ ] )
    self . responses [ cookie ] = response
    args = list ( args ) + [ b'cookie=' + bytes ( cookie , "ascii" ) ]
if args :
    bytes_args = [ ]
    for arg in args :
        if isinstance ( arg , bytes ) :
            bytes_args . append ( arg )
        else :
            bytes_args . append ( bytearray ( arg , "ascii" ) )
    data = bytearray ( cmd , "ascii" ) + b' ' + b' ' . join ( bytes_args ) + b'\n'
else :
    data = bytearray ( cmd , "ascii" ) + b'\n'
self . process . stdin . write ( data )
self . process . stdin . flush ( )


signature:
def close ( self ) :
    """Close outputs of process ."""

implementation:
self . process . stdout . close ( )
self . process . stderr . close ( )
self . running = False


signature:
def get_output ( self ) :
    """: yield : stdout _ line , stderr _ line , running
 Generator that outputs lines captured from stdout and stderr
 These can be consumed to output on a widget in an IDE"""

implementation:
if self . process . poll ( ) is not None :
    self . close ( )
    yield None , None
while not ( self . stdout_queue . empty ( ) and self . stderr_queue . empty ( ) ) :
    if not self . stdout_queue . empty ( ) :
        line = self . stdout_queue . get ( ) . decode ( 'utf-8' )
        yield line , None
    if not self . stderr_queue . empty ( ) :
        line = self . stderr_queue . get ( ) . decode ( 'utf-8' )
        yield None , line


signature:
def get_command_responses ( self ) :
    """Get responses to commands sent"""

implementation:
if not self . response_queue . empty ( ) :
    yield None
while not self . response_queue . empty ( ) :
    line = self . response_queue . get ( )
    if line is not None :
        yield line


signature:
def sort_by_preference ( options , prefer ) :
    """: param options : List of options
 : param prefer : Prefered options
 : return :
 Pass in a list of options , return options in ' prefer ' first
 > > > sort _ by _ preference ( [ " cairo " , " cairocffi " ] , [ " cairocffi " ] )
 [ " cairocffi " , " cairo " ]"""

implementation:
if not prefer :
    return options
return sorted ( options , key = lambda x : ( prefer + options ) . index ( x ) )


signature:
def get_driver_options ( ) :
    """Interpret env var as key = value
 : return :"""

implementation:
options = os . environ . get ( "SHOEBOT_GRAPHICS" )
if not options :
    return { }
try :
    return dict ( [ kv . split ( '=' ) for kv in options . split ( ) ] )
except ValueError :
    sys . stderr . write ( "Bad option format.\n" )
    sys . stderr . write ( "Environment variable should be in the format key=value separated by spaces.\n\n" )
    sys . stderr . write ( "SHOEBOT_GRAPHICS='cairo=cairocffi,cairo gi=pgi'\n" )
    sys . exit ( 1 )


signature:
def import_libs ( self , module_names , impl_name ) :
    """Loop through module _ names ,
 add has _ . . . . booleans to class
 set . . . _ impl to first successful import
 : param module _ names : list of module names to try importing
 : param impl _ name : used in error output if no modules succeed
 : return : name , module from first successful implementation"""

implementation:
for name in module_names :
    try :
        module = __import__ ( name )
        has_module = True
    except ImportError :
        module = None
        has_module = False
    setattr ( self , name , module )
    setattr ( self , 'has_%s' % name , has_module )
for name in module_names :
    try :
        return name , __import__ ( name )
    except ImportError :
        pass
raise ImportError ( 'No %s Implementation found, tried: %s' % ( impl_name , ' ' . join ( module_names ) ) )


signature:
def ensure_pycairo_context ( self , ctx ) :
    """If ctx is a cairocffi Context convert it to a PyCairo Context
 otherwise return the original context
 : param ctx :
 : return :"""

implementation:
if self . cairocffi and isinstance ( ctx , self . cairocffi . Context ) :
    from shoebot . util . cairocffi . cairocffi_to_pycairo import _UNSAFE_cairocffi_context_to_pycairo
    return _UNSAFE_cairocffi_context_to_pycairo ( ctx )
else :
    return ctx


signature:
def pangocairo_create_context ( cr ) :
    """If python - gi - cairo is not installed , using PangoCairo . create _ context
 dies with an unhelpful KeyError , check for that and output somethig
 useful ."""

implementation:
# TODO move this to core . backend
try :
    return PangoCairo . create_context ( cr )
except KeyError as e :
    if e . args == ( 'could not find foreign type Context' , ) :
        raise ShoebotInstallError ( "Error creating PangoCairo missing dependency: python-gi-cairo" )
    else :
        raise


signature:
def _get_center ( self ) :
    '''Returns the center point of the path , disregarding transforms .'''

implementation:
w , h = self . layout . get_pixel_size ( )
x = ( self . x + w / 2 )
y = ( self . y + h / 2 )
return x , y


signature:
def is_list ( str ) :
    """Determines if an item in a paragraph is a list .
 If all of the lines in the markup start with a " * " or " 1 . "
 this indicates a list as parsed by parse _ paragraphs ( ) .
 It can be drawn with draw _ list ( ) ."""

implementation:
for chunk in str . split ( "\n" ) :
    chunk = chunk . replace ( "\t" , "" )
    if not chunk . lstrip ( ) . startswith ( "*" ) and not re . search ( r"^([0-9]{1,3}\. )" , chunk . lstrip ( ) ) :
        return False
return True


signature:
def is_math ( str ) :
    """Determines if an item in a paragraph is a LaTeX math equation .
 Math equations are wrapped in < math > < / math > tags .
 They can be drawn as an image using draw _ math ( ) ."""

implementation:
str = str . strip ( )
if str . startswith ( "<math>" ) and str . endswith ( "</math>" ) :
    return True
else :
    return False


signature:
def draw_math ( str , x , y , alpha = 1.0 ) :
    """Uses mimetex to generate a GIF - image from the LaTeX equation ."""

implementation:
try :
    from web import _ctx
except :
    pass
str = re . sub ( "</{0,1}math>" , "" , str . strip ( ) )
img = mimetex . gif ( str )
w , h = _ctx . imagesize ( img )
_ctx . image ( img , x , y , alpha = alpha )
return w , h


signature:
def textwidth ( str ) :
    """textwidth ( ) reports incorrectly when lineheight ( ) is smaller than 1.0"""

implementation:
try :
    from web import _ctx
except :
    pass
l = _ctx . lineheight ( )
_ctx . lineheight ( 1 )
w = _ctx . textwidth ( str )
_ctx . lineheight ( l )
return w


signature:
def draw_list ( markup , x , y , w , padding = 5 , callback = None ) :
    """Draws list markup with indentation in NodeBox .
 Draw list markup at x , y coordinates
 using indented bullets or numbers .
 The callback is a command that takes a str and an int ."""

implementation:
try :
    from web import _ctx
except :
    pass
i = 1
for chunk in markup . split ( "\n" ) :
    if callback != None :
        callback ( chunk , i )
    m = re . search ( "^([0-9]{1,3}\. )" , chunk . lstrip ( ) )
    if m :
        indent = re . search ( "[0-9]" , chunk ) . start ( ) * padding * 2
        bullet = m . group ( 1 )
        dx = textwidth ( "000." )
        chunk = chunk . lstrip ( m . group ( 1 ) + "\t" )
    if chunk . lstrip ( ) . startswith ( "*" ) :
        indent = chunk . find ( "*" ) * padding * 2
        bullet = u"•"
        dx = textwidth ( "*" )
        chunk = chunk . lstrip ( "* \t" )
    _ctx . text ( bullet , x + indent , y )
    dx += padding + indent
    _ctx . text ( chunk , x + dx , y , width = w - dx )
    y += _ctx . textheight ( chunk , width = w - dx )
    y += _ctx . textheight ( " " ) * 0.25
    i += 1


signature:
def draw_table ( table , x , y , w , padding = 5 ) :
    """This is a very poor algorithm to draw Wikipedia tables in NodeBox ."""

implementation:
try :
    from web import _ctx
except :
    pass
f = _ctx . fill ( )
_ctx . stroke ( f )
h = _ctx . textheight ( " " ) + padding * 2
row_y = y
if table . title != "" :
    _ctx . fill ( f )
    _ctx . rect ( x , row_y , w , h )
    _ctx . fill ( 1 )
    _ctx . text ( table . title , x + padding , row_y + _ctx . fontsize ( ) + padding )
    row_y += h
# A table of flags marking how long a cell
# from a previous row is still spanning in a column .
rowspans = [ 1 for i in range ( 10 ) ]
previous_cell_w = 0
for row in table :
    cell_x = x
    # The width of a cell is the total table width
    # evenly divided by the number of cells .
    # Previous rows ' cells still spanning will push cells
    # to the right and decrease their width .
    cell_w = 1.0 * w
    cell_w -= previous_cell_w * len ( [ n for n in rowspans if n > 1 ] )
    cell_w /= len ( row )
    # The height of each cell is the highest cell in the row .
    # The height depends on the amount of text in the cell .
    cell_h = 0
    for cell in row :
        this_h = _ctx . textheight ( cell , width = cell_w - padding * 2 ) + padding * 2
        cell_h = max ( cell_h , this_h )
    # Traverse each cell in this row .
    i = 0
    for cell in row : # If a previous row ' s cell is still spanning ,
    # push this cell to the right .
        if rowspans [ i ] > 1 :
            rowspans [ i ] -= 1
            cell_x += previous_cell_w
            i += 1
        # Get the rowspan attribute for this cell .
        m = re . search ( "rowspan=\"(.*?)\"" , cell . properties )
        if m :
            rowspan = int ( m . group ( 1 ) )
            rowspans [ i ] = rowspan
        else :
            rowspan = 1
        # Padded cell text .
        # Horizontal line above each cell .
        # Vertical line before each cell .
        _ctx . fill ( f )
        _ctx . text ( cell , cell_x + padding , row_y + _ctx . fontsize ( ) + padding , cell_w - padding * 2 )
        _ctx . line ( cell_x , row_y , cell_x + cell_w , row_y )
        if cell_x > x :
            _ctx . nofill ( )
            _ctx . line ( cell_x , row_y , cell_x , row_y + cell_h )
        cell_x += cell_w
        i += 1
    # Move to next row .
    row_y += cell_h
    previous_cell_w = cell_w
# Table ' s bounding rectangle .
_ctx . nofill ( )
_ctx . rect ( x , y , w , row_y - y )


signature:
def parse ( self , light = False ) :
    """Parses data from Wikipedia page markup .
 The markup comes from Wikipedia ' s edit page .
 We parse it here into objects containing plain text .
 The light version parses only links to other articles , it ' s faster than a full parse ."""

implementation:
markup = self . markup
self . disambiguation = self . parse_disambiguation ( markup )
self . categories = self . parse_categories ( markup )
self . links = self . parse_links ( markup )
if not light : # Conversion of HTML markup to Wikipedia markup .
    markup = self . convert_pre ( markup )
    markup = self . convert_li ( markup )
    markup = self . convert_table ( markup )
    markup = replace_entities ( markup )
    # Harvest references from the markup
    # and replace them by footnotes .
    markup = markup . replace ( "{{Cite" , "{{cite" )
    markup = re . sub ( "\{\{ {1,2}cite" , "{{cite" , markup )
    self . references , markup = self . parse_references ( markup )
    # Make sure there are no legend linebreaks in image links .
    # Then harvest images and strip them from the markup .
    markup = re . sub ( "\n+(\{\{legend)" , "\\1" , markup )
    self . images , markup = self . parse_images ( markup )
    self . images . extend ( self . parse_gallery_images ( markup ) )
    self . paragraphs = self . parse_paragraphs ( markup )
    self . tables = self . parse_tables ( markup )
    self . translations = self . parse_translations ( markup )
    self . important = self . parse_important ( markup )


signature:
def plain ( self , markup ) :
    """Strips Wikipedia markup from given text .
 This creates a " plain " version of the markup ,
 stripping images and references and the like .
 Does some commonsense maintenance as well ,
 like collapsing multiple spaces .
 If you specified full _ strip = False for WikipediaPage instance ,
 some markup is preserved as HTML ( links , bold , italic ) ."""

implementation:
# Strip bold and italic .
if self . full_strip :
    markup = markup . replace ( "'''" , "" )
    markup = markup . replace ( "''" , "" )
else :
    markup = re . sub ( "'''([^']*?)'''" , "\\1" , markup )
    markup = re . sub ( "''([^']*?)''" , "\\1" , markup )
# Strip image gallery sections .
markup = re . sub ( self . re [ "gallery" ] , "" , markup )
# Strip tables .
markup = re . sub ( self . re [ "table" ] , "" , markup )
markup = markup . replace ( "||" , "" )
markup = markup . replace ( "|}" , "" )
# Strip links , keeping the display alias .
# We ' ll strip the ending ] ] later .
if self . full_strip :
    markup = re . sub ( r"\[\[[^\]]*?\|" , "" , markup )
else :
    markup = re . sub ( r"\[\[([^]|]*|)\]\]" , '\\1' , markup )
    markup = re . sub ( r"\[\[([^]|]*|)\|([^]]*)\]\]" , '\\2' , markup )
# Strip translations , users , etc .
markup = re . sub ( self . re [ "translation" ] , "" , markup )
# This math TeX is not supported :
markup = markup . replace ( "\displaytyle" , "" )
markup = markup . replace ( "\textstyle" , "" )
markup = markup . replace ( "\scriptstyle" , "" )
markup = markup . replace ( "\scriptscriptstyle" , "" )
# Before stripping [ and ] brackets ,
# make sure they are retained inside < math > < / math > equations .
markup = re . sub ( "(<math>.*?)\[(.*?</math>)" , "\\1MATH___OPEN\\2" , markup )
markup = re . sub ( "(<math>.*?)\](.*?</math>)" , "\\1MATH___CLOSE\\2" , markup )
markup = markup . replace ( "[" , "" )
markup = markup . replace ( "]" , "" )
markup = markup . replace ( "MATH___OPEN" , "[" )
markup = markup . replace ( "MATH___CLOSE" , "]" )
# a ) Strip references .
# b ) Strip < ref > < / ref > tags .
# c ) Strip < ref name = " " / > tags .
# d ) Replace - - REF - - ( 12 ) by [ 12 ] .
# e ) Remove space between [ 12 ] and trailing punctuation . ,
# f ) Remove HTML comment < ! - - - - >
# g ) Keep the Latin Extended - B template : { { latinx | } }
# h ) Strip Middle - Earth references .
# i ) Keep quotes : { { quote | } }
# j ) Remove templates
markup = re . sub ( self . re [ "reference" ] , "" , markup )
markup = re . sub ( "</{0,1}ref.*?>" , "" , markup )
markup = re . sub ( "<ref name=\".*?\" {0,1}/>" , "" , markup )
markup = re . sub ( self . ref + "\(([0-9]*?)\)" , "[\\1] " , markup )
markup = re . sub ( "\] ([,.\"\?\)])" , "]\\1" , markup )
markup = re . sub ( self . re [ "comment" ] , "" , markup )
markup = re . sub ( "\{\{latinx\|(.*?)\}\}" , "\\1" , markup )
markup = re . sub ( "\{\{ME-ref.*?\}\}" , "" , markup )
markup = re . sub ( "\{\{quote\|(.*?)\}\}" , "\"\\1\"" , markup )
markup = re . sub ( re . compile ( "\{\{.*?\}\}" , re . DOTALL ) , "" , markup )
markup = markup . replace ( "}}" , "" )
# Collapse multiple spaces between words ,
# unless they appear in preformatted text .
markup = re . sub ( "
" , " " , markup )
markup = markup . split ( "\n" )
for i in range ( len ( markup ) ) :
    if not markup [ i ] . startswith ( " " ) :
        markup [ i ] = re . sub ( r"[ ]+" , " " , markup [ i ] )
markup = "\n" . join ( markup )
markup = markup . replace ( " ." , "." )
# Strip all HTML except < math > tags .
if self . full_strip :
    markup = strip_tags ( markup , exclude = [ "math" ] , linebreaks = True )
markup = markup . strip ( )
return markup


signature:
def convert_pre ( self , markup ) :
    """Substitutes < pre > to Wikipedia markup by adding a space at the start of a line ."""

implementation:
for m in re . findall ( self . re [ "preformatted" ] , markup ) :
    markup = markup . replace ( m , m . replace ( "\n" , "\n " ) )
    markup = re . sub ( "<pre.*?>\n{0,}" , "" , markup )
    markup = re . sub ( "\W{0,}</pre>" , "" , markup )
return markup


signature:
def convert_li ( self , markup ) :
    """Subtitutes < li > content to Wikipedia markup ."""

implementation:
for li in re . findall ( "<li;*?>" , markup ) :
    markup = re . sub ( li , "\n* " , markup )
markup = markup . replace ( "</li>" , "" )
return markup


signature:
def convert_table ( self , markup ) :
    """Subtitutes < table > content to Wikipedia markup ."""

implementation:
for table in re . findall ( self . re [ "html-table" ] , markup ) :
    wiki = table
    wiki = re . sub ( r"
" , "{|\\1" , wiki )
    wiki = re . sub ( r"
" , "|-\\1" , wiki )
    wiki = re . sub ( r"" , "|\\1|" , wiki )
    wiki = wiki . replace ( "	" , "\n" )
    wiki = wiki . replace ( "
" , "\n" )
    wiki = wiki . replace ( "
" , "\n|}" )
    markup = markup . replace ( table , wiki )
return markup


signature:
def parse_links ( self , markup ) :
    """Returns a list of internal Wikipedia links in the markup .
 # A Wikipedia link looks like :
 # [ [ List of operating systems # Embedded | List of embedded operating systems ] ]
 # It does not contain a colon , this indicates images , users , languages , etc .
 The return value is a list containing the first part of the link ,
 without the anchor ."""

implementation:
links = [ ]
m = re . findall ( self . re [ "link" ] , markup )
for link in m : # We don ' t like [ [ { { { 1 | Universe ( disambiguation ) } } } ] ]
    if link . find ( "{" ) >= 0 :
        link = re . sub ( "\{{1,3}[0-9]{0,2}\|" , "" , link )
        link = link . replace ( "{" , "" )
        link = link . replace ( "}" , "" )
    link = link . split ( "|" )
    link [ 0 ] = link [ 0 ] . split ( "#" )
    page = link [ 0 ] [ 0 ] . strip ( )
    # anchor = u " "
    # display = u " "
    # if len ( link [ 0 ] ) > 1:
    # anchor = link [ 0 ] [ 1 ] . strip ( )
    # if len ( link ) > 1:
    # display = link [ 1 ] . strip ( )
    if not page in links :
        links . append ( page )
        # links [ page ] = WikipediaLink ( page , anchor , display )
links . sort ( )
return links


signature:
def parse_images ( self , markup , treshold = 6 ) :
    """Returns a list of images found in the markup .
 An image has a pathname , a description in plain text
 and a list of properties Wikipedia uses to size and place images .
 # A Wikipedia image looks like :
 # [ [ Image : Columbia Supercomputer - NASA Advanced Supercomputing Facility . jpg | right | thumb |
 # The [ [ NASA ] ] [ [ Columbia ( supercomputer ) | Columbia Supercomputer ] ] . ] ]
 # Parts are separated by " | " .
 # The first part is the image file , the last part can be a description .
 # In between are display properties , like " right " or " thumb " ."""

implementation:
images = [ ]
m = re . findall ( self . re [ "image" ] , markup )
for p in m :
    p = self . parse_balanced_image ( p )
    img = p . split ( "|" )
    path = img [ 0 ] . replace ( "[[Image:" , "" ) . strip ( )
    description = u""
    links = { }
    properties = [ ]
    if len ( img ) > 1 :
        img = "|" . join ( img [ 1 : ] )
        links = self . parse_links ( img )
        properties = self . plain ( img ) . split ( "|" )
        description = u""
        # Best guess : an image description is normally
        # longer than six characters , properties like
        # " thumb " and " right " are less than six characters .
        if len ( properties [ - 1 ] ) > treshold :
            description = properties [ - 1 ]
            properties = properties [ : - 1 ]
    img = WikipediaImage ( path , description , links , properties )
    images . append ( img )
    markup = markup . replace ( p , "" )
return images , markup . strip ( )


signature:
def parse_balanced_image ( self , markup ) :
    """Corrects Wikipedia image markup .
 Images have a description inside their link markup that
 can contain link markup itself , make sure the outer " [ " and " ] " brackets
 delimiting the image are balanced correctly ( e . g . no [ [ ] ] ] ] ) .
 Called from parse _ images ( ) ."""

implementation:
opened = 0
closed = 0
for i in range ( len ( markup ) ) :
    if markup [ i ] == "[" :
        opened += 1
    if markup [ i ] == "]" :
        closed += 1
    if opened == closed :
        return markup [ : i + 1 ]
return markup


signature:
def parse_gallery_images ( self , markup ) :
    """Parses images from the < gallery > < / gallery > section .
 Images inside < gallery > tags do not have outer " [ [ " brackets .
 Add these and then parse again ."""

implementation:
gallery = re . search ( self . re [ "gallery" ] , markup )
if gallery :
    gallery = gallery . group ( 1 )
    gallery = gallery . replace ( "Image:" , "[[Image:" )
    gallery = gallery . replace ( "\n" , "]]\n" )
    images , markup = self . parse_images ( gallery )
    return images
return [ ]


signature:
def parse_paragraph ( self , markup ) :
    """Creates a list from lines of text in a paragraph .
 Each line of text is a new item in the list ,
 except lists and preformatted chunks ( < li > and < pre > ) ,
 these are kept together as a single chunk .
 Lists are formatted using parse _ paragraph _ list ( ) .
 Empty lines are stripped from the output .
 Indentation ( i . e . lines starting with " : " ) is ignored .
 Called from parse _ paragraphs ( ) method ."""

implementation:
s = self . plain ( markup )
# Add an extra linebreak between the last list item
# and the normal line following after it , so they don ' t stick together , e . g .
# * * [ [ Alin Magic ] ] , magic used in the videogame ' ' [ [ Rise of Nations : Rise of Legends ] ] ' '
# In ' ' ' popular culture ' ' ' :
# * [ [ Magic ( film ) | ' ' Magic ' ' ( film ) ] ] , a 1978 film starring Anthony Hopkins and Ann - Margret
s = re . sub ( re . compile ( "\n([*#;].*?)\n([^*#?])" , re . DOTALL ) , "\n\\1\n\n\\2" , s )
# This keeps list items with linebreaks
# between them nicely together .
s = re . sub ( "\n{2,3}([*#;])" , "\n\\1" , s )
chunks = [ ]
ch = ""
i = 1
for chunk in s . split ( "\n" ) :
    if chunk . startswith ( ":" ) :
        chunk = chunk . lstrip ( ":" )
    if len ( chunk . strip ( ) ) > 1 : # Leave out taxoboxes and infoboxes .
        if not chunk . startswith ( "|" ) :
            ch += chunk + "\n"
    if ch . strip ( ) != "" :
        if not re . search ( "^[ *#;]" , chunk ) :
            ch = self . parse_paragraph_list ( ch )
            chunks . append ( ch . rstrip ( ) )
            ch = ""
if ch . strip ( ) != "" :
    ch = self . parse_paragraph_list ( ch )
    chunks . append ( ch . strip ( ) )
return chunks


signature:
def parse_paragraph_list ( self , markup , indent = "\t" ) :
    """Formats bullets and numbering of Wikipedia lists .
 List items are marked by " * " , " # " or " ; " at the start of a line .
 We treat " ; " the same as " * " ,
 and replace " # " with real numbering ( e . g . " 2 . " ) .
 Sublists ( e . g . * * * and # # # ) get indented by tabs .
 Called from parse _ paragraphs ( ) method ."""

implementation:
def lastleft ( ch , str ) :
    n = 0
    while n < len ( str ) and str [ n ] == ch :
        n += 1
    return n
tally = [ 1 for i in range ( 10 ) ]
chunks = markup . split ( "\n" )
for i in range ( len ( chunks ) ) :
    if chunks [ i ] . startswith ( "#" ) :
        j = min ( lastleft ( "#" , chunks [ i ] ) , len ( tally ) - 1 )
        chunks [ i ] = indent * ( j - 1 ) + str ( tally [ j ] ) + ". " + chunks [ i ] [ j : ]
        chunks [ i ] = chunks [ i ] . replace ( ".  " , ". " )
        tally [ j ] += 1
        # Reset the numbering of sublists .
        for k in range ( j + 1 , len ( tally ) ) :
            tally [ k ] = 1
    if chunks [ i ] . startswith ( ";" ) :
        chunks [ i ] = "*" + chunks [ i ] [ 1 : ]
    if chunks [ i ] . startswith ( "*" ) :
        j = lastleft ( "*" , chunks [ i ] )
        chunks [ i ] = indent * ( j - 1 ) + "* " + chunks [ i ] [ j : ]
        chunks [ i ] = chunks [ i ] . replace ( "*  " , "* " )
return "\n" . join ( chunks )


signature:
def connect_paragraph ( self , paragraph , paragraphs ) :
    """Create parent / child links to other paragraphs .
 The paragraphs parameters is a list of all the paragraphs
 parsed up till now .
 The parent is the previous paragraph whose depth is less .
 The parent ' s children include this paragraph .
 Called from parse _ paragraphs ( ) method ."""

implementation:
if paragraph . depth > 0 :
    n = range ( len ( paragraphs ) )
    n . reverse ( )
    for i in n :
        if paragraphs [ i ] . depth == paragraph . depth - 1 :
            paragraph . parent = paragraphs [ i ]
            paragraphs [ i ] . children . append ( paragraph )
            break
return paragraph


signature:
def parse_paragraph_references ( self , markup ) :
    """Updates references with content from specific paragraphs .
 The " references " , " notes " , " external links " paragraphs
 are double - checked for references . Not all items in the list
 might have been referenced inside the article , or the item
 might contain more info than we initially parsed from it .
 Called from parse _ paragraphs ( ) method ."""

implementation:
for chunk in markup . split ( "\n" ) : # We already parsed this , it contains the self . ref mark .
# See if we can strip more notes from it .
    m = re . search ( self . ref + "\(([0-9]*?)\)" , chunk )
    if m :
        chunk = chunk . strip ( "* " )
        chunk = chunk . replace ( m . group ( 0 ) , "" )
        chunk = self . plain ( chunk )
        i = int ( m . group ( 1 ) )
        if chunk != "" :
            self . references [ i - 1 ] . note = chunk
    # If it ' s not a citation we don ' t have this reference yet .
    elif chunk . strip ( ) . startswith ( "*" ) and chunk . find ( "{{cite" ) < 0 :
        chunk = chunk . strip ( "* " )
        chunk = self . plain ( chunk )
        if chunk != "" :
            r = WikipediaReference ( )
            r . note = chunk
            self . references . append ( r )


signature:
def parse_paragraphs ( self , markup ) :
    """Returns a list of paragraphs in the markup .
 A paragraph has a title and multiple lines of plain text .
 A paragraph might have parent and child paragraphs ,
 denoting subtitles or bigger chapters .
 A paragraph might have links to additional articles .
 Formats numbered lists by replacing # by 1.
 Formats bulleted sublists like * * or * * * with indentation ."""

implementation:
# Paragraphs to exclude .
refs = [ "references" , "notes" , "notes and references" , "external links" , "further reading" ]
exclude = [ "see also" , "media" , "gallery" , "related topics" , "lists" , "gallery" , "images" ]
exclude . extend ( refs )
paragraphs = [ ]
paragraph = WikipediaParagraph ( self . title )
paragraph_data = ""
for chunk in markup . split ( "\n" ) : # Strip each line of whitespace ,
# unless it ' s a preformatted line ( starts with a space ) .
    if not chunk . startswith ( " " ) :
        chunk = chunk . strip ( )
    # A title wrapped in " = " , " = = " , " = = = " . . .
    # denotes a new paragraphs section .
    if chunk . startswith ( "=" ) :
        if paragraph . title . lower ( ) in refs or ( paragraph . parent and paragraph . parent . title . lower ( ) in refs ) :
            self . parse_paragraph_references ( paragraph_data )
        paragraph . extend ( self . parse_paragraph ( paragraph_data ) )
        paragraphs . append ( paragraph )
        # Initialise a new paragraph .
        # Create parent / child links to other paragraphs .
        title = chunk . strip ( ) . strip ( "=" )
        title = self . plain ( title )
        paragraph = WikipediaParagraph ( title )
        paragraph . depth = self . parse_paragraph_heading_depth ( chunk )
        if paragraph . title . lower ( ) not in exclude :
            paragraph = self . connect_paragraph ( paragraph , paragraphs )
        paragraph_data = ""
    # Underneath a title might be links to in - depth articles ,
    # e . g . Main articles : Computer program and Computer programming
    # which in wiki markup would be { { main | Computer program | Computer programming } }
    # The second line corrects " { { Main | Credit ( finance ) } } or { { Main | Usury } } " .
    elif re . search ( re . compile ( "^{{main" , re . I ) , chunk ) :
        paragraph . main = [ link . strip ( "} " ) for link in chunk . split ( "|" ) [ 1 : ] ]
        paragraph . main = [ re . sub ( re . compile ( "}}.*?{{main" , re . I ) , "" , link ) for link in paragraph . main ]
    # At the bottom might be links to related articles ,
    # e . g . See also : Abundance of the chemical elements
    # which in wiki markup would be { { see also | Abundance of the chemical elements } }
    elif re . search ( re . compile ( "^{{see {0,1}also" , re . I ) , chunk ) :
        paragraph . related = [ link . strip ( "} " ) for link in chunk . split ( "|" ) [ 1 : ] ]
    # Accumulate the data in this paragraph ,
    # we ' ll process it once a new paragraph starts .
    else :
        paragraph_data += chunk + "\n"
# Append the last paragraph .
if paragraph . title . lower ( ) in refs or ( paragraph . parent and paragraph . parent . title . lower ( ) in refs ) :
    self . parse_paragraph_references ( paragraph_data )
paragraph . extend ( self . parse_paragraph ( paragraph_data ) )
paragraphs . append ( paragraph )
# The " See also " paragraph is an enumeration of links
# which we already parsed so don ' t show them .
# We also did references , and other paragraphs are not that relevant .
paragraphs_exclude = [ ]
for paragraph in paragraphs :
    if paragraph . title . lower ( ) not in exclude and not ( paragraph . parent and paragraph . parent . title . lower ( ) in exclude ) :
        paragraphs_exclude . append ( paragraph )
if len ( paragraphs_exclude ) == 1 and len ( paragraphs_exclude [ 0 ] ) == 0 :
    return [ ]
return paragraphs_exclude


signature:
def parse_table_row ( self , markup , row ) :
    """Parses a row of cells in a Wikipedia table .
 Cells in the row are separated by " | | " .
 A " ! " indicates a row of heading columns .
 Each cell can contain properties before a " | " ,
 # e . g . align = " right " | Cell 2 ( right aligned ) ."""

implementation:
if row == None :
    row = WikipediaTableRow ( )
markup = markup . replace ( "!!" , "||" )
for cell in markup . lstrip ( "|!" ) . split ( "||" ) : # The " | " after the properties can ' t be part of a link .
    i = cell . find ( "|" )
    j = cell . find ( "[[" )
    if i > 0 and ( j < 0 or i < j ) :
        data = self . plain ( cell [ i + 1 : ] )
        properties = cell [ : i ] . strip ( )
    else :
        data = self . plain ( cell )
        properties = u""
    cell = WikipediaTableCell ( data )
    cell . properties = properties
    row . append ( cell )
return row


signature:
def connect_table ( self , table , chunk , markup ) :
    """Creates a link from the table to paragraph and vice versa .
 Finds the first heading above the table in the markup .
 This is the title of the paragraph the table belongs to ."""

implementation:
k = markup . find ( chunk )
i = markup . rfind ( "\n=" , 0 , k )
j = markup . find ( "\n" , i + 1 )
paragraph_title = markup [ i : j ] . strip ( ) . strip ( "= " )
for paragraph in self . paragraphs :
    if paragraph . title == paragraph_title :
        paragraph . tables . append ( table )
        table . paragraph = paragraph


signature:
def parse_tables ( self , markup ) :
    """Returns a list of tables in the markup .
 A Wikipedia table looks like :
 { | border = " 1"
 | Cell 1 ( no modifier - not aligned )
 | align = " right " | Cell 2 ( right aligned )"""

implementation:
tables = [ ]
m = re . findall ( self . re [ "table" ] , markup )
for chunk in m :
    table = WikipediaTable ( )
    table . properties = chunk . split ( "\n" ) [ 0 ] . strip ( "{|" ) . strip ( )
    self . connect_table ( table , chunk , markup )
    # Tables start with " { | " .
    # On the same line can be properties , e . g . { | border = " 1"
    # The table heading starts with " | + " .
    # A new row in the table starts with " | - " .
    # The end of the table is marked with " | } " .
    row = None
    for chunk in chunk . split ( "\n" ) :
        chunk = chunk . strip ( )
        if chunk . startswith ( "|+" ) :
            title = self . plain ( chunk . strip ( "|+" ) )
            table . title = title
        elif chunk . startswith ( "|-" ) :
            if row :
                row . properties = chunk . strip ( "|-" ) . strip ( )
                table . append ( row )
            row = None
        elif chunk . startswith ( "|}" ) :
            pass
        elif chunk . startswith ( "|" ) or chunk . startswith ( "!" ) :
            row = self . parse_table_row ( chunk , row )
    # Append the last row .
    if row :
        table . append ( row )
    if len ( table ) > 0 :
        tables . append ( table )
return tables


signature:
def parse_references ( self , markup ) :
    """Returns a list of references found in the markup .
 References appear inline as < ref > footnotes ,
 http : / / external links , or { { cite } } citations .
 We replace it with ( 1 ) - style footnotes .
 Additional references data is gathered in
 parse _ paragraph _ references ( ) when we parse paragraphs .
 References can also appear in image descriptions ,
 tables and taxoboxes , so they might not always pop up in a paragraph .
 The plain ( ) method finally replaces ( 1 ) by [ 1 ] ."""

implementation:
references = [ ]
# A Wikipedia reference note looks like :
# < ref > In 1946 , [ [ ENIAC ] ] consumed an estimated 174 kW .
# By comparison , a typical personal computer may use around 400 W ;
# over four hundred times less . { { Ref harvard | kempf1961 | Kempf 1961 | a } } < / ref >
m = re . findall ( self . re [ "reference" ] , markup )
for reference in m :
    reference = re . sub ( "<ref> {0,1}cite" , "<ref>{{cite" , reference )
    if not reference . strip ( ) . startswith ( "[http://" ) and not re . search ( "\{\{cite" , reference ) :
        r = WikipediaReference ( )
        r . note = self . plain ( re . sub ( "</{0,1}ref.*?>" , "" , reference ) )
        if r . note != "" :
            references . append ( r )
            p = " " + self . ref + "(" + str ( len ( references ) ) + ")"
            markup = markup . replace ( reference , p , 1 )
    else : # References containing a citation or url
    # are better handled by the next patterns .
        pass
# A Wikipedia citation looks like :
# { { cite journal
# | last = Einstein
# | first = Albert
# | authorlink = Albert Einstein
# | title = Sidelights on Relativity ( Geometry and Experience )
# | publisher = P . Dutton . , Co
# | date = 1923 } }
m = re . findall ( self . re [ "citation" ] , markup )
for citation in m :
    c = citation . replace ( "\n" , "" )
    r = WikipediaReference ( )
    for key in r . __dict__ . keys ( ) :
        value = re . search ( "\| {0,1}" + key + "(.*?)[\|}]" , c )
        if value :
            value = value . group ( 1 )
            value = value . replace ( "link" , "" )
            value = value . strip ( ) . strip ( " =[]" )
            value = self . plain ( value )
            setattr ( r , key , value )
    if r . first != "" and r . last != "" :
        r . author = r . first + " " + r . last
    references . append ( r )
    p = " " + self . ref + "(" + str ( len ( references ) ) + ")"
    markup = markup . replace ( citation , p , 1 )
# A Wikipedia embedded url looks like :
# [ http : / / www . pbs . org / wnet / hawking / html / home . html ' ' Stephen Hawking ' s Universe ' ' ]
m = re . findall ( self . re [ "url" ] , markup )
for url in m :
    r = WikipediaReference ( )
    i = url . find ( " " )
    if i > 0 :
        r . url = url [ : i ] . strip ( )
        r . note = self . plain ( url [ i : ] )
    else :
        r . url = url . strip ( )
    references . append ( r )
    p = r . note + " " + self . ref + "(" + str ( len ( references ) ) + ")"
    markup = markup . replace ( "[" + url + "]" , p , 1 )
# Since we parsed all citations first and then all notes and urls ,
# the ordering will not be correct in the markup ,
# e . g . ( 1 ) ( 11 ) ( 12 ) ( 2 ) ( 3 ) .
sorted = [ ]
m = re . findall ( self . ref + "\(([0-9]*)\)" , markup )
for i in m :
    sorted . append ( references [ int ( i ) - 1 ] )
    markup = markup . replace ( self . ref + "(" + i + ")" , self . ref + "**(" + str ( len ( sorted ) ) + ")" )
markup = markup . replace ( self . ref + "**" , self . ref )
for r in references :
    if r not in sorted :
        sorted . append ( r )
references = sorted
return references , markup . strip ( )


signature:
def parse_categories ( self , markup ) :
    """Returns a list of categories the page belongs to .
 # A Wikipedia category link looks like :
 # [ [ Category : Computing ] ]
 # This indicates the page is included in the given category .
 # If " Category " is preceded by " : " this indicates a link to a category ."""

implementation:
categories = [ ]
m = re . findall ( self . re [ "category" ] , markup )
for category in m :
    category = category . split ( "|" )
    page = category [ 0 ] . strip ( )
    display = u""
    if len ( category ) > 1 :
        display = category [ 1 ] . strip ( )
    # if not categories . has _ key ( page ) :
    # categories [ page ] = WikipediaLink ( page , u " " , display )
    if not page in categories :
        categories . append ( page )
return categories


signature:
def parse_translations ( self , markup ) :
    """Returns a dictionary of translations for the page title .
 A Wikipedia language link looks like : [ [ af : Rekenaar ] ] .
 The parser will also fetch links like " user : " and " media : "
 but these are stripped against the dictionary of
 Wikipedia languages .
 You can get a translated page by searching Wikipedia
 with the appropriate language code and supplying
 the translated title as query ."""

implementation:
global languages
translations = { }
m = re . findall ( self . re [ "translation" ] , markup )
for language , translation in m :
    if language in languages :
        translations [ language ] = translation
return translations


signature:
def parse_disambiguation ( self , markup ) :
    """Gets the Wikipedia disambiguation page for this article .
 A Wikipedia disambiguation link refers to other pages
 with the same title but of smaller significance ,
 e . g . { { dablink | For the IEEE magazine see [ [ Computer ( magazine ) ] ] . } }"""

implementation:
m = re . search ( self . re [ "disambiguation" ] , markup )
if m :
    return self . parse_links ( m . group ( 1 ) )
else :
    return [ ]


signature:
def parse_important ( self , markup ) :
    """Returns a list of words that appear in bold in the article .
 Things like table titles are not added to the list ,
 these are probably bold because it makes the layout nice ,
 not necessarily because they are important ."""

implementation:
important = [ ]
table_titles = [ table . title for table in self . tables ]
m = re . findall ( self . re [ "bold" ] , markup )
for bold in m :
    bold = self . plain ( bold )
    if not bold in table_titles :
        important . append ( bold . lower ( ) )
return important


signature:
def sanitize ( self , val ) :
    """Given a Variable and a value , cleans it out"""

implementation:
if self . type == NUMBER :
    try :
        return clamp ( self . min , self . max , float ( val ) )
    except ValueError :
        return 0.0
elif self . type == TEXT :
    try :
        return unicode ( str ( val ) , "utf_8" , "replace" )
    except :
        return ""
elif self . type == BOOLEAN :
    if unicode ( val ) . lower ( ) in ( "true" , "1" , "yes" ) :
        return True
    else :
        return False


signature:
def compliesTo ( self , v ) :
    """Return whether I am compatible with the given var :
 - Type should be the same
 - My value should be inside the given vars ' min / max range ."""

implementation:
if self . type == v . type :
    if self . type == NUMBER :
        if self . value < self . min or self . value > self . max :
            return False
    return True
return False


signature:
def isList ( l ) :
    """Convenience method that works with all 2 . x versions of Python
 to determine whether or not something is listlike ."""

implementation: return hasattr ( l , '__iter__' ) or ( type ( l ) in ( types . ListType , types . TupleType ) )


signature:
def isString ( s ) :
    """Convenience method that works with all 2 . x versions of Python
 to determine whether or not something is stringlike ."""

implementation:
try :
    return isinstance ( s , unicode ) or isinstance ( s , basestring )
except NameError :
    return isinstance ( s , str )


signature:
def buildTagMap ( default , * args ) :
    """Turns a list of maps , lists , or scalars into a single map .
 Used to build the SELF _ CLOSING _ TAGS , NESTABLE _ TAGS , and
 NESTING _ RESET _ TAGS maps out of lists and partial maps ."""

implementation:
built = { }
for portion in args :
    if hasattr ( portion , 'items' ) : # It ' s a map . Merge it .
        for k , v in portion . items ( ) :
            built [ k ] = v
    elif isList ( portion ) : # It ' s a list . Map each item to the default .
        for k in portion :
            built [ k ] = default
    else : # It ' s a scalar . Map it to the default .
        built [ portion ] = default
return built


signature:
def setup ( self , parent = None , previous = None ) :
    """Sets up the initial relations between this element and
 other elements ."""

implementation:
self . parent = parent
self . previous = previous
self . next = None
self . previousSibling = None
self . nextSibling = None
if self . parent and self . parent . contents :
    self . previousSibling = self . parent . contents [ - 1 ]
    self . previousSibling . nextSibling = self


signature:
def extract ( self ) :
    """Destructively rips this element out of the tree ."""

implementation:
if self . parent :
    try :
        self . parent . contents . remove ( self )
    except ValueError :
        pass
# Find the two elements that would be next to each other if
# this element ( and any children ) hadn ' t been parsed . Connect
# the two .
lastChild = self . _lastRecursiveChild ( )
nextElement = lastChild . next
if self . previous :
    self . previous . next = nextElement
if nextElement :
    nextElement . previous = self . previous
self . previous = None
lastChild . next = None
self . parent = None
if self . previousSibling :
    self . previousSibling . nextSibling = self . nextSibling
if self . nextSibling :
    self . nextSibling . previousSibling = self . previousSibling
self . previousSibling = self . nextSibling = None
return self


signature:
def _lastRecursiveChild ( self ) :
    "Finds the last element beneath this object to be parsed ."

implementation:
lastChild = self
while hasattr ( lastChild , 'contents' ) and lastChild . contents :
    lastChild = lastChild . contents [ - 1 ]
return lastChild


signature:
def findNext ( self , name = None , attrs = { } , text = None , ** kwargs ) :
    """Returns the first item that matches the given criteria and
 appears after this Tag in the document ."""

implementation: return self . _findOne ( self . findAllNext , name , attrs , text , ** kwargs )


signature:
def findAllNext ( self , name = None , attrs = { } , text = None , limit = None , ** kwargs ) :
    """Returns all items that match the given criteria and appear
 after this Tag in the document ."""

implementation: return self . _findAll ( name , attrs , text , limit , self . nextGenerator , ** kwargs )


signature:
def findNextSibling ( self , name = None , attrs = { } , text = None , ** kwargs ) :
    """Returns the closest sibling to this Tag that matches the
 given criteria and appears after this Tag in the document ."""

implementation: return self . _findOne ( self . findNextSiblings , name , attrs , text , ** kwargs )


signature:
def findNextSiblings ( self , name = None , attrs = { } , text = None , limit = None , ** kwargs ) :
    """Returns the siblings of this Tag that match the given
 criteria and appear after this Tag in the document ."""

implementation: return self . _findAll ( name , attrs , text , limit , self . nextSiblingGenerator , ** kwargs )


signature:
def findPrevious ( self , name = None , attrs = { } , text = None , ** kwargs ) :
    """Returns the first item that matches the given criteria and
 appears before this Tag in the document ."""

implementation: return self . _findOne ( self . findAllPrevious , name , attrs , text , ** kwargs )


signature:
def findAllPrevious ( self , name = None , attrs = { } , text = None , limit = None , ** kwargs ) :
    """Returns all items that match the given criteria and appear
 before this Tag in the document ."""

implementation: return self . _findAll ( name , attrs , text , limit , self . previousGenerator , ** kwargs )


signature:
def findPreviousSibling ( self , name = None , attrs = { } , text = None , ** kwargs ) :
    """Returns the closest sibling to this Tag that matches the
 given criteria and appears before this Tag in the document ."""

implementation: return self . _findOne ( self . findPreviousSiblings , name , attrs , text , ** kwargs )


signature:
def findPreviousSiblings ( self , name = None , attrs = { } , text = None , limit = None , ** kwargs ) :
    """Returns the siblings of this Tag that match the given
 criteria and appear before this Tag in the document ."""

implementation: return self . _findAll ( name , attrs , text , limit , self . previousSiblingGenerator , ** kwargs )


signature:
def findParent ( self , name = None , attrs = { } , ** kwargs ) :
    """Returns the closest parent of this Tag that matches the given
 criteria ."""

implementation:
# NOTE : We can ' t use _ findOne because findParents takes a different
# set of arguments .
r = None
l = self . findParents ( name , attrs , 1 )
if l :
    r = l [ 0 ]
return r


signature:
def findParents ( self , name = None , attrs = { } , limit = None , ** kwargs ) :
    """Returns the parents of this Tag that match the given
 criteria ."""

implementation: return self . _findAll ( name , attrs , None , limit , self . parentGenerator , ** kwargs )


signature:
def _findAll ( self , name , attrs , text , limit , generator , ** kwargs ) :
    "Iterates over a generator looking for things that match ."

implementation:
if isinstance ( name , SoupStrainer ) :
    strainer = name
else : # Build a SoupStrainer
    strainer = SoupStrainer ( name , attrs , text , ** kwargs )
results = ResultSet ( strainer )
g = generator ( )
while True :
    try :
        i = g . next ( )
    except StopIteration :
        break
    if i :
        found = strainer . search ( i )
        if found :
            results . append ( found )
            if limit and len ( results ) >= limit :
                break
return results


signature:
def toEncoding ( self , s , encoding = None ) :
    """Encodes an object to a string in some encoding , or to Unicode ."""

implementation:
if isinstance ( s , unicode ) :
    if encoding :
        s = s . encode ( encoding )
elif isinstance ( s , str ) :
    if encoding :
        s = s . encode ( encoding )
    else :
        s = unicode ( s )
else :
    if encoding :
        s = self . toEncoding ( str ( s ) , encoding )
    else :
        s = unicode ( s )
return s


signature:
def _invert ( h ) :
    "Cheap function to invert a hash ."

implementation:
i = { }
for k , v in h . items ( ) :
    i [ v ] = k
return i


signature:
def _convertEntities ( self , match ) :
    """Used in a call to re . sub to replace HTML , XML , and numeric
 entities with the appropriate Unicode characters . If HTML
 entities are being converted , any unrecognized entities are
 escaped ."""

implementation:
x = match . group ( 1 )
if self . convertHTMLEntities and x in name2codepoint :
    return unichr ( name2codepoint [ x ] )
elif x in self . XML_ENTITIES_TO_SPECIAL_CHARS :
    if self . convertXMLEntities :
        return self . XML_ENTITIES_TO_SPECIAL_CHARS [ x ]
    else :
        return u'&%s;' % x
elif len ( x ) > 0 and x [ 0 ] == '#' : # Handle numeric entities
    if len ( x ) > 1 and x [ 1 ] == 'x' :
        return unichr ( int ( x [ 2 : ] , 16 ) )
    else :
        return unichr ( int ( x [ 1 : ] ) )
elif self . escapeUnrecognizedEntities :
    return u'&%s;' % x
else :
    return u'&%s;' % x


signature:
def decompose ( self ) :
    """Recursively destroys the contents of this tree ."""

implementation:
contents = [ i for i in self . contents ]
for i in contents :
    if isinstance ( i , Tag ) :
        i . decompose ( )
    else :
        i . extract ( )
self . extract ( )


signature:
def renderContents ( self , encoding = DEFAULT_OUTPUT_ENCODING , prettyPrint = False , indentLevel = 0 ) :
    """Renders the contents of this tag as a string in the given
 encoding . If encoding is None , returns a Unicode string . ."""

implementation:
s = [ ]
for c in self :
    text = None
    if isinstance ( c , NavigableString ) :
        text = c . __str__ ( encoding )
    elif isinstance ( c , Tag ) :
        s . append ( c . __str__ ( encoding , prettyPrint , indentLevel ) )
    if text and prettyPrint :
        text = text . strip ( )
    if text :
        if prettyPrint :
            s . append ( " " * ( indentLevel - 1 ) )
        s . append ( text )
        if prettyPrint :
            s . append ( "\n" )
return '' . join ( s )


signature:
def find ( self , name = None , attrs = { } , recursive = True , text = None , ** kwargs ) :
    """Return only the first child of this Tag matching the given
 criteria ."""

implementation:
r = None
l = self . findAll ( name , attrs , recursive , text , 1 , ** kwargs )
if l :
    r = l [ 0 ]
return r


signature:
def findAll ( self , name = None , attrs = { } , recursive = True , text = None , limit = None , ** kwargs ) :
    """Extracts a list of Tag objects that match the given
 criteria . You can specify the name of the Tag and any
 attributes you want the Tag to have .
 The value of a key - value pair in the ' attrs ' map can be a
 string , a list of strings , a regular expression object , or a
 callable that takes a string and returns whether or not the
 string matches for some custom definition of ' matches ' . The
 same is true of the tag name ."""

implementation:
generator = self . recursiveChildGenerator
if not recursive :
    generator = self . childGenerator
return self . _findAll ( name , attrs , text , limit , generator , ** kwargs )


signature:
def _getAttrMap ( self ) :
    """Initializes a map representation of this tag ' s attributes ,
 if not already initialized ."""

implementation:
if not getattr ( self , 'attrMap' ) :
    self . attrMap = { }
    for ( key , value ) in self . attrs :
        self . attrMap [ key ] = value
return self . attrMap


signature:
def convert_charref ( self , name ) :
    """This method fixes a bug in Python ' s SGMLParser ."""

implementation:
try :
    n = int ( name )
except ValueError :
    return
if not 0 <= n <= 127 : # ASCII ends at 127 , not 255
    return
return self . convert_codepoint ( n )


signature:
def isSelfClosingTag ( self , name ) :
    """Returns true iff the given string is the name of a
 self - closing tag according to this parser ."""

implementation: return self . SELF_CLOSING_TAGS . has_key ( name ) or self . instanceSelfClosingTags . has_key ( name )


signature:
def _popToTag ( self , name , inclusivePop = True ) :
    """Pops the tag stack up to and including the most recent
 instance of the given tag . If inclusivePop is false , pops the tag
 stack up to but * not * including the most recent instqance of
 the given tag ."""

implementation:
# print " Popping to % s " % name
if name == self . ROOT_TAG_NAME :
    return
numPops = 0
mostRecentTag = None
for i in range ( len ( self . tagStack ) - 1 , 0 , - 1 ) :
    if name == self . tagStack [ i ] . name :
        numPops = len ( self . tagStack ) - i
        break
if not inclusivePop :
    numPops = numPops - 1
for i in range ( 0 , numPops ) :
    mostRecentTag = self . popTag ( )
return mostRecentTag


signature:
def _toStringSubclass ( self , text , subclass ) :
    """Adds a certain piece of text to the tree as a NavigableString
 subclass ."""

implementation:
self . endData ( )
self . handle_data ( text )
self . endData ( subclass )


signature:
def handle_pi ( self , text ) :
    """Handle a processing instruction as a ProcessingInstruction
 object , possibly one with a % SOUP - ENCODING % slot into which an
 encoding will be plugged later ."""

implementation:
if text [ : 3 ] == "xml" :
    text = u"xml version='1.0' encoding='%SOUP-ENCODING%'"
self . _toStringSubclass ( text , ProcessingInstruction )


signature:
def handle_charref ( self , ref ) :
    "Handle character references as data ."

implementation:
if self . convertEntities :
    data = unichr ( int ( ref ) )
else :
    data = '&#%s;' % ref
self . handle_data ( data )


signature:
def handle_entityref ( self , ref ) :
    """Handle entity references as data , possibly converting known
 HTML and / or XML entity references to the corresponding Unicode
 characters ."""

implementation:
data = None
if self . convertHTMLEntities :
    try :
        data = unichr ( name2codepoint [ ref ] )
    except KeyError :
        pass
if not data and self . convertXMLEntities :
    data = self . XML_ENTITIES_TO_SPECIAL_CHARS . get ( ref )
if not data and self . convertHTMLEntities and not self . XML_ENTITIES_TO_SPECIAL_CHARS . get ( ref ) : # TODO : We ' ve got a problem here . We ' re told this is
# an entity reference , but it ' s not an XML entity
# reference or an HTML entity reference . Nonetheless ,
# the logical thing to do is to pass it through as an
# unrecognized entity reference .
# Except : when the input is " & carol ; " this function
# will be called with input " carol " . When the input is
# " AT & T " , this function will be called with input
# " T " . We have no way of knowing whether a semicolon
# was present originally , so we don ' t know whether
# this is an unknown entity or just a misplaced
# ampersand .
# The more common case is a misplaced ampersand , so I
# escape the ampersand and omit the trailing semicolon .
    data = "&%s" % ref
if not data : # This case is different from the one above , because we
# haven ' t already gone through a supposedly comprehensive
# mapping of entities to Unicode characters . We might not
# have gone through any mapping at all . So the chances are
# very high that this is a real entity , and not a
# misplaced ampersand .
    data = "&%s;" % ref
self . handle_data ( data )


signature:
def parse_declaration ( self , i ) :
    """Treat a bogus SGML declaration as raw data . Treat a CDATA
 declaration as a CData object ."""

implementation:
j = None
if self . rawdata [ i : i + 9 ] == '<![CDATA[' :
    k = self . rawdata . find ( ']]>' , i )
    if k == - 1 :
        k = len ( self . rawdata )
    data = self . rawdata [ i + 9 : k ]
    j = k + 3
    self . _toStringSubclass ( data , CData )
else :
    try :
        j = SGMLParser . parse_declaration ( self , i )
    except SGMLParseError :
        toHandle = self . rawdata [ i : ]
        self . handle_data ( toHandle )
        j = i + len ( toHandle )
return j


signature:
def start_meta ( self , attrs ) :
    """Beautiful Soup can detect a charset included in a META tag ,
 try to convert the document to that charset , and re - parse the
 document from the beginning ."""

implementation:
httpEquiv = None
contentType = None
contentTypeIndex = None
tagNeedsEncodingSubstitution = False
for i in range ( 0 , len ( attrs ) ) :
    key , value = attrs [ i ]
    key = key . lower ( )
    if key == 'http-equiv' :
        httpEquiv = value
    elif key == 'content' :
        contentType = value
        contentTypeIndex = i
if httpEquiv and contentType : # It ' s an interesting meta tag .
    match = self . CHARSET_RE . search ( contentType )
    if match :
        if ( self . declaredHTMLEncoding is not None or self . originalEncoding == self . fromEncoding ) : # An HTML encoding was sniffed while converting
        # the document to Unicode , or an HTML encoding was
        # sniffed during a previous pass through the
        # document , or an encoding was specified
        # explicitly and it worked . Rewrite the meta tag .
            def rewrite ( match ) :
                return match . group ( 1 ) + "%SOUP-ENCODING%"
            newAttr = self . CHARSET_RE . sub ( rewrite , contentType )
            attrs [ contentTypeIndex ] = ( attrs [ contentTypeIndex ] [ 0 ] , newAttr )
            tagNeedsEncodingSubstitution = True
        else : # This is our first pass through the document .
        # Go through it again with the encoding information .
            newCharset = match . group ( 3 )
            if newCharset and newCharset != self . originalEncoding :
                self . declaredHTMLEncoding = newCharset
                self . _feed ( self . declaredHTMLEncoding )
                raise StopParsing
            pass
tag = self . unknown_starttag ( "meta" , attrs )
if tag and tagNeedsEncodingSubstitution :
    tag . containsSubstitutions = True


signature:
def _subMSChar ( self , orig ) :
    """Changes a MS smart quote character to an XML or HTML
 entity ."""

implementation:
sub = self . MS_CHARS . get ( orig )
if type ( sub ) == types . TupleType :
    if self . smartQuotesTo == 'xml' :
        sub = '&#x%s;' % sub [ 1 ]
    else :
        sub = '&%s;' % sub [ 0 ]
return sub


signature:
def _toUnicode ( self , data , encoding ) :
    '''Given a string and its encoding , decodes the string into Unicode .
 % encoding is a string recognized by encodings . aliases'''

implementation:
# strip Byte Order Mark ( if present )
if ( len ( data ) >= 4 ) and ( data [ : 2 ] == '\xfe\xff' ) and ( data [ 2 : 4 ] != '\x00\x00' ) :
    encoding = 'utf-16be'
    data = data [ 2 : ]
elif ( len ( data ) >= 4 ) and ( data [ : 2 ] == '\xff\xfe' ) and ( data [ 2 : 4 ] != '\x00\x00' ) :
    encoding = 'utf-16le'
    data = data [ 2 : ]
elif data [ : 3 ] == '\xef\xbb\xbf' :
    encoding = 'utf-8'
    data = data [ 3 : ]
elif data [ : 4 ] == '\x00\x00\xfe\xff' :
    encoding = 'utf-32be'
    data = data [ 4 : ]
elif data [ : 4 ] == '\xff\xfe\x00\x00' :
    encoding = 'utf-32le'
    data = data [ 4 : ]
newdata = unicode ( data , encoding )
return newdata


signature:
def _detectEncoding ( self , xml_data , isHTML = False ) :
    """Given a document , tries to detect its XML encoding ."""

implementation:
xml_encoding = sniffed_xml_encoding = None
try :
    if xml_data [ : 4 ] == '\x4c\x6f\xa7\x94' : # EBCDIC
        xml_data = self . _ebcdic_to_ascii ( xml_data )
    elif xml_data [ : 4 ] == '\x00\x3c\x00\x3f' : # UTF - 16BE
        sniffed_xml_encoding = 'utf-16be'
        xml_data = unicode ( xml_data , 'utf-16be' ) . encode ( 'utf-8' )
    elif ( len ( xml_data ) >= 4 ) and ( xml_data [ : 2 ] == '\xfe\xff' ) and ( xml_data [ 2 : 4 ] != '\x00\x00' ) : # UTF - 16BE with BOM
        sniffed_xml_encoding = 'utf-16be'
        xml_data = unicode ( xml_data [ 2 : ] , 'utf-16be' ) . encode ( 'utf-8' )
    elif xml_data [ : 4 ] == '\x3c\x00\x3f\x00' : # UTF - 16LE
        sniffed_xml_encoding = 'utf-16le'
        xml_data = unicode ( xml_data , 'utf-16le' ) . encode ( 'utf-8' )
    elif ( len ( xml_data ) >= 4 ) and ( xml_data [ : 2 ] == '\xff\xfe' ) and ( xml_data [ 2 : 4 ] != '\x00\x00' ) : # UTF - 16LE with BOM
        sniffed_xml_encoding = 'utf-16le'
        xml_data = unicode ( xml_data [ 2 : ] , 'utf-16le' ) . encode ( 'utf-8' )
    elif xml_data [ : 4 ] == '\x00\x00\x00\x3c' : # UTF - 32BE
        sniffed_xml_encoding = 'utf-32be'
        xml_data = unicode ( xml_data , 'utf-32be' ) . encode ( 'utf-8' )
    elif xml_data [ : 4 ] == '\x3c\x00\x00\x00' : # UTF - 32LE
        sniffed_xml_encoding = 'utf-32le'
        xml_data = unicode ( xml_data , 'utf-32le' ) . encode ( 'utf-8' )
    elif xml_data [ : 4 ] == '\x00\x00\xfe\xff' : # UTF - 32BE with BOM
        sniffed_xml_encoding = 'utf-32be'
        xml_data = unicode ( xml_data [ 4 : ] , 'utf-32be' ) . encode ( 'utf-8' )
    elif xml_data [ : 4 ] == '\xff\xfe\x00\x00' : # UTF - 32LE with BOM
        sniffed_xml_encoding = 'utf-32le'
        xml_data = unicode ( xml_data [ 4 : ] , 'utf-32le' ) . encode ( 'utf-8' )
    elif xml_data [ : 3 ] == '\xef\xbb\xbf' : # UTF - 8 with BOM
        sniffed_xml_encoding = 'utf-8'
        xml_data = unicode ( xml_data [ 3 : ] , 'utf-8' ) . encode ( 'utf-8' )
    else :
        sniffed_xml_encoding = 'ascii'
        pass
except :
    xml_encoding_match = None
xml_encoding_match = re . compile ( '^<\?.*encoding=[\'"](.*?)[\'"].*\?>' ) . match ( xml_data )
if not xml_encoding_match and isHTML :
    regexp = re . compile ( '<\s*meta[^>]+charset=([^>]*?)[;\'">]' , re . I )
    xml_encoding_match = regexp . search ( xml_data )
if xml_encoding_match is not None :
    xml_encoding = xml_encoding_match . groups ( ) [ 0 ] . lower ( )
    if isHTML :
        self . declaredHTMLEncoding = xml_encoding
    if sniffed_xml_encoding and ( xml_encoding in ( 'iso-10646-ucs-2' , 'ucs-2' , 'csunicode' , 'iso-10646-ucs-4' , 'ucs-4' , 'csucs4' , 'utf-16' , 'utf-32' , 'utf_16' , 'utf_32' , 'utf16' , 'u16' ) ) :
        xml_encoding = sniffed_xml_encoding
return xml_data , xml_encoding , sniffed_xml_encoding


signature:
def shoebot_example ( ** shoebot_kwargs ) :
    """Decorator to run some code in a bot instance ."""

implementation:
def decorator ( f ) :
    def run ( ) :
        from shoebot import ShoebotInstallError
        # https : / / github . com / shoebot / shoebot / issues / 206
        print ( "    Shoebot - %s:" % f . __name__ . replace ( "_" , " " ) )
        try :
            import shoebot
            outputfile = "/tmp/shoebot-%s.png" % f . __name__
            bot = shoebot . create_bot ( outputfile = outputfile )
            f ( bot )
            bot . finish ( )
            print ( '        [passed] : %s' % outputfile )
            print ( '' )
        except ShoebotInstallError as e :
            print ( '        [failed]' , e . args [ 0 ] )
            print ( '' )
        except Exception :
            print ( '        [failed] - traceback:' )
            for line in traceback . format_exc ( ) . splitlines ( ) :
                print ( '    %s' % line )
            print ( '' )
    return run
return decorator


signature:
def _get_center ( self ) :
    '''Returns the center point of the path , disregarding transforms .'''

implementation:
x = ( self . x + self . width / 2 )
y = ( self . y + self . height / 2 )
return ( x , y )


signature:
def scale_context_and_center ( self , cr ) :
    """Scale context based on difference between bot size and widget"""

implementation:
bot_width , bot_height = self . bot_size
if self . width != bot_width or self . height != bot_height : # Scale up by largest dimension
    if self . width < self . height :
        scale_x = float ( self . width ) / float ( bot_width )
        scale_y = scale_x
        cr . translate ( 0 , ( self . height - ( bot_height * scale_y ) ) / 2.0 )
    elif self . width > self . height :
        scale_y = float ( self . height ) / float ( bot_height )
        scale_x = scale_y
        cr . translate ( ( self . width - ( bot_width * scale_x ) ) / 2.0 , 0 )
    else :
        scale_x = 1.0
        scale_y = 1.0
    cr . scale ( scale_x , scale_y )
    self . input_device . scale_x = scale_y
    self . input_device . scale_y = scale_y


signature:
def draw ( self , widget , cr ) :
    '''Draw just the exposed part of the backing store , scaled to fit'''

implementation:
if self . bot_size is None : # No bot to draw yet .
    self . draw_default_image ( cr )
    return
cr = driver . ensure_pycairo_context ( cr )
surface = self . backing_store . surface
cr . set_source_surface ( surface )
cr . paint ( )


signature:
def create_rcontext ( self , size , frame ) :
    '''Creates a recording surface for the bot to draw on
 : param size : The width and height of bot'''

implementation:
self . frame = frame
width , height = size
meta_surface = cairo . RecordingSurface ( cairo . CONTENT_COLOR_ALPHA , ( 0 , 0 , width , height ) )
ctx = cairo . Context ( meta_surface )
return ctx


signature:
def do_drawing ( self , size , frame , cairo_ctx ) :
    '''Update the backing store from a cairo context and
 schedule a redraw ( expose event )
 : param size : width , height in pixels of bot
 : param frame : frame # thar was drawn
 : param cairo _ ctx : cairo context the bot was drawn on'''

implementation:
if self . get_window ( ) and not self . bot_size : # Get initial size for window
    self . set_size_request ( * size )
self . bot_size = size
self . backing_store = BackingStore . get_backingstore ( self . width , self . height )
cr = pycairo . Context ( self . backing_store . surface )
if self . scale_fit :
    self . scale_context_and_center ( cr )
cairo_ctx = driver . ensure_pycairo_context ( cairo_ctx )
cr . set_source_surface ( cairo_ctx . get_target ( ) )
# Create the cairo context
cr . set_operator ( cairo . OPERATOR_SOURCE )
cr . paint ( )
self . queue_draw ( )
while Gtk . events_pending ( ) :
    Gtk . main_iteration_do ( False )


signature:
def encode ( self , o ) :
    """Return a JSON string representation of a Python data structure .
 > > > JSONEncoder ( ) . encode ( { " foo " : [ " bar " , " baz " ] } )
 ' { " foo " : [ " bar " , " baz " ] } '"""

implementation:
# This is for extremely simple cases and benchmarks .
if isinstance ( o , basestring ) :
    if isinstance ( o , str ) :
        _encoding = self . encoding
        if ( _encoding is not None and not ( _encoding == 'utf-8' ) ) :
            o = o . decode ( _encoding )
    if self . ensure_ascii :
        return encode_basestring_ascii ( o )
    else :
        return encode_basestring ( o )
# This doesn ' t pass the iterator directly to ' ' . join ( ) because the
# exceptions aren ' t as detailed . The list call should be roughly
# equivalent to the PySequence _ Fast that ' ' . join ( ) would do .
chunks = list ( self . iterencode ( o ) )
return '' . join ( chunks )


signature:
def iterencode ( self , o ) :
    """Encode the given object and yield each string
 representation as available .
 For example : :
 for chunk in JSONEncoder ( ) . iterencode ( bigobject ) :
 mysocket . write ( chunk )"""

implementation:
if self . check_circular :
    markers = { }
else :
    markers = None
return self . _iterencode ( o , markers )


signature:
def get_key_map ( self ) :
    '''Return a dict in the form of
 SHOEBOT _ KEY _ NAME , GTK _ VALUE
 Shoebot key names look like KEY _ LEFT , whereas Gdk uses KEY _ Left
 - Shoebot key names are derived from Nodebox 1 , which was a mac
 app .'''

implementation:
kdict = { }
for gdk_name in dir ( Gdk ) :
    nb_name = gdk_name . upper ( )
    kdict [ nb_name ] = getattr ( Gdk , gdk_name )
return kdict


signature:
def _grow ( self , generation , rule , angle , length , time = maxint , draw = True ) :
    """Recurse through the system .
 When a segment is drawn , the LSsytem . segment ( ) method will be called .
 You can customize this method to create your own visualizations .
 It takes an optional time parameter .
 If you divide this parameter by LSsytem . duration ( ) you get
 a number between 0.0 and 1.0 you can use as an alpha value for example .
 The method also has an id parameter which is a unique number
 between 0 and LSystem . segments ."""

implementation:
if generation == 0 : # We are at the bottom of the system so now we now the total time needed .
    self . _duration = 1 + maxint - time
if length <= self . threshold : # Segment length has fallen below the threshold , stop recursing .
    self . _duration = 1 + maxint - time
    return
if rule in self . commands : # Custom command symbols :
# If the rule is a key in the LSsytem . commands dictionary ,
# execute its value which is a function taking 6 parameters :
# lsystem , generation , rule , angle , length and time .
    self . commands [ rule ] ( self , generation , rule , angle , length , time )
if draw : # Standard command symbols :
# f signifies a move ,
# + and - rotate either left or right , | rotates 180 degrees ,
# [ and ] are for push ( ) and pop ( ) , e . g . offshoot branches ,
# < and > decrease or increases the segment length ,
# ( and ) decrease or increases the rotation angle .
    if rule == "f" :
        _ctx . translate ( 0 , - min ( length , length * time ) )
    elif rule == "-" :
        _ctx . rotate ( max ( - angle , - angle * time ) )
    elif rule == "+" :
        _ctx . rotate ( min ( + angle , + angle * time ) )
    elif rule == "|" :
        _ctx . rotate ( 180 )
    elif rule == "[" :
        _ctx . push ( )
    elif rule == "]" :
        _ctx . pop ( )
if rule in self . rules and generation > 0 and time > 0 : # Recursion :
# Occurs when there is enough " life " ( i . e . generation or time ) .
# Generation is decreased and segment length scaled down .
# Also , F symbols in the rule have a cost that depletes time .
    for cmd in self . rules [ rule ] : # Modification command symbols :
        if cmd == "F" :
            time -= self . cost
        elif cmd == "!" :
            angle = - angle
        elif cmd == "(" :
            angle *= 1.1
        elif cmd == ")" :
            angle *= 0.9
        elif cmd == "<" :
            length *= 0.9
        elif cmd == ">" :
            length *= 1.1
        self . _grow ( generation - 1 , cmd , angle , length * self . decrease , time , draw )
elif rule == "F" or ( rule in self . rules and self . rules [ rule ] == "" ) : # Draw segment :
# If the rule is an F symbol or empty ( e . g . in Penrose tiles ) .
# Segment length grows to its full size as time progresses .
    self . _segments += 1
    if draw and time > 0 :
        length = min ( length , length * time )
        if self . _timed :
            self . segment ( length , generation , time , id = self . _segments )
    else :
        self . segment ( length , generation , None , id = self . _segments )
        _ctx . translate ( 0 , - length )


signature:
def _output_file ( self , frame ) :
    """If filename was used output a filename , along with multifile
 numbered filenames will be used .
 If buff was specified it is returned .
 : return : Output buff or filename ."""

implementation:
if self . buff :
    return self . buff
elif self . multifile :
    return self . file_root + "_%03d" % frame + self . file_ext
else :
    return self . filename


signature:
def create_rcontext ( self , size , frame ) :
    """Called when CairoCanvas needs a cairo context to draw on"""

implementation:
if self . format == 'pdf' :
    surface = cairo . PDFSurface ( self . _output_file ( frame ) , * size )
elif self . format in ( 'ps' , 'eps' ) :
    surface = cairo . PSSurface ( self . _output_file ( frame ) , * size )
elif self . format == 'svg' :
    surface = cairo . SVGSurface ( self . _output_file ( frame ) , * size )
elif self . format == 'surface' :
    surface = self . target
else :
    surface = cairo . ImageSurface ( cairo . FORMAT_ARGB32 , * size )
return cairo . Context ( surface )


signature:
def rendering_finished ( self , size , frame , cairo_ctx ) :
    """Called when CairoCanvas has rendered a bot"""

implementation:
surface = cairo_ctx . get_target ( )
if self . format == 'png' :
    surface . write_to_png ( self . _output_file ( frame ) )
surface . finish ( )
surface . flush ( )


signature:
def output_closure ( self , target , file_number = None ) :
    '''Function to output to a cairo surface
 target is a cairo Context or filename
 if file _ number is set , then files will be numbered
 ( this is usually set to the current frame number )'''

implementation:
def output_context ( ctx ) :
    target_ctx = target
    target_ctx . set_source_surface ( ctx . get_target ( ) )
    target_ctx . paint ( )
    return target_ctx
def output_surface ( ctx ) :
    target_ctx = cairo . Context ( target )
    target_ctx . set_source_surface ( ctx . get_target ( ) )
    target_ctx . paint ( )
    return target_ctx
def output_file ( ctx ) :
    root , extension = os . path . splitext ( target )
    if file_number :
        filename = '%s_%04d%s' % ( root , file_number , extension )
    else :
        filename = target
    extension = extension . lower ( )
    if extension == '.png' :
        surface = ctx . get_target ( )
        surface . write_to_png ( target )
    elif extension == '.pdf' :
        target_ctx = cairo . Context ( cairo . PDFSurface ( filename , * self . size_or_default ( ) ) )
        target_ctx . set_source_surface ( ctx . get_target ( ) )
        target_ctx . paint ( )
    elif extension in ( '.ps' , '.eps' ) :
        target_ctx = cairo . Context ( cairo . PSSurface ( filename , * self . size_or_default ( ) ) )
        if extension == '.eps' :
            target_ctx . set_eps ( extension = '.eps' )
        target_ctx . set_source_surface ( ctx . get_target ( ) )
        target_ctx . paint ( )
    elif extension == '.svg' :
        target_ctx = cairo . Context ( cairo . SVGSurface ( filename , * self . size_or_default ( ) ) )
        target_ctx . set_source_surface ( ctx . get_target ( ) )
        target_ctx . paint ( )
    return filename
if isinstance ( target , cairo . Context ) :
    return output_context
elif isinstance ( target , cairo . Surface ) :
    return output_surface
else :
    return output_file