def format_single_paragraph_sentences(text, debug=False, myprefix=True,
                                      sentence_break=True, max_width=73,
                                      sepcolon=True):
    r"""
    helps me separatate sentences grouped in paragraphs that I have a
    difficult time reading due to dyslexia

    Args:
        text (str):

    Returns:
        str: wrapped_text

    CommandLine:
        python -m utool.util_str --exec-format_single_paragraph_sentences --show
        python -m utool.util_str --exec-format_single_paragraph_sentences --show --nobreak

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.util_str import *  # NOQA
        >>> import utool as ut
        >>> text = '     lorium ipsum doloar dolar dolar dolar erata man foobar is this there yet almost man not quit ate 80 chars yet hold out almost there? dolar erat. sau.ltum. fds.fd... . . fd oob fd. list: (1) abcd, (2) foobar (4) 123456789 123456789 123456789 123456789 123 123 123 123 123456789 123 123 123 123 123456789 123456789 123456789 123456789 123456789 123 123 123 123 123 123456789 123456789 123456789 123456789 123456789 123456789 (3) spam.'
        >>> #text = 'list: (1) abcd, (2) foobar (3) spam.'
        >>> #text = 'foo. when: (1) there is a new individual,'
        >>> #text = 'when: (1) there is a new individual,'
        >>> #text = '? ? . lorium. ipsum? dolar erat. saultum. fds.fd...  fd oob fd. ? '  # causes breakdown
        >>> print('text = %r' % (text,))
        >>> sentence_break = not ut.get_argflag('--nobreak')
        >>> wrapped_text = format_single_paragraph_sentences(text, debug=True, sentence_break=sentence_break)
        >>> result = ('wrapped_text =\n%s' % (str(wrapped_text),))
        >>> print(result)
    """
    import utool as ut
    #ut.util_dbg.COLORED_EXCEPTIONS = False
    import textwrap
    import re
    #ut.rrrr(verbose=False)
    # max_width = 73  # 79  # 80
    debug = _rectify_countdown_or_bool(debug)
    min_indent = ut.get_minimum_indentation(text)
    min_indent = (min_indent // 4) * 4
    if debug:
        print(ut.colorprint(msgblock('preflat', repr(text)), 'darkyellow'))
    text_ = ut.remove_doublspaces(text)
    # TODO: more intelligent sentence parsing
    text_ = ut.flatten_textlines(text)
    if debug:
        print(ut.colorprint(msgblock('postflat', repr(text_)), 'yellow'))

    raw_sep_chars = ['.', '?', '!', ':']
    if not sepcolon:
        raw_sep_chars.remove(':')

    USE_REGEX_SPLIT = True

    def split_sentences(text_):
        # TODO: rectify with split_sentences2
        if not USE_REGEX_SPLIT:
            # Old way that just handled periods
            sentence_list = text_.split('. ')
        else:
            # ******* #
            # SPLITS line endings based on regular expressions.
            esc = re.escape
            # Define separation patterns
            regex_sep_chars = list(map(re.escape, raw_sep_chars))
            regex_sep_prefix = [esc('(') + r'\d' + esc(')')]
            regex_sep_list = regex_sep_chars + regex_sep_prefix
            # Combine into a full regex
            sep_pattern = ut.regex_or(regex_sep_list)
            full_pattern = '(' + sep_pattern + r'+\s)'
            full_regex = re.compile(full_pattern)
            # Make the splits
            num_groups = full_regex.groups  # num groups in the regex
            split_list = re.split(full_pattern, text_)
            if len(split_list) > 0:
                num_bins = num_groups + 1
                sentence_list = split_list[0::num_bins]
                sep_list_group1 = split_list[1::num_bins]
                sep_list = sep_list_group1
            if debug:
                print('<SPLIT DBG>')
                print('num_groups = %r' % (num_groups,))
                print('len(split_list) = %r' % (len(split_list)))
                print('len(split_list) / len(sentence_list) = %r' % (
                    len(split_list) / len(sentence_list)))
                print('len(sentence_list) = %r' % (len(sentence_list),))
                print('len(sep_list_group1) = %r' % (len(sep_list_group1),))
                #print('len(sep_list_group2) = %r' % (len(sep_list_group2),))
                print('full_pattern = %s' % (full_pattern,))
                #print('split_list = %r' % (split_list,))
                print('sentence_list = %s' % (ut.repr2(sentence_list),))
                print('sep_list = %s' % ((sep_list),))
                print('</SPLIT DBG>')
            # ******* #
            return sentence_list, sep_list

    def wrap_sentences(sentence_list, min_indent, max_width):
        # prefix for continuations of a sentence
        if myprefix:
            # helps me read LaTeX
            sentence_prefix = '  '
        else:
            sentence_prefix = ''
        if text_.startswith('>>>'):
            # Hack to do docstrings
            # TODO: make actualy docstring reformater
            sentence_prefix = '...     '

        if max_width is not None:
            width = max_width - min_indent - len(sentence_prefix)

            wrapkw = dict(width=width, break_on_hyphens=False, break_long_words=False)
            #wrapped_lines_list = [textwrap.wrap(sentence_prefix + line, **wrapkw)
            #                      for line in sentence_list]
            wrapped_lines_list = []
            for count, line in enumerate(sentence_list):
                wrapped_lines = textwrap.wrap(line, **wrapkw)
                wrapped_lines = [line_ if count == 0 else sentence_prefix + line_
                                 for count, line_ in enumerate(wrapped_lines)]
                wrapped_lines_list.append(wrapped_lines)

            wrapped_sentences = ['\n'.join(line) for line in wrapped_lines_list]
        else:
            wrapped_sentences = sentence_list[:]
        return wrapped_sentences

    def rewrap_sentences2(sentence_list, sep_list):
        # FIXME: probably where nl error is
        # ******* #
        # put the newline before or after the sep depending on if it is
        # supposed to prefix or suffix the sentence.
        from six.moves import zip_longest
        # FIXME: Place the separators either before or after a sentence
        sentence_list2 = ['']
        _iter = zip_longest(sentence_list, sep_list)
        for count, (sentence, sep) in enumerate(_iter):
            if sep is None:
                sentence_list2[-1] += sentence
                continue
            sepchars = sep.strip()
            if len(sepchars) > 0 and sepchars[0] in raw_sep_chars:
                sentence_list2[-1] += sentence + (sep.strip())
                sentence_list2.append('')
            else:
                # Place before next
                sentence_list2[-1] += sentence
                sentence_list2.append(sep)
        sentence_list2 = [x.strip() for x in sentence_list2 if len(x.strip()) > 0]
        return sentence_list2

    # New way
    #print('last_is_nl = %r' % (last_is_nl,))
    if sentence_break:
        # Break at sentences
        sentence_list, sep_list = split_sentences(text_)
        # FIXME: probably where nl error is
        sentence_list2 = rewrap_sentences2(sentence_list, sep_list)
        wrapped_sentences = wrap_sentences(sentence_list2, min_indent, max_width)
        wrapped_block = '\n'.join(wrapped_sentences)
    else:
        # Break anywhere
        width = max_width - min_indent
        wrapkw = dict(width=width, break_on_hyphens=False,
                      break_long_words=False)
        wrapped_block = '\n'.join(textwrap.wrap(text_, **wrapkw))

        if False:
            # for a one-time purpose
            print('HACKING')
            print('width = {!r}'.format(width))
            # HACK
            words = text_.split(', (')
            lines = []
            line = ''
            for _, w1 in enumerate(words):
                if _ > 0:
                    w1 = '(' + w1 + ', '
                if len(line + w1) > width:
                    line += ''
                    lines.append(line)
                    line = ''
                line += w1
            lines.append(line)
            wrapped_block = '\n'.join(lines)

    # HACK for last nl (seems to only happen if nl follows a seperator)
    last_is_nl = text.endswith('\n') and  not wrapped_block.endswith('\n')
    first_is_nl = len(text) > 1 and text.startswith('\n') and not wrapped_block.startswith('\n')
    # if last_is_nl and wrapped_block.strip().endswith('.'):
    if last_is_nl:
        wrapped_block += '\n'
    if first_is_nl:
        wrapped_block = '\n' + wrapped_block
    # Do the final indentation
    wrapped_text = ut.indent(wrapped_block, ' ' * min_indent)
    return wrapped_text
def format_single_paragraph_sentences ( text , debug = False , myprefix = True , sentence_break = True , max_width = 73 , sepcolon = True ) : import utool as ut import textwrap import re debug = _rectify_countdown_or_bool ( debug ) min_indent = ut . get_minimum_indentation ( text ) min_indent = ( min_indent // 4 ) * 4 if debug : print ( ut . colorprint ( msgblock ( 'preflat' , repr ( text ) ) , 'darkyellow' ) ) text_ = ut . remove_doublspaces ( text ) text_ = ut . flatten_textlines ( text ) if debug : print ( ut . colorprint ( msgblock ( 'postflat' , repr ( text_ ) ) , 'yellow' ) ) raw_sep_chars = [ '.' , '?' , '!' , ':' ] if not sepcolon : raw_sep_chars . remove ( ':' ) USE_REGEX_SPLIT = True def split_sentences ( text_ ) : if not USE_REGEX_SPLIT : sentence_list = text_ . split ( '. ' ) else : esc = re . escape regex_sep_chars = list ( map ( re . escape , raw_sep_chars ) ) regex_sep_prefix = [ esc ( '(' ) + r'\d' + esc ( ')' ) ] regex_sep_list = regex_sep_chars + regex_sep_prefix sep_pattern = ut . regex_or ( regex_sep_list ) full_pattern = '(' + sep_pattern + r'+\s)' full_regex = re . compile ( full_pattern ) num_groups = full_regex . groups split_list = re . split ( full_pattern , text_ ) if len ( split_list ) > 0 : num_bins = num_groups + 1 sentence_list = split_list [ 0 : : num_bins ] sep_list_group1 = split_list [ 1 : : num_bins ] sep_list = sep_list_group1 if debug : print ( '<SPLIT DBG>' ) print ( 'num_groups = %r' % ( num_groups , ) ) print ( 'len(split_list) = %r' % ( len ( split_list ) ) ) print ( 'len(split_list) / len(sentence_list) = %r' % ( len ( split_list ) / len ( sentence_list ) ) ) print ( 'len(sentence_list) = %r' % ( len ( sentence_list ) , ) ) print ( 'len(sep_list_group1) = %r' % ( len ( sep_list_group1 ) , ) ) print ( 'full_pattern = %s' % ( full_pattern , ) ) print ( 'sentence_list = %s' % ( ut . repr2 ( sentence_list ) , ) ) print ( 'sep_list = %s' % ( ( sep_list ) , ) ) print ( '</SPLIT DBG>' ) return sentence_list , sep_list def wrap_sentences ( sentence_list , min_indent , max_width ) : if myprefix : sentence_prefix = '  ' else : sentence_prefix = '' if text_ . startswith ( '>>>' ) : sentence_prefix = '...     ' if max_width is not None : width = max_width - min_indent - len ( sentence_prefix ) wrapkw = dict ( width = width , break_on_hyphens = False , break_long_words = False ) wrapped_lines_list = [ ] for count , line in enumerate ( sentence_list ) : wrapped_lines = textwrap . wrap ( line , ** wrapkw ) wrapped_lines = [ line_ if count == 0 else sentence_prefix + line_ for count , line_ in enumerate ( wrapped_lines ) ] wrapped_lines_list . append ( wrapped_lines ) wrapped_sentences = [ '\n' . join ( line ) for line in wrapped_lines_list ] else : wrapped_sentences = sentence_list [ : ] return wrapped_sentences def rewrap_sentences2 ( sentence_list , sep_list ) : from six . moves import zip_longest sentence_list2 = [ '' ] _iter = zip_longest ( sentence_list , sep_list ) for count , ( sentence , sep ) in enumerate ( _iter ) : if sep is None : sentence_list2 [ - 1 ] += sentence continue sepchars = sep . strip ( ) if len ( sepchars ) > 0 and sepchars [ 0 ] in raw_sep_chars : sentence_list2 [ - 1 ] += sentence + ( sep . strip ( ) ) sentence_list2 . append ( '' ) else : sentence_list2 [ - 1 ] += sentence sentence_list2 . append ( sep ) sentence_list2 = [ x . strip ( ) for x in sentence_list2 if len ( x . strip ( ) ) > 0 ] return sentence_list2 if sentence_break : sentence_list , sep_list = split_sentences ( text_ ) sentence_list2 = rewrap_sentences2 ( sentence_list , sep_list ) wrapped_sentences = wrap_sentences ( sentence_list2 , min_indent , max_width ) wrapped_block = '\n' . join ( wrapped_sentences ) else : width = max_width - min_indent wrapkw = dict ( width = width , break_on_hyphens = False , break_long_words = False ) wrapped_block = '\n' . join ( textwrap . wrap ( text_ , ** wrapkw ) ) if False : print ( 'HACKING' ) print ( 'width = {!r}' . format ( width ) ) words = text_ . split ( ', (' ) lines = [ ] line = '' for _ , w1 in enumerate ( words ) : if _ > 0 : w1 = '(' + w1 + ', ' if len ( line + w1 ) > width : line += '' lines . append ( line ) line = '' line += w1 lines . append ( line ) wrapped_block = '\n' . join ( lines ) last_is_nl = text . endswith ( '\n' ) and not wrapped_block . endswith ( '\n' ) first_is_nl = len ( text ) > 1 and text . startswith ( '\n' ) and not wrapped_block . startswith ( '\n' ) if last_is_nl : wrapped_block += '\n' if first_is_nl : wrapped_block = '\n' + wrapped_block wrapped_text = ut . indent ( wrapped_block , ' ' * min_indent ) return wrapped_text
r"""
    helps me separatate sentences grouped in paragraphs that I have a
    difficult time reading due to dyslexia

    Args:
        text (str):

    Returns:
        str: wrapped_text

    CommandLine:
        python -m utool.util_str --exec-format_single_paragraph_sentences --show
        python -m utool.util_str --exec-format_single_paragraph_sentences --show --nobreak

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.util_str import *  # NOQA
        >>> import utool as ut
        >>> text = '     lorium ipsum doloar dolar dolar dolar erata man foobar is this there yet almost man not quit ate 80 chars yet hold out almost there? dolar erat. sau.ltum. fds.fd... . . fd oob fd. list: (1) abcd, (2) foobar (4) 123456789 123456789 123456789 123456789 123 123 123 123 123456789 123 123 123 123 123456789 123456789 123456789 123456789 123456789 123 123 123 123 123 123456789 123456789 123456789 123456789 123456789 123456789 (3) spam.'
        >>> #text = 'list: (1) abcd, (2) foobar (3) spam.'
        >>> #text = 'foo. when: (1) there is a new individual,'
        >>> #text = 'when: (1) there is a new individual,'
        >>> #text = '? ? . lorium. ipsum? dolar erat. saultum. fds.fd...  fd oob fd. ? '  # causes breakdown
        >>> print('text = %r' % (text,))
        >>> sentence_break = not ut.get_argflag('--nobreak')
        >>> wrapped_text = format_single_paragraph_sentences(text, debug=True, sentence_break=sentence_break)
        >>> result = ('wrapped_text =\n%s' % (str(wrapped_text),))
        >>> print(result)