1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package Torello.Java;

class WrapHelpers
{
    // ********************************************************************************************
    // ********************************************************************************************
    // Two Error Printers, Debug Printers
    // ********************************************************************************************
    // ********************************************************************************************


    static String SP(final int start, final int pos)
    { return "  (start=" + start + ", pos=" + pos + ')'; }

    static String PRINTABLE_C(char c)
    {
        switch (c)
        {
            case '\f':  return "\\f";
            case '\t':  return "\\t";
            case '\n':  return "\\n";
            case '\r':  return "\\r";
            default:    return "" + c;
        }
    }


    // ********************************************************************************************
    // ********************************************************************************************
    // Helpers
    // ********************************************************************************************
    // ********************************************************************************************


    static int backupSpaces_AKA_RightTrimCurLine(final String s, final int start, int pos)
    {
        if (pos < start) return start;

        while ((pos >= start) && (s.charAt(pos) == ' ')) pos--;

        return (pos < start)
            ? start 
            : (pos + 1);
    }

    static int skipSpacesTowardsNextLine(final String s, int pos, final int LEN)
    {
        while ((pos < LEN) && (s.charAt(pos) == ' ')) pos++;
        return pos;
    }

    static int firstLeftWhiteSpace(final String s, final int start, int pos)
    {
        while ((pos >= start) && (s.charAt(pos) != ' ')) pos--;
        return (pos < start) ? -1 : pos;
    }

    static int lastLeftWhiteSpace(final String s, final int start, int pos)
    {
        while ((pos >= start) && (s.charAt(pos) == ' ')) pos--;
        return pos + 1;
    }

    static boolean lastLineIsNewLine(final String s, final int LEN)
    {
        char c;

        for (int pos=LEN-1; pos >= 0; pos--)
            if ((c = s.charAt(pos)) == ' ') continue;
            else if (c == '\n')             return true;

        return false;
    }

    static String getIndentationAmount(final String line)
    {
        final int LEN = line.length();

        if ((LEN == 0) || (line.charAt(0) != ' ')) return "";

        for (int pos=1; pos < LEN; pos++)
            if (line.charAt(pos) != ' ')
                return line.substring(0, pos);


        // This line should not ever execute!  This method should only be invoked using lines of
        // text that have some character data.  Execution of this line would be tantamount to
        // saying that this method received a line that consisted only of space characters.

        return line;
    }


    // ********************************************************************************************
    // ********************************************************************************************
    // Currently Unused.  Code Snippet from a future feature
    // ********************************************************************************************
    // ********************************************************************************************


    /**
     * 
     * <BR /><BR /><B CLASS=JDDescLabel>ANSI Color Sequences:</B>
     * 
     * <BR />This method explicity requests that any and all ANSI-Terminal Color-Code
     * Escape-Sequences be prevented from "counting" their Character-Lengths to the total length of
     * a line of text.
     * 
     * <BR /><BR />If a {@code String} of text contains the characters {@code "Hello World"}, but
     * before the {@code String} are the ANSI Color-Sequences for {@link C#BGREEN Bright-Green},
     * and ends with the {@link C#RESET Reset} Sequence, then this line of text shall be counted as
     * having exactly 11 Characters of Text, rather than 20.
     * 
     * <BR /><BR />This, despite the fact, that the {@code 'BGREEN'} ANSI-Sequence actually adds an
     * additional 5 characters, while the {@code 'RESET'} adds an additional 4.  Specifically:
     * 
     * <DIV CLASS=EXAMPLE>{@code
     * String s = C.BYELLOW + "Hello World" + RESET;
     * 
     * System.out.println(StrPrint.indent(s, 5, 5));
     * 
     * // PRINTS: "Hello\nWorld"
     * }</DIV>
     * @param s
     * @param pos
     * @param LEN
     * @return
     */
    /*
    static int ansiSeqEnd(final String s, int pos, final int LEN)
    {
        char c = s.charAt(pos);

        if (c == 'm') return pos;

        while (     (c >= '0')
                &&  (c <= '9')
                &&  (pos < LEN)
        )
            c = s.charAt(++pos);

        return (c == 'm') ? pos : -1;
    }
    */


    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    // Check for ANSI-Color Escape-Sequences (don't count lengths - if requested)
    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

    /*
    if (    dontCountANSISeq
        &&  (c == '\u001B')
        &&  (pos < (LEN - 4))
        &&  (s.charAt(pos + 1) == '[')
        &&  ((tempChar = s.charAt(pos + 2)) >= '0')
        &&  (tempChar <= '9')
        &&  ((ansiSeqEnd = WrapHelpers.ansiSeqEnd(s, pos + 3, LEN)) != -1)
    )
    {
        pos = ansiSeqEnd;   // 'pos' is currently pointing to the ending 'm'
        curLineLen--;       // The Loop's Post-Increment will add "+1".  However, because
        continue;           // this sequence is being ignored completely, subtract "-1"
    }                       // All that means is that the "curLineLen" DOES NOT reflect
                            // this substring's characters / length!
    */
}