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 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | package Torello.Java; import java.util.Vector; import java.util.HashMap; import java.io.File; /** * A UNIX Terminal Color-Codes implementation for printing colored text to terminal. * * <BR /><BR /><EMBED CLASS='external-html' DATA-FILE-ID=UNIX_COLORS> */ @Torello.JavaDoc.StaticFunctional public class C { private C() { } /** * If Java is not running on a UNIX machine, the terminal output that contains "color" will not function. * If it does not, then the Shell color commands will default to empty, zero-length strings. * * <BR /><BR /><B CLASS=JDDescLabel>WINDOWS SUPPORT:</B> * * <BR />Since Windows Release 1909, which was the 2019 Version of Windows 10, MS-DOS Command * Prompt Windows will also support ANSI Color-Code Escape Sequences; */ public static final boolean colorANSI; static { String osName = System.getProperty("os.name"); String osArch = System.getProperty("os.arch"); String osVers = System.getProperty("os.version"); boolean windows = StrCmpr.containsIgnoreCase(osName, "win"); boolean unix = StrCmpr.containsOR_CI(osName, "nix", "nux", "aix"); float version = -1; if (windows) try { version = Float.parseFloat(osVers); } catch (Exception e) { } /* // Finding out where this class works is more difficult than you realize System.out.println( "os.name: " + osName + '\n' + "os.arch: " + osArch + '\n' + "os.version: " + osVers + '\n' + "version: " + version ); Q.BP(); */ if (windows) colorANSI = (version >= 10); else if (unix) colorANSI = true; else if (StrCmpr.containsIgnoreCase(osName, "max")) colorANSI = false; else if (StrCmpr.containsIgnoreCase(osName, "sunos")) colorANSI = false; else colorANSI = true; } public static final String RESET = colorANSI ? "\u001B[0m" : ""; public static final String BLACK = colorANSI ? "\u001B[30m" : ""; public static final String RED = colorANSI ? "\u001B[31m" : ""; public static final String GREEN = colorANSI ? "\u001B[32m" : ""; public static final String YELLOW = colorANSI ? "\u001B[33m" : ""; public static final String BLUE = colorANSI ? "\u001B[34m" : ""; public static final String PURPLE = colorANSI ? "\u001B[35m" : ""; public static final String CYAN = colorANSI ? "\u001B[36m" : ""; public static final String WHITE = colorANSI ? "\u001B[37m" : ""; public static final String BLACK_BKGND = colorANSI ? "\u001B[40m" : ""; public static final String RED_BKGND = colorANSI ? "\u001B[41m" : ""; public static final String GREEN_BKGND = colorANSI ? "\u001B[42m" : ""; public static final String YELLOW_BKGND = colorANSI ? "\u001B[43m" : ""; public static final String BLUE_BKGND = colorANSI ? "\u001B[44m" : ""; public static final String PURPLE_BKGND = colorANSI ? "\u001B[45m" : ""; public static final String CYAN_BKGND = colorANSI ? "\u001B[46m" : ""; public static final String WHITE_BKGND = colorANSI ? "\u001B[47m" : ""; public static final String BBLACK = colorANSI ? "\u001B[90m" : ""; public static final String BRED = colorANSI ? "\u001B[91m" : ""; public static final String BGREEN = colorANSI ? "\u001B[92m" : ""; public static final String BYELLOW = colorANSI ? "\u001B[93m" : ""; public static final String BBLUE = colorANSI ? "\u001B[94m" : ""; public static final String BPURPLE = colorANSI ? "\u001B[95m" : ""; public static final String BCYAN = colorANSI ? "\u001B[96m" : ""; public static final String BWHITE = colorANSI ? "\u001B[97m" : ""; public static final String BBLACK_BKGND = colorANSI ? "\u001B[100m" : ""; public static final String BRED_BKGND = colorANSI ? "\u001B[101m" : ""; public static final String BGREEN_BKGND = colorANSI ? "\u001B[102m" : ""; public static final String BYELLOW_BKGND = colorANSI ? "\u001B[103m" : ""; public static final String BBLUE_BKGND = colorANSI ? "\u001B[104m" : ""; public static final String BPURPLE_BKGND = colorANSI ? "\u001B[105m" : ""; public static final String BCYAN_BKGND = colorANSI ? "\u001B[106m" : ""; public static final String BWHITE_BKGND = colorANSI ? "\u001B[107m" : ""; private static final String CSS_DEFINITIONS_FILE = "data-files" + File.separator + "C-CSS.sdat"; private static final String HTML_SPANS_FILE = "data-files" + File.separator + "C-SPANS.sarrdat"; @SuppressWarnings("rawtypes") private static final Vector v = LFEC.readObjectFromFile_JAR (Torello.Java.C.class, HTML_SPANS_FILE, true, Vector.class); // This list has: // "</SPAN>" (Maps to: C.RESET) // "<SPAN CLASS=SC1>" through SC8 (Maps to: C.BLACK ... C.WHITE) // "<SPAN CLASS=SB1>" through SB8 (Maps to: C.BLACK_BKGND ... C.WHITE_BKGND) // "<SPAN CLASS=BC1>" through BC8 (Maps to: C.BBLACK ... C.BWHITE) // "<SPAN CLASS=BB1>" through BB8 (Maps to: C.BBLACK_BKGND ... C.BWHITE_BKGND) @SuppressWarnings("unchecked") private static final String[] htmlSpansCSSClasses = (String[]) v.elementAt(0); // This list is identical to the one above, but uses **INLINE** STYLE ATTRIBUTES: // C.RESET ==> "</SPAN>" // C.BLACK ==> "<SPAN style='color: black;'>" // C.BLACK_BKGND ==> "<SPAN style='background: black;'>" // C.BBLACK ==> "<SPAN style='color: black; font-weight: bold;'>" // C.BBLACK_BKGN ==> "<SPAN style='background: brightblack;'>" @SuppressWarnings("unchecked") private static final String[] htmlSpansStyleAttributes = (String[]) v.elementAt(1); // Efficiently (using HashMap) converts a "Char Code String" to an array position // The "Char Code String" may be any one of the 33 String defined in this class. // The array position is an index into the PREVIOUS TWO ARRAYS. @SuppressWarnings("unchecked") private static final HashMap<String, Integer> charCodesMap = (HashMap<String, Integer>) v.elementAt(2); // less efficient version, 'StrRepace' requires this... Note - these Strings are all // extremely short. There isn't a way to improve StrReplace in this regard - it *MUST* // check for *ALL* of the codes... private static final String[] charCodesArr = (String[]) v.elementAt(3); /** * This will convert a UNIX 'Character Code' into an HTML Tag if it is necessary to convert * UNIX colored-text into HTML. * * <BR /><BR /><B CLASS=JDDescLabel>CSS-Definitions:</B> * * <BR />This method returns an HTML {@code SPAN}-Tag that contains an inline * {@code CSS-CLASS}. It is (hopefully) obvious that the definitiions for any / all * {@code CSS-CLASSES} that are used will need to be provided on the page. * * <BR /><BR />The method {@link #getCSSDefinitions()} will return the complete definition * page for all {@code CSS CLASSES} that are employed by this method. * * <BR /><BR />You may also view the contents of the CSS Definitions Below: * * <BR /><BR /><B><A HREF="hilite-files/C.css.html">Shell.C CSS Definitions</A></B> * * @param charCode Any one of the 33 codes defined in this class. * * @return An HTML {@code <SPAN CLASS=...>} element that may be used as a substitute for * one of the codes defined in this class. * * @throws IllegalArgumentException If the {@code String} that is passed to parameter * {@code 'charCode'} is not one of the defined codes in this class. * * @see #getCSSDefinitions() */ public static String span(String charCode) { Integer arrPos = charCodesMap.get(charCode); if (arrPos == null) throw new IllegalArgumentException( "The value passed to parameter 'charCode' is not one of the defined codes in " + "this class." ); return htmlSpansCSSClasses[arrPos]; } /** * This will convert a UNIX 'Character Code' into an HTML Tag if it is necessary to convert * UNIX colored-text into HTML. * * <BR /><BR /><B CLASS=JDDescLabel>CSS Inline-Style:</B> * * <BR />This method returns an HTML {@code SPAN}-Tag that contains an <B>inline * {@code STYLE}-Attribute</B>. Remember, if you are converting large Text-{@code String's} * into HTML using inlne {@code STYLE}-Attributes, your output could potentially grow very * large, and rather quickly. * * <BR /><BR />Using {@code CSS-CLASSES} provided by method {@link #span(java.lang.String)} * <I>will make your generated HTML <B>somewhat</B> more efficient</I>. If you do, you must * remember to import the CSS Definitions for these classes somewhere in your HTML-File. * * @param charCode Any one of the 33 codes defined in this class. * * @return An HTML {@code <SPAN STYLE=...>} element that may be used as a substitute for * one of the color-codes defined in this class. * * @throws IllegalArgumentException If the {@code String} that is passed to parameter * {@code 'charCode'} is not one of the defined codes in this class. */ public static String spanInlineStyle(String charCode) { Integer arrPos = charCodesMap.get(charCode); if (arrPos == null) throw new IllegalArgumentException( "The value passed to parameter 'charCode' is not one of the defined codes in " + "this class." ); return htmlSpansStyleAttributes[arrPos]; } /** * Convenience Method. * <BR />Invokes: {@link #toHTML(String, boolean, boolean, boolean)} */ public static String toHTML(String text) { return toHTML(text, false, true, false); } // Used in method below private static final String[] MATCH_STRS_1 = { "<", ">", "\n\r", "\r\n", "\n", "\r" }; private static final String[] MATCH_STRS_2 = { "<", ">" }; private static final String[] MATCH_STRS_3 = { "\n\r", "\r\n", "\n", "\r" }; private static final String REPLACER(int i, String s) { switch (s) { case "<" : return "<"; case ">" : return ">"; case "\n" : case "\r" : case "\n\r" : case "\r\n" : return "<BR />\n"; default: throw new UnreachableError(); } } /** * Converts the instances of these escape-sequences that are found inside of Java * {@code String's} that were generated using these ANSI UNIX color escape sequences, and * produces a valid HTML {@code String} that contains HTML * {@code <SPAN STYLE="color-information">} replacements! * * <BR /><BR /><B CLASS=JDDescLabel>New-Line Characters:</B> * * <BR />Any new-line Character-Sequences such as {@code '\n'} or {@code '\r\n'} will be * replaced with HTML {@code <BR />} elements. * * @param text This should be any string, usually one that is saved from a * {@code 'StorageWriter'}, although any text that includes these UNIX Color Escape Codes * is fine. * * @param preFormat When this parameter receives {@code FALSE}, everywhere in the input * text-{@code String} that a {@code CRLF} (new-line) occurs, that newline will be replaced * by an HTML {@code <BR />} element, in addition to the original newline. * * <BR /><BR />This parameter is referring to the CSS {@code 'white-space: pre'} setting, * which can be used. Althought, sometimes going with the plain-old-vanilla {@code <BR />} * tag can also be advisable. * * @param escapeHTMLElements Whenever HTML is sent to the input-parameter 'text' - if the * intention is to render the HTML using the browser, this parameter should be * {@code FALSE}. If it is intended to allow the UI to "show the HTML" like it were * text-to-be-viewed, then each and every greater-than-symbol {@code '>'} and also every * less-than-symbol {@code '<'} will be escaped. This is done to prevent the browser from * trying to parse the text as HTML. * * @param useCSSClasses When this parameter receives {@code TRUE}, all returned * {@code <SPAN STYLE=...>} elements shall be converted to using a simplified * {@code CSS Class Name}. The {@code CLASS} definitions for the returned {@code String} * can be retrieved by simply calling the method: {@link #getCSSDefinitions()}. * * <BR /><BR /><B><SPAN STYLE="color: red;">IMPORTANT:</SPAN></B> If this parameter does * receive a {@code TRUE} value, it is imperitive to include the {@code CSS STYLE} * definitions that are returned by the above mentioned method, or else the colors shall * not be visible. * * <BR /><BR />You may view the contents of the CSS Definitions Below: * * <BR /><BR /><B><A HREF="hilite-files/C.css.html">Shell.C CSS Definitions</A></B> * * @return Every UNIX-ANSI color escape-sequence that is found/identified in this text will * be replaced with an HTML * {@code <SPAN STYLE="color: a-color; background: a-background-color">} element. */ public static String toHTML (String text, boolean preFormat, boolean escapeHTMLElements, boolean useCSSClasses) { // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // Old Way, much less efficient // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // If the input text, itself, has HTML elements, then those have to be "escaped" to // properly render. If the intention was to have them rendered has HTML Elements // (not text), then this boolean should be false. // if (escapeHTMLElements) text = text.replace("<", "<").replace(">", ">"); // With "Pre-Formatted Text" - there is no need to add "<BR />" where line-breaks // occur CRLF will automatically be inserted courtesy of the browser // if (! preFormat) text = text.replaceAll("\n|\r\n|\r", "<BR />\n"); // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // Quite a bit faster // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** String[] matchStrs = null; // Replaces both '<', '>' **AND** '\n', '\r', '\n\r', '\r\n' (all at once) if (escapeHTMLElements && (! preFormat)) matchStrs = MATCH_STRS_1; // Replaces ONLY '<' and '>' else if (escapeHTMLElements && preFormat) matchStrs = MATCH_STRS_2; // Replaces ONLY '\n', '\r', '\n\r', '\r\n' else if ((! escapeHTMLElements) && (! preFormat)) matchStrs = MATCH_STRS_3; // NOW RUN IT... if (matchStrs != null) text = StrReplace.r(text, matchStrs, C::REPLACER); return StrReplace.r( text, charCodesArr, useCSSClasses ? htmlSpansCSSClasses : htmlSpansStyleAttributes ); } /** * If the {@code 'useCSSDefinitions'} option is selected with the * {@link #toHTML(String, boolean, boolean, boolean)} method, then the {@code String} * returned from this method shall provide the {@code CSS Style} definitions needed to use * the colors provided by {@code toHTML(...)} * * @return This shall visit the internal data-files for this JAR distribution, and return a * list of {@code CSS Style} definitions that will colorize the HTML produced by an * invocation of {@code toHTML()}. * * <BR /><BR />You may view the contents of the CSS Definitions Below: * * <BR /><BR /><B><A HREF="hilite-files/C.css.html">Shell.C CSS Definitions</A></B> */ public static String getCSSDefinitions() { /* return LFEC.readObjectFromFile_JAR (Torello.Data.DataFileLoader.class, CSS_DEFINITIONS_FILE, true, String.class); */ return LFEC.readObjectFromFile_JAR (Torello.Java.C.class, CSS_DEFINITIONS_FILE, true, String.class); } /** * Convenience Method. * <BR />Creates an {@code '.html'}-file from the output produced by * {@link #toHTML(String, boolean, boolean, boolean)} * <BR />Invokes: {@link #getCSSDefinitions()} * <BR />And Invokes: {@link #toHTML(String, boolean, boolean, boolean)} * <BR />Passes: {@code TRUE} to parameter {@code 'useCSSClasses'} */ public static String toHTML (String text, boolean preFormat, boolean escapeHTMLElements, String titleStr) { return "<HTML>\n" + "<HEAD>\n" + "<TITLE>" + titleStr + "</TITLE>\n" + "<STYLE TYPE='text/css'>\n" + '\n' + // This method simply copies the CSS-Definitions File out of the Java-HTML JAR, and // into a String that is returned to the user. Make sure to wrap that String // inside of a <STYLE>...</STYLE> HTML-Tag. Also - set the background color getCSSDefinitions() + "BODY { background: black; color: white; }\n" + "</STYLE>\n" + "</HEAD>\n" + "<BODY>\n" + (preFormat ? "<PRE>\n" : "") + // NOTE: This just calls the other variant of 'toHTML' - but ensures that 'true' is // passed to the 'useCSSClasses' parameter. toHTML(text, preFormat, escapeHTMLElements, true) + (preFormat ? "</PRE>\n" : "") + "</BODY>\n" + "</HTML>"; } } |