Converts a list of ``regions.Shape`` objects to ds9 region strings.

        Parameters
        ----------
        coordsys : str
            This overrides the coordinate system frame for all regions.
        fmt : str
            A python string format defining the output precision.
            Default is .6f, which is accurate to 0.0036 arcseconds.
        radunit : str
            This denotes the unit of the radius.

        Returns
        -------
        region_string : str
            ds9 region string

        Examples
        --------
        TODO

def to_ds9(self, coordsys='fk5', fmt='.6f', radunit='deg'):
        """
        Converts a list of ``regions.Shape`` objects to ds9 region strings.

        Parameters
        ----------
        coordsys : str
            This overrides the coordinate system frame for all regions.
        fmt : str
            A python string format defining the output precision.
            Default is .6f, which is accurate to 0.0036 arcseconds.
        radunit : str
            This denotes the unit of the radius.

        Returns
        -------
        region_string : str
            ds9 region string

        Examples
        --------
        TODO
        """
        valid_symbols_reverse = {y: x for x, y in valid_symbols_ds9.items()}

        ds9_strings = {
            'circle': '{0}circle({1:FMT},{2:FMT},{3:FMT}RAD)',
            'circleannulus': '{0}annulus({1:FMT},{2:FMT},{3:FMT}RAD,{4:FMT}RAD)',
            'ellipse': '{0}ellipse({1:FMT},{2:FMT},{3:FMT}RAD,{4:FMT}RAD,{5:FMT})',
            'rectangle': '{0}box({1:FMT},{2:FMT},{3:FMT}RAD,{4:FMT}RAD,{5:FMT})',
            'polygon': '{0}polygon({1})',
            'point': '{0}point({1:FMT},{2:FMT})',
            'line': '{0}line({1:FMT},{2:FMT},{3:FMT},{4:FMT})',
            'text': '{0}text({1:FMT},{2:FMT})'
                      }

        output = '# Region file format: DS9 astropy/regions\n'

        if radunit == 'arcsec':
            # what's this for?
            if coordsys in coordsys_mapping['DS9'].values():
                radunitstr = '"'
            else:
                raise ValueError('Radius unit arcsec not valid for coordsys {}'.format(coordsys))
        else:
            radunitstr = ''

        for key, val in ds9_strings.items():
            ds9_strings[key] = val.replace("FMT", fmt).replace("RAD", radunitstr)

        output += '{}\n'.format(coordsys)

        for shape in self:

            shape.check_ds9()
            shape.meta = to_ds9_meta(shape.meta)

            # if unspecified, include is True.
            include = "-" if shape.include in (False, '-') else ""

            if 'point' in shape.meta:
                shape.meta['point'] = valid_symbols_reverse[shape.meta['point']]

            if 'symsize' in shape.meta:
                shape.meta['point'] += " {}".format(shape.meta.pop('symsize'))

            meta_str = " ".join("{0}={1}".format(key, val) for key, val in
                                shape.meta.items() if key not in ('include', 'tag', 'comment', 'font', 'text'))
            if 'tag' in shape.meta:
                meta_str += " " + " ".join(["tag={0}".format(tag) for tag in shape.meta['tag']])
            if 'font' in shape.meta:
                meta_str += " " + 'font="{0}"'.format(shape.meta['font'])
            if shape.meta.get('text', '') != '':
                meta_str += " " + 'text={' + shape.meta['text'] + '}'
            if 'comment' in shape.meta:
                meta_str += " " + shape.meta['comment']

            coord = []

            if coordsys not in ['image', 'physical']:
                for val in shape.coord:
                    if isinstance(val, Angle):
                        coord.append(float(val.value))
                    else:
                        if radunit == '' or None:
                            coord.append(float(val.value))
                        else:
                            coord.append(float(val.to(radunit).value))
                if shape.region_type in ['ellipse', 'rectangle'] and len(shape.coord) % 2 == 1:
                    coord[-1] = float(shape.coord[-1].to('deg').value)
            else:
                for val in shape.coord:
                    if isinstance(val, u.Quantity):
                        coord.append(float(val.value))
                    else:
                        coord.append(float(val))
                if shape.region_type in ['polygon', 'line']:
                    coord = [x+1 for x in coord]
                else:
                    coord[0] += 1
                    coord[1] += 1

            if shape.region_type == 'polygon':
                val = "{0:" + fmt + "}"
                temp = [val.format(x) for x in coord]
                coord = ",".join(temp)
                line = ds9_strings['polygon'].format(include, coord)
            elif shape.region_type == 'ellipse':
                coord[2:] = [x / 2 for x in coord[2:]]
                if len(coord) % 2 == 1:
                    coord[-1] *= 2
                line = ds9_strings['ellipse'].format(include, *coord)
            else:
                line = ds9_strings[shape.region_type].format(include, *coord)

            if meta_str.strip():
                output += "{0} # {1}\n".format(line, meta_str)
            else:
                output += "{0}\n".format(line)

        return output