import re


def extract_initials(names):
    """Extract a list of initials from names.

    Parameters
    ----------
    names : str or list of str
        Names (in one long string, or divided into elements of a list) from
        which to extract initials. Each name in names can be a full name or
        initial. In each string, the names can be separated by whitespace or
        artibrary numbers of dots and commas (possibly surrounded by
        whitespace). Hyphenated names are also valid (hyphens may not be
        surrounded by whitespace). If a hyphenated name is used, the hypen is
        retained e.g. 'Smith-Jones' becomes 'S-J'.

    Returns
    -------
    initials : list
        List of initials of names in the given `names`.
    """
    initials = []
    try:
        names = names.split()
    except AttributeError:
        try:
            names = ' '.join(names).split()
        except AttributeError:
            raise ValueError('Invalid `names`. Please supply either a str or '
                             'list of str.')
    for name in names:
        name = re.sub(r'^[.,]+|[.,]+$', '', name)
        if name == '':
            # name contained only dots or commas
            continue
        # If names are separated by dots only (no whitespace)
        if '.' in name:
            name = ' '.join(name.split('.'))
            initials += extract_initials(name)
        elif ',' in name:
            name = ' '.join(name.split(','))
            initials += extract_initials(name)
        # If names are hyphenated
        elif '-' in name:
            subnames = name.split('-')
            try:
                initial = '-'.join([name[0].upper() for name in subnames])
            except IndexError:
                raise ValueError('Invalid hypenation in `names`.')
            initials.append(initial)
        else:
            initial = name[0].upper()
            initials.append(initial)
    return initials