I pushed changes to http://hg.openjdk.java.net/amber/amber <http://hg.openjdk.java.net/amber/amber> string-tapas branch to reflect the incidental whitespace discussion. What is implemented is what Brian described as
Version 2 of the algorithm — the “significant closing delimiter” version — is: - Strip leading and trailing blanks (perhaps limited to one each only) - Compute the maximal common whitespace prefix of the remaining lines, _including the stripped trailing blank line from above, if any_, and trim that off - If a blank last line was trimmed, add back a newline With strip leading and trailing blanks limited to one each. I also added a "super escape" \~ to opt out of auto align. Example: String l = """\~ +--------+ | text | +--------+ """; // what opt out might look like Actual: \n .......................+--------+\n .......................| text |\n .......................+--------+\n ................... Note that the String#align needs tweaking to reflect the algorithm (needs to add closing delimiter influence). There is a sampler at http://cr.openjdk.java.net/~jlaskey/Strings/AutoAlign.java <http://cr.openjdk.java.net/~jlaskey/Strings/AutoAlign.java> (included below as well) that shows the examples from my original (1a) incidental whitespace e-mail. Cheers, -- Jim _____________________________________________________________________________________________________________ public class AutoAlign { public static void report(String label, String result) { System.out.format("Result of variable %s%n", label); String formatted = result.replaceAll(" ", ".") .replaceAll("\n", "\\\\n\n"); System.out.format("%s%n%n", formatted); } public static void main(String... args) throws Exception { String a = """ +--------+ | text | +--------+ """; // first characters in first column? String b = """ +--------+ | text | +--------+ """; // first characters in first column or indented four spaces? String c = """ +--------+ | text | +--------+ """; // first characters in first column or indented several? String d = """ +--------+ | text | +--------+ """; // first characters in first column or indented four? String e = """ +--------+ | text | +--------+ """; // heredoc? String f = """ +--------+ | text | +--------+ """; // one or all leading or trailing blank lines stripped? String g = """ +--------+ | text | +--------+"""; // Last \n dropped String h = """+--------+ | text | +--------+"""; // determine indent of first line using scanner knowledge? String i = """ "nested" """; // strip leading/trailing space? String name = " methodName"; String j = (""" public static void """ + name + """(String... args) { System.out.println(String.join(args)); } """).align(); // how do we handle expressions with multi-line strings? String k = String.format(""" public static void %s(String... args) { System.out.println(String.join(args)); } """, name); // is this the answer to multi-line string expressions? String l = """\~ +--------+ | text | +--------+ """; // what opt out might look like report("a", a); report("b", b); report("c", c); report("d", d); report("e", e); report("f", f); report("g", g); report("h", h); report("i", i); report("j", j); report("k", k); report("l", l); } } _____________________________________________________________________________________________________________ Result of variable a +--------+\n |..text..|\n +--------+\n Result of variable b ....+--------+\n ....|..text..|\n ....+--------+\n Result of variable c ...............+--------+\n ...............|..text..|\n ...............+--------+\n Result of variable d ....+--------+\n ....|..text..|\n ....+--------+\n Result of variable e +--------+\n |..text..|\n +--------+\n Result of variable f \n \n ....+--------+\n ....|..text..|\n ....+--------+\n \n \n Result of variable g +--------+\n |..text..|\n +--------+ Result of variable h +--------+\n |..text..|\n +--------+ Result of variable i "nested" Result of variable j public.static.void.methodName(String....args).{\n ..........System.out.println(String.join(args));\n ......}\n Result of variable k ......public.static.void..methodName(String....args).{\n ..........System.out.println(String.join(args));\n ......}\n Result of variable l \n .......................+--------+\n .......................|..text..|\n .......................+--------+\n ...................