Can anyone suggest a method for writing a mutli-line String to a system console and having that text block be indented? I'm looking for something relatively lightweight because it's only being used for displaying help for a command line program.
Asked
Active
Viewed 3.0k times
15
-
1Do you have a string that contains linebreaks, or do you want auto-wrapping, or do you just have multiple lines and want to align them in some tabular format? In short: please give an example of input and desired output. – Cephalopod Apr 08 '13 at 21:14
-
1@Arian. I would like auto-wrapping. Something similar to how man pages are formatted. I was hoping for something lightweight, but maybe some sort of template language is the only way. – BillMan Apr 09 '13 at 11:51
-
What about splitting the string at spaces and inserting a line break whenever a word exceeds line width? – Cephalopod Apr 09 '13 at 18:51
-
I was hoping that there was something already out there to do this for me. I did a little research and it seems like something as simple as getting the console width isn't supported in a cross platform way. I'm not sure why this doesn't get more attention, but I think it should. I don't see the command line going away anytime soon. – BillMan Apr 09 '13 at 19:07
-
These answers may be useful: http://stackoverflow.com/questions/19425508/format-text-output-for-console-in-java – joelittlejohn Oct 27 '16 at 15:08
2 Answers
45
NOTE: The approach described below does not meet the updated requirements described by @BillMan in the question's comments. This will not automatically wrap lines that are longer than the console line length - only use this approach if wrapping isn't an issue.
As a simple option, you could use
String.replaceAll()
as follows:
String output = <your string here>
String indented = output.replaceAll("(?m)^", "\t");
If you're unfamiliar with Java regular expressions, it works as follows:
(?m)
enables multiline mode. This means each line inoutput
is considered individually, instead of treatingoutput
as a single line (which is the default).^
is a regex matching the start of each line.\t
causes each match of the preceding regex (i.e. the start of each line) to be replaced by a tab character.
As an example, the following code:
String output = "foo\nbar\nbaz\n"
String indented = output.replaceAll("(?m)^", "\t");
System.out.println(indented);
Produces this output:
foo bar baz
-
I don't think this is what the OP is looking for, as lines that are too long are wrapped by the console and not indented. I think what's needed here is a method that a) wraps to N char limit (e.g. 80 chars) but splits on words and b) indents each line, even the ones that have been wrapped. – joelittlejohn Oct 27 '16 at 15:06
-
4@joelittlejohn: you are right - the updated requirements (added as comments *after* I last looked at this question) are not met by the approach I describe. It may still be useful advice for others with similar requirements, though. I've added a disclaimer to that effect at the top. Thanks for bringing that to my attention. – Mac Oct 28 '16 at 00:47
-
1This was exactly what I needed! ... Except I'm in Java 1.3 land and `replaceAll()` doesn't exist there. – Andrew Keeton Feb 19 '19 at 14:41
-
1@AndrewKeeton: yep, looking at the version history, [regexes were added in 1.4](https://en.wikipedia.org/wiki/Java_version_history#J2SE_1.4). That was **17 years ago** though, are you really stuck with such an ancient Java version? – Mac Feb 19 '19 at 23:12
-
@Mac: Embedded device. It's OK, I didn't need this for anything important. My main point was acknowledging the "It may still be useful advice for others..." comment. – Andrew Keeton Feb 20 '19 at 00:42
6
With JDK/12 early access builds, one can now make use of the indent
API of the String class which is currently available under the preview feature and can be used as :
String indentedBody =
`<html>
<body>
<p>Hello World - Indented.</p>
</body>
</html>`.indent(4);
and the output of the above code would be
<html> <body> <p>Hello World - Indented.</p> </body> </html>
The current documented specification of the API further is as follows:
/**
* Adjusts the indentation of each line of this string based on the value of
* {@code n}, and normalizes line termination characters.
* <p>
* This string is conceptually separated into lines using
* {@link String#lines()}. Each line is then adjusted as described below
* and then suffixed with a line feed {@code "\n"} (U+000A). The resulting
* lines are then concatenated and returned.
* <p>
* If {@code n > 0} then {@code n} spaces (U+0020) are inserted at the
* beginning of each line. {@link String#isBlank() Blank lines} are
* unaffected.
* <p>
* If {@code n < 0} then up to {@code n}
* {@link Character#isWhitespace(int) white space characters} are removed
* from the beginning of each line. If a given line does not contain
* sufficient white space then all leading
* {@link Character#isWhitespace(int) white space characters} are removed.
* Each white space character is treated as a single character. In
* particular, the tab character {@code "\t"} (U+0009) is considered a
* single character; it is not expanded.
* <p>
* If {@code n == 0} then the line remains unchanged. However, line
* terminators are still normalized.
* <p>
*
* @param n number of leading
* {@link Character#isWhitespace(int) white space characters}
* to add or remove
*
* @return string with indentation adjusted and line endings normalized
*
* @see String#lines()
* @see String#isBlank()
* @see Character#isWhitespace(int)
*
* @since 12
*/
public String indent(int n)

Naman
- 27,789
- 26
- 218
- 353
-
2You can read the answer from me on how to [enable preview features and test out with maven](https://stackoverflow.com/a/52232682/1746118) for exploring this via Maven. – Naman Sep 21 '18 at 09:37