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
package Torello.Java;

import Torello.Java.StringParse;
import Torello.Java.Verbosity;

import static Torello.Java.C.BYELLOW;
import static Torello.Java.C.BCYAN;
import static Torello.Java.C.RESET;

import java.io.IOException;

class PrintingRecSingleLine
{
    // Re-Use the Pointer, I guess
    private static final String I4 = Helper.I4;

    // This is the only file/class that even has an "I8"
    private static final String I8 = I4 + I4;


    String originalLine, newLine;
    int originalLineLength, newLineLength, lineNumber;

    void saveOriginalLine       (String s)  { this.originalLine = s;        }
    void saveNewLine            (String s)  { this.newLine = s;             }
    void saveOriginalLineLength (int i)     { this.originalLineLength = i;  }
    void saveNewLineLength      (int i)     { this.newLineLength = i;       }
    void saveLineNumber         (int i)     { this.lineNumber = i;          }

    String toString(
            final int       maxLineLen,
            final boolean   useUNIXColors
        )
    {
        // The line-number (as an integer), converted to to a line-number as a string
        final String origLineLenStr = "" + originalLineLength;
        final String newLineLenStr  = "" + newLineLength;

        // This is nothing more than the amount of space-characters need for the output
        // to be evenly-spaced / lined-up.  Since (at least in my code), line-numbers are
        // always less than 100, or equal to exactly 100 characters, most of the time
        // 'oPad' and 'nPad' will be zero-length / empty String's!
        //
        // In the '.java' Files I wite, they will be a 1-character long String that simply
        // contains 1 Space-Character.

        final String oPad = StringParse.nChars(' ', maxLineLen - origLineLenStr.length());
        final String nPad = StringParse.nChars(' ', maxLineLen - newLineLenStr.length());

        if (useUNIXColors) return 

            I4 + "LINE: " + BYELLOW + "" + lineNumber + RESET + '\n' +
            I8 + "[" + BCYAN + origLineLenStr   + RESET + "]: " + oPad + originalLine + '\n' +
            I8 + '[' + BCYAN + newLineLenStr    + RESET + "]: " + nPad + newLine + '\n' +
            '\n';

        else return

            I4 + "LINE: " + "" + lineNumber + '\n' +
            I8 + "[" + origLineLenStr   + "]: " + oPad + originalLine + '\n' +
            I8 + '[' + newLineLenStr    + "]: " + nPad + newLine + '\n' +
            '\n';
    }

    static void printAll(
            final PrintingRecSingleLine[]   recs,
            final boolean                   useUNIXColors, 
            final Appendable                appendable,
            final Verbosity                 verbosity
        )

        // This method cannot actually throw IOException.  The user's Appendable is not always
        // present.  If it is, and it is used, it will be wrapped in an AppendableSafe
        // instance.  If the User-Appendable is not present, System.out is the only thing being
        // written to, and that never throws IOException.

        throws IOException
    {
        // '.....' is printed when the user requests Verbosity.Quiet mode.  Therefore in this
        // particular case, it is necessary to print a newline character.

        if (verbosity == Verbosity.Quiet) appendable.append('\n');

        // The longest line-length for all lines that had matches which must be changed
        int max = 0;

        for (PrintingRecSingleLine r : recs)
        {
            if (r.originalLineLength > max) max = r.originalLineLength;
            if (r.newLineLength > max)      max = r.newLineLength;
        }

        // It is (a lot) more efficient to do this with a divide-by-10-loop, but I'm leaving 
        // the Math.log10 call / invocation, because I don't care.
        //
        // Variable 'l' is the Maximum-Length of the Line-Length-As-A-String.  Note that is not
        // the same as the "Maximum-Line-Length".  So if the Maximum-Line-Length were '99', the
        // Max-Line-Len-As-A-String is '2' because only two characters are required to print
        // the number 99.
        //
        // I choose to call this concept 'l'

        final int l = 1 + ((int) Math.floor(Math.log10(max)));

        for (PrintingRecSingleLine r : recs)
            appendable.append(r.toString(l, useUNIXColors));
    }
}