Replace links to different parts of the program, formatted as
    [[name]] or [[name(object-type)]] with the appropriate URL. Can also
    link to an item's entry in another's page with the syntax
    [[parent-name:name]]. The object type can be placed in parentheses
    for either or both of these parts.

def sub_links(string,project):
    '''
    Replace links to different parts of the program, formatted as
    [[name]] or [[name(object-type)]] with the appropriate URL. Can also
    link to an item's entry in another's page with the syntax
    [[parent-name:name]]. The object type can be placed in parentheses
    for either or both of these parts.
    '''
    LINK_TYPES    = { 'module': 'modules',
                      'type': 'types',
                      'procedure': 'procedures',
                      'subroutine': 'procedures',
                      'function': 'procedures',
                      'proc': 'procedures',
                      'file': 'allfiles',
                      'interface': 'absinterfaces',
                      'absinterface': 'absinterfaces',
                      'program': 'programs',
                      'block': 'blockdata' }
        
    SUBLINK_TYPES = { 'variable': 'variables',
                      'type': 'types',
                      'constructor': 'constructor',
                      'interface': 'interfaces',
                      'absinterface': 'absinterfaces',
                      'subroutine': 'subroutines',
                      'function': 'functions',
                      'final': 'finalprocs',
                      'bound': 'boundprocs',
                      'modproc': 'modprocs',
                      'common': 'common' }
        
    
    def convert_link(match):
        ERR = 'Warning: Could not substitute link {}. {}'
        url = ''
        name = ''
        found = False
        searchlist = []
        item = None
        
        #[name,obj,subname,subobj]
        if not match.group(2):
            for key, val in LINK_TYPES.items():
                searchlist.extend(getattr(project,val))
        else:
            if match.group(2).lower() in LINK_TYPES:
                searchlist.extend(getattr(project,LINK_TYPES[match.group(2).lower()]))
            else:
                print(ERR.format(match.group(),'Unrecognized classification "{}".'.format(match.group(2))))
                return match.group()
        
        for obj in searchlist:
            if match.group(1).lower() == obj.name.lower():
                url = obj.get_url()
                name = obj.name
                found = True
                item = obj
                break
        else:
            print(ERR.format(match.group(),'"{}" not found.'.format(match.group(1))))
            url = ''
            name = match.group(1)
        
        if found and match.group(3):
            searchlist = []
            if not match.group(4):
                for key, val in SUBLINK_TYPES.items():
                    if val == 'constructor':
                        if getattr(item,'constructor', False):
                            searchlist.append(item.constructor)
                        else:
                            continue
                    else:
                        searchlist.extend(getattr(item,val,[]))
            else:
                if match.group(4).lower() in SUBLINK_TYPES:
                    if hasattr(item,SUBLINK_TYPES[match.group(4).lower()]):
                        if match.group(4).lower == 'constructor':
                            if item.constructor:
                                searchlist.append(item.constructor)
                        else:
                            searchlist.extend(getattr(item,SUBLINK_TYPES[match.group(4).lower()]))
                    else:
                        print(ERR.format(match.group(),'"{}" can not be contained in "{}"'.format(match.group(4),item.obj)))
                        return match.group()
                else:
                    print(ERR.format(match.group(),'Unrecognized classification "{}".'.format(match.group(2))))
                    return match.group()
            
            for obj in searchlist:
                if match.group(3).lower() == obj.name.lower():
                    url = url + '#' + obj.anchor
                    name = obj.name
                    item = obj
                    break
            else:
                print(ERR.format(match.group(),'"{0}" not found in "{1}", linking to page for "{1}" instead.'.format(match.group(3),name)))

        if found:
            return '<a href="{}">{}</a>'.format(url,name)
        else:
            return '<a>{}</a>'.format(name)

    # Get information from links (need to build an RE)
    string = LINK_RE.sub(convert_link,string)
    return string