Loading
24, Jun 2024
Working with indentation in text blocks – Text blocks, Locales, Numbers & Math

3. Working with indentation in text blocks

Indentation in text blocks is easy to understand if we have a clear picture of two terms:

incidental (or unessential) white spaces – represent the meaningless white spaces that result from code formatting (leading white spaces commonly added by the IDE) or are added intentionally/accidentally at the end of the text (trailing white spaces) essential white spaces – represent the white spaces that we explicitly add and they are meaningful for the final string

In Figure 1.3, you can see the incidental vs. essential white spaces in a JSON text block:

Figure 1.3 – Incidental vs. essential white spaces in a JSON text block

In the left figure, you can see the incidental vs. essential white spaces when the closing delimiter is placed at the end of the content. In the middle figure, the closing delimiter was moved on its own line, while in the right figure, we also shifted to the left.The incidental (unessential) white spaces are automatically removed by the Java compiler. The compiler removes all incidental trailing spaces (for enforcing the same look in different text editors which may automatically remove trailing white spaces) and uses a special internal algorithm (dissected in the next problem) to determine and remove the incidental leading white spaces. Also, it is important to mention that the line containing the closing delimiter is always part of this check (this is known as the significant trailing line policy).The essential white spaces are preserved in the final string. Basically, as you can intuit from the previous figures, the essential white spaces can be added in two ways as follows:

by shifting left the closing delimiter (when this delimiter is on its own line) by shifting right the content (by explicitly adding white spaces or by using helper methods dedicated to controlling indentation)

Shifting the closing delimiter and/or the content

But, let’s start our dissertation with the following code:

The white spaces highlighted with “–” sign represents incidental leading white spaces (there are no incidental trailing white spaces), while the white spaces highlighted with the “+” sign represent essential white spaces that you’ll see in the resulting String. If we shift right the whole content while the closing delimiter is at the end of the content then the explicitly added white spaces are considered incidental and are removed by the compiler:

But, if we move the closing delimiter on its own line (vertically aligned with the opening delimiter) and shift right only the content then we obtain essential white spaces that remain in the final string:

Of course, we can add the same essential white spaces by shifting left the closing delimiter:

Moreover, we can adjust each line of text by manually adding white spaces as in the following example:

Next, let’s see some helper methods useful for indentation purposes.

Using indentation methods

Starting with JDK 12, we can add essential white spaces to a literal string via the String.indent(int n) method, where n represents the number of white spaces. This method can also be applied to indent the whole content of a text block as follows:

Obviously, the white spaces added via indent() are not visible in the code editor of the IDE, by they are highlighted here via the “*” sign just to imagine the effect on the final string. However, when indent() is used, a new line is also appended even if the closing delimiter is at the end of the content. In this context, moving the closing delimiter on its own line results in the same effect, so don’t expect to see two new lines appended. Of course, fill free to practice the bundled code for the real experience.The indent() method may be useful to align a block of content that contains lines of text placed at the same level of indentation. Like the poem that follows:

If we manually add white spaces in front of each line of the poem then the compiler will remove them, so no essential white spaces could be added globally. We can move the closing delimiter on its own line and shift it to the left or shift right the content to obtain the desired essential white spaces. But, in such a case, you still need to remove the new line that is added as the effect of moving the closing delimiter on its own line. The easiest way to do this is via the JDK 14 new escape sequence, \. By adding this escape sequence at the end of a line, we instruct the compiler to suppress appending a new line character to that line:

While this escape sequence (\) is dissected in Problem 5, Using text block just for readability, let’s see a few approaches based on string API.Before JDK 11, we can remove this line via a simple regular expression such as replaceFirst(“\\s++$”, “”), or rely on a third-party helper such as the Apache Commons StringUtils.stripEnd() method. However, starting with JDK 11, we can achieve this goal via String.stripTrailing() as follows:

Now, the content block is indented as the effect of shifting left the closing delimiter, and the automatically added new line is removed thanks to stripTrailing() method.

Next to stripTrailing(), JDK 11 also comes with stripLeading() and strip(). And, starting with JDK 15, we have stripIndent() which removes the leading and trailing white spaces exactly as the compiler does.

However, starting with JDK 12, we can use String.indent(int n) which saves us from adding white spaces manually:

It is time to step forward and dissect the algorithm for removing incidental white spaces.

Leave a Reply

Your email address will not be published. Required fields are marked *