public static String flow()

in mailet/base/src/main/java/org/apache/mailet/base/FlowedMessageUtils.java [207:341]


    public static String flow(String text, boolean delSp, int width) {
        int lastIndex = text.length() - 1;

        StringBuilder result = new StringBuilder();
        int lineStartIndex = 0;

        while (lineStartIndex <= lastIndex) {
            int quoteDepth = 0;
            while (lineStartIndex <= lastIndex && text.charAt(lineStartIndex) == RFC2646_QUOTE) {
                quoteDepth++;
                lineStartIndex++;
            }

            if (quoteDepth > 0 && lineStartIndex + 1 <= lastIndex && text.charAt(lineStartIndex) == RFC2646_SPACE) {
                lineStartIndex++;
            }

            // We support both LF and CRLF line endings. To cover both cases we search for LF.
            int lineFeedIndex = text.indexOf(LF, lineStartIndex);
            boolean lineBreakFound = lineFeedIndex != -1;
            int lineEndIndex = lineBreakFound ? lineFeedIndex : text.length();
            int nextLineStartIndex = lineBreakFound ? lineFeedIndex + 1 : text.length();

            if (lineBreakFound && lineEndIndex > 0 && text.charAt(lineEndIndex - 1) == CR) {
                lineEndIndex--;
            }

            // Special case: signature separator
            if (lineEndIndex - lineStartIndex == RFC2646_SIGNATURE.length() &&
                text.regionMatches(lineStartIndex, RFC2646_SIGNATURE, 0, RFC2646_SIGNATURE.length())
            ) {
                if (quoteDepth > 0) {
                    for (int i = 0; i < quoteDepth; i++) {
                        result.append(RFC2646_QUOTE);
                    }
                    result.append(RFC2646_SPACE);
                }
                result.append(RFC2646_SIGNATURE);
                result.append(RFC2646_CRLF);

                lineStartIndex = nextLineStartIndex;
                continue;
            }

            // Remove trailing spaces
            while (lineEndIndex > lineStartIndex && text.charAt(lineEndIndex - 1) == RFC2646_SPACE) {
                lineEndIndex--;
            }

            // Special case: a quoted line without any content
            if (lineStartIndex == lineEndIndex && quoteDepth > 0) {
                for (int i = 0; i < quoteDepth; i++) {
                    result.append(RFC2646_QUOTE);
                }
            }

            while (lineStartIndex < lineEndIndex) {
                int prefixLength = 0;
                if (quoteDepth == 0) {
                    if (text.charAt(lineStartIndex) == RFC2646_SPACE || text.charAt(lineStartIndex) == RFC2646_QUOTE ||
                        lineEndIndex - lineStartIndex >= RFC2646_FROM.length() &&
                            text.regionMatches(lineStartIndex, RFC2646_FROM, 0, RFC2646_FROM.length())
                    ) {
                        // This line needs space stuffing
                        result.append(RFC2646_SPACE);
                        prefixLength = 1;
                    }
                } else {
                    for (int i = 0; i < quoteDepth; i++) {
                        result.append(RFC2646_QUOTE);
                    }
                    result.append(RFC2646_SPACE);
                    prefixLength = quoteDepth + 1;
                }

                int remainingWidth = width - prefixLength - 1;
                if (delSp) {
                    remainingWidth--;
                }
                if (remainingWidth < 0) {
                    remainingWidth = 0;
                }

                int breakIndex = lineStartIndex + remainingWidth;
                if (breakIndex >= lineEndIndex) {
                    breakIndex = lineEndIndex;
                } else {
                    while (breakIndex >= lineStartIndex &&
                        (delSp && isAlphaChar(text, breakIndex) || !delSp && text.charAt(breakIndex) != RFC2646_SPACE)
                    ) {
                        breakIndex--;
                    }

                    if (breakIndex < lineStartIndex) {
                        // Not able to cut a word: skip to word end even if greater than the max width
                        breakIndex = lineStartIndex + remainingWidth;
                        while (breakIndex < lineEndIndex &&
                            ((delSp && isAlphaChar(text, breakIndex)) ||
                                (!delSp && text.charAt(breakIndex) != RFC2646_SPACE))
                        ) {
                            breakIndex++;
                        }
                    }

                    breakIndex++;

                    if (breakIndex >= lineEndIndex) {
                        breakIndex = lineEndIndex;
                    } else if (Character.isHighSurrogate(text.charAt(breakIndex - 1))) {
                        // Don't break surrogate pairs apart
                        breakIndex++;
                    }
                }

                result.append(text, lineStartIndex, breakIndex);

                if (breakIndex < lineEndIndex) {
                    if (delSp) {
                        result.append(RFC2646_SPACE);
                    }
                    result.append(RFC2646_CRLF);
                }

                lineStartIndex = breakIndex;
            }

            if (lineBreakFound) {
                result.append(RFC2646_CRLF);
            }

            lineStartIndex = nextLineStartIndex;
        }

        return result.toString();
    }