def smart_truncate(string, max_length=0, word_boundary=False, separator=' ', save_order=False):
    """
    Truncate a string.
    :param string (str): string for modification
    :param max_length (int): output string length
    :param word_boundary (bool):
    :param save_order (bool): if True then word order of output string is like input string
    :param separator (str): separator between words
    :return:
    """

    string = string.strip(separator)

    if not max_length:
        return string

    if len(string) < max_length:
        return string

    if not word_boundary:
        return string[:max_length].strip(separator)

    if separator not in string:
        return string[:max_length]

    truncated = ''
    for word in string.split(separator):
        if word:
            next_len = len(truncated) + len(word)
            if next_len < max_length:
                truncated += '{0}{1}'.format(word, separator)
            elif next_len == max_length:
                truncated += '{0}'.format(word)
                break
            else:
                if save_order:
                    break
    if not truncated: # pragma: no cover
        truncated = string[:max_length]
    return truncated.strip(separator)
def smart_truncate(string, max_length=0, word_boundary=False, separator=' ', save_order=False):
    """
    Truncate a string.
    :param string (str): string for modification
    :param max_length (int): output string length
    :param word_boundary (bool):
    :param save_order (bool): if True then word order of output string is like input string
    :param separator (str): separator between words
    :return:
    """

    string = string.strip(separator)

    if not max_length:
        return string

    if len(string) < max_length:
        return string

    if not word_boundary:
        return string[:max_length].strip(separator)

    if separator not in string:
        return string[:max_length]

    truncated = ''
    for word in string.split(separator):
        if word:
            next_len = len(truncated) + len(word)
            if next_len < max_length:
                truncated += '{0}{1}'.format(word, separator)
            elif next_len == max_length:
                truncated += '{0}'.format(word)
                break
            else:
                if save_order:
                    break
    if not truncated: # pragma: no cover
        truncated = string[:max_length]
    return truncated.strip(separator)
def smart_truncate ( string , max_length = 0 , word_boundary = False , separator = ' ' , save_order = False ) : string = string . strip ( separator ) if not max_length : return string if len ( string ) < max_length : return string if not word_boundary : return string [ : max_length ] . strip ( separator ) if separator not in string : return string [ : max_length ] truncated = '' for word in string . split ( separator ) : if word : next_len = len ( truncated ) + len ( word ) if next_len < max_length : truncated += '{0}{1}' . format ( word , separator ) elif next_len == max_length : truncated += '{0}' . format ( word ) break else : if save_order : break if not truncated : # pragma: no cover truncated = string [ : max_length ] return truncated . strip ( separator )
Truncate a string.
    :param string (str): string for modification
    :param max_length (int): output string length
    :param word_boundary (bool):
    :param save_order (bool): if True then word order of output string is like input string
    :param separator (str): separator between words
    :return:
Truncate a string . : param string ( str ) : string for modification : param max_length ( int ) : output string length : param word_boundary ( bool ) : : param save_order ( bool ) : if True then word order of output string is like input string : param separator ( str ) : separator between words : return :