def merge_ranges(ranges):
    """Merge short, fragmental ranges into long, continuous ones.

    Parameters
    ----------
    ranges : list of int
        Ranges to merge.

    Returns
    -------
    list of int
        Merged ranges.

    Notes
    -----
    Ranges that have overlaps will be merged into one. For example:

    >>> merge_ranges([1, 3, 2, 4, 6, 8, 7, 9])
    [1, 4, 6, 9]
    """
    res = []
    res_extend = res.extend
    cstart, cend = None, None
    for start, end in sorted(zip(*[iter(ranges)] * 2)):
        if cend is None:
            # case 1: no active range, start active range
            cstart, cend = start, end
        elif cend >= start - 1:
            # case 2: active range continues through this range
            # extend active range
            cend = max(cend, end)
        else:
            # case 3: active range ends before this range begins
            # write new range out, then start new active range
            res_extend((cstart, cend))
            cstart, cend = start, end
    if cend is not None:
        res_extend((cstart, cend))
    return res