def string_formatter_factory(format_str, format_mapper):
    """
    Meta formatter : a formater based on other formater

    Parameters
    ----------
    format_str : str
        The formatting string with place holder to be replaced.
    format_mapper : dict
        The dictionary containing the mapping placeholder - formatter

    Return
    ------
    :func:`format_string_formatter`
    """

    def format_string_formatter(task, exception=None):
        """
        Meta formatter

        Return
        ------
        string : str
            The formatted result

        Example
        -------
        format_str = {$thread} {$task} {$progressbar} {$time} {$exception}

        Thread 'MainThread' (id=140735231197952) Task # 0: Lengthy 
        [=========> ] 97.06% elapsed time: 10.18s 
        remaining time (estimation): 0.56s total time (estimation): 10.74s 
        """
        val_dict = dict()
        for name, str_formatter in format_mapper.iteritems():
            val_dict[name] = str_formatter(task, exception)
        return format_str.format(**val_dict)

    return format_string_formatter