Convert file extension(s) to normalized form, e.g. '.tgz' -> '.tar.gz'

    Normalized extensions are ordered in reverse order of how they should be processed.
    Also extensions are ordered in order of decreasing specificity/detail.
    e.g. zip last, then txt/bin, then model type, then model dimensionality

    .TGZ => .tar.gz
    .ZIP => .zip
    .tgz => .tar.gz
    .bin.gz => .w2v.bin.gz
    .6B.zip => .6B.glove.txt.zip
    .27B.zip => .27B.glove.txt.zip
    .42B.300d.zip => .42B.300d.glove.txt.zip
    .840B.300d.zip => .840B.300d.glove.txt.zip

    FIXME: Don't do this! Stick with the original file names and let the text loader figure out what it is!
    TODO: use regexes to be more general (deal with .300D and .42B extensions)

    >>> normalize_ext('glove.42B.300d.zip')
    'glove.42B.300d.glove.txt.zip'

def normalize_ext(filepath):
    """ Convert file extension(s) to normalized form, e.g. '.tgz' -> '.tar.gz'

    Normalized extensions are ordered in reverse order of how they should be processed.
    Also extensions are ordered in order of decreasing specificity/detail.
    e.g. zip last, then txt/bin, then model type, then model dimensionality

    .TGZ => .tar.gz
    .ZIP => .zip
    .tgz => .tar.gz
    .bin.gz => .w2v.bin.gz
    .6B.zip => .6B.glove.txt.zip
    .27B.zip => .27B.glove.txt.zip
    .42B.300d.zip => .42B.300d.glove.txt.zip
    .840B.300d.zip => .840B.300d.glove.txt.zip

    FIXME: Don't do this! Stick with the original file names and let the text loader figure out what it is!
    TODO: use regexes to be more general (deal with .300D and .42B extensions)

    >>> normalize_ext('glove.42B.300d.zip')
    'glove.42B.300d.glove.txt.zip'
    """
    mapping = tuple(reversed((
        ('.tgz', '.tar.gz'),
        ('.bin.gz', '.w2v.bin.gz'),
        ('.6B.zip', '.6b.glove.txt.zip'),
        ('.42B.zip', '.42b.glove.txt.zip'),
        ('.27B.zip', '.27b.glove.txt.zip'),
        ('.300d.zip', '.300d.glove.txt.zip'),
    )))
    if not isinstance(filepath, str):
        return [normalize_ext(fp) for fp in filepath]
    if '~' == filepath[0] or '$' in filepath:
        filepath = expand_filepath(filepath)
    fplower = filepath.lower()
    for ext, newext in mapping:
        r = ext.lower().replace('.', r'\.') + r'$'
        r = r'^[.]?([^.]*)\.([^.]{1,10})*' + r
        if re.match(r, fplower) and not fplower.endswith(newext):
            filepath = filepath[:-len(ext)] + newext
    return filepath