def beautify_string(self, data, path=''):
        """Beautify string (file part)."""
        tab = 0
        case_level = 0
        prev_line_had_continue = False
        continue_line = False
        started_multiline_quoted_string = False
        ended_multiline_quoted_string = False
        open_brackets = 0
        in_here_doc = False
        defer_ext_quote = False
        in_ext_quote = False
        ext_quote_string = ''
        here_string = ''
        output = []
        line = 1
        formatter = True
        for record in re.split('\n', data):
            record = record.rstrip()
            stripped_record = record.strip()

            # preserve blank lines
            if not stripped_record:
                output.append(stripped_record)
                continue

            # ensure space before ;; terminators in case statements
            if case_level:
                stripped_record = re.sub(r'(\S);;', r'\1 ;;', stripped_record)

            test_record = self.get_test_record(stripped_record)

            # detect whether this line ends with line continuation character:
            prev_line_had_continue = continue_line
            continue_line = True if (re.search(r'\\$', stripped_record)!=None) else False
            inside_multiline_quoted_string = prev_line_had_continue and continue_line and started_multiline_quoted_string

            if not continue_line and prev_line_had_continue and started_multiline_quoted_string:
                # remove contents of strings initiated on previous lines and that are ending on this line:
                [test_record, num_subs] = re.subn(r'^[^"]*"', '', test_record)
                ended_multiline_quoted_string = True if num_subs>0 else False
            else:
                ended_multiline_quoted_string = False

            if(in_here_doc) or (inside_multiline_quoted_string) or (ended_multiline_quoted_string):  # pass on with no changes
                output.append(record)
                # now test for here-doc termination string
                if(re.search(here_string, test_record) and not
                   re.search(r'<<', test_record)):
                    in_here_doc = False
            else:  # not in here doc or inside multiline-quoted

                if continue_line:
                    if prev_line_had_continue:
                        # this line is not STARTING a multiline-quoted string... we may be in the middle
                        # of such a multiline string though
                        started_multiline_quoted_string = False
                    else:
                        # remove contents of strings initiated on current line but that continue on next line
                        # (in particular we need to ignore brackets they may contain!)
                        [test_record, num_subs] = re.subn(r'"[^"]*?\\$', '', test_record)
                        started_multiline_quoted_string = True if num_subs>0 else False
                else:
                    # this line is not STARTING a multiline-quoted string
                    started_multiline_quoted_string = False

                if(re.search(r'<<-?', test_record)) and not (re.search(r'.*<<<', test_record)):
                    here_string = re.sub(
                        r'.*<<-?\s*[\'|"]?([_|\w]+)[\'|"]?.*', r'\1',
                        stripped_record, 1)
                    in_here_doc = (len(here_string) > 0)

                if(in_ext_quote):
                    if(re.search(ext_quote_string, test_record)):
                        # provide line after quotes
                        test_record = re.sub(
                            r'.*%s(.*)' % ext_quote_string, r'\1',
                            test_record, 1)
                        in_ext_quote = False
                else:  # not in ext quote
                    if(re.search(r'(\A|\s)(\'|")', test_record)):
                        # apply only after this line has been processed
                        defer_ext_quote = True
                        ext_quote_string = re.sub(
                            r'.*([\'"]).*', r'\1', test_record, 1)
                        # provide line before quote
                        test_record = re.sub(
                            r'(.*)%s.*' % ext_quote_string, r'\1',
                            test_record, 1)
                if(in_ext_quote or not formatter):
                    # pass on unchanged
                    output.append(record)
                    if(re.search(r'#\s*@formatter:on', stripped_record)):
                        formatter = True
                        continue
                else:  # not in ext quote
                    if(re.search(r'#\s*@formatter:off', stripped_record)):
                        formatter = False
                        output.append(record)
                        continue

                    # multi-line conditions are often meticulously formatted
                    if open_brackets:
                        output.append(record)
                    else:
                        inc = len(re.findall(
                            r'(\s|\A|;)(case|then|do)(;|\Z|\s)', test_record))
                        inc += len(re.findall(r'(\{|\(|\[)', test_record))
                        outc = len(re.findall(
                            r'(\s|\A|;)(esac|fi|done|elif)(;|\)|\||\Z|\s)',
                            test_record))
                        outc += len(re.findall(r'(\}|\)|\])', test_record))
                        if(re.search(r'\besac\b', test_record)):
                            if(case_level == 0):
                                sys.stderr.write(
                                    'File %s: error: "esac" before "case" in '
                                    'line %d.\n' % (path, line))
                            else:
                                outc += 1
                                case_level -= 1

                        # special handling for bad syntax within case ... esac
                        if re.search(r'\bcase\b', test_record):
                            inc += 1
                            case_level += 1

                        choice_case = 0
                        if case_level:
                            if(re.search(r'\A[^(]*\)', test_record)):
                                inc += 1
                                choice_case = -1

                        # detect functions
                        func_decl_style = self.detect_function_style(test_record)
                        if func_decl_style != None:
                             stripped_record = self.change_function_style(stripped_record, func_decl_style)

                        # an ad-hoc solution for the "else" or "elif" keyword
                        else_case = (0, -1)[re.search(r'^(else|elif)',
                                            test_record) is not None]
                        net = inc - outc
                        tab += min(net, 0)

                        # while 'tab' is preserved across multiple lines, 'extab' is not and is used for
                        # some adjustments:
                        extab = tab + else_case + choice_case
                        if prev_line_had_continue and not open_brackets and not ended_multiline_quoted_string:
                            extab+=1
                        extab = max(0, extab)
                        output.append((self.tab_str * self.tab_size * extab) +
                                      stripped_record)
                        tab += max(net, 0)
                if(defer_ext_quote):
                    in_ext_quote = True
                    defer_ext_quote = False

                # count open brackets for line continuation
                open_brackets += len(re.findall(r'\[', test_record))
                open_brackets -= len(re.findall(r'\]', test_record))
            line += 1
        error = (tab != 0)
        if(error):
            sys.stderr.write(
                'File %s: error: indent/outdent mismatch: %d.\n' % (path, tab))
        return '\n'.join(output), error
Beautify string (file part).