Tuesday, March 02, 2021

Incidental and essential white spaces in text blocks

Consider the below piece of code containing a text block declaration

String poemTextBlock = """               
    <html>
        <body>
            <pre>
                The woods are lovely, dark and deep,   
                But I have promises to keep,   
                And miles to go before I sleep,   
                And miles to go before I sleep.
            </pre>
        </body>
    </html>
    """;

From this, can we infer how the string in the text block gets formatted for spaces. 

Would all leading spaces get into it? 

And what about trailing spaces if there are any, included at the end of some of the lines?

Lets first see what and how the spaces are contained within the above block of code. 

For that, we will refer to the below screen grab from the editor, with whitespace visibility set to 'Yes'


Spaces are indicated by dot (.) and end of line by CRLF 

Note that there are some trailing spaces on lines 5, 6 & 7.

So with all these leading and trailing spaces, how does the text block format the string contained in it?

We do not want it to retain all the spaces as-is

  • Trailing spaces may not be intentional and they are not even visible in the editors to check and correct. 
  • A part of the leading spaces were introduced just to align with the indentation of the surrounding code. Changing indentation of the code would result in the content of the text block getting changed.

And we do not want it to simply remove all leading and trailing spaces either. 

This would make the final string to be as shown below without indentation, which definitely is not what we want. 



To understand how Java handles leading & trailing whitespaces contained within text block, lets first check what are incidental and essential whitespaces  

Incidental whitespace
These are whitespaces that are 
  • To the left of the least intended line within the text block
  • All the trailing whitespaces on each line

Essential whitespace
Leading whitespaces on each line that are not incidental are essential whitespaces. They are essential for providing the indentation of the text contained within the text block. 

Incidental whitespaces are stripped away and essential whitespaces are retained by the Java compiler when processing a text block. 

This makes the text block represented in the above code, formatted as shown below after processing


Note that all the incidental whitespaces are removed but essential white spaces are retained in the processed text. 

Full code to test this sample shown below: 
public class Main {

    public static void main(String[] args) {

        String poemTextBlock = """
                <html>
                    <body>
                        <pre>
                            The woods are lovely, dark and deep,
                            But I have promises to keep,
                            And miles to go before I sleep,
                            And miles to go before I sleep.
                        </pre>
                    </body>
                </html>
                """;
        System.out.println(poemTextBlock);
    }
}

Note that the ending three double quotes is also considered when establishing the left margin for incidental whitespace

Below code fragment would produce a string with all leading white spaces included as the ending three double quotes are aligned to the left most margin

        String poemTextBlock = """
                <html>
                    <body>
                        <pre>
                            The woods are lovely, dark and deep,
                            But I have promises to keep,
                            And miles to go before I sleep,
                            And miles to go before I sleep.
                        </pre>
                    </body>
                </html>
        """;

Above code will produce a string that is formatted as shown below, with the leading spaces included


We have seen in this post, how Java handles leading and trailing whitespaces by stripping away the incidental whitespaces. But what if we want to include leading or trailing whitespaces into text blocks? We will see how to do that in the next post.

 

Sample code used in this post can be downloaded from https://github.com/ashokkumarta/awesomely-java/tree/main/2021/03/Language-Features/Text-blocks/Incidental-and-essential-white-spaces

No comments:

Post a Comment