Showing posts with label Java 13. Show all posts
Showing posts with label Java 13. Show all posts

Saturday, March 06, 2021

Using -Xlint:text-blocks compiler option

Consider this piece of code:

public class Main {

    public static void main(String[] args) {

        String poemTextBlock = """
                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.    
                """;
        System.out.println(poemTextBlock);
    
    }
}

This seemingly perfect code when executed produces the following output




The indentation and white spaces included within the string produced by this text block is not what could have been intended. 

To help identifying this not so obviously visible issue, -Xlint:text-blocks compiler option was introduced.

When compiling the code with this option, it throws out warning messages highlight issues with white spaces used within the text block. 

It specifically shows these two warning messages

  • inconsistent white space indentation - shown if there is inconsistency in the incidental white space characters across the lines within text block
  • trailing white space will be removed - shown if a trailing space is present in any of the lines within the text block that would stripped off

Try compiling the above program with -Xlint:text-blocks flag included as in the command below

javac -Xlint:text-blocks Main.java

This gives the two warning messages, as shown below 

Main.java:5: warning: [text-blocks] inconsistent white space indentation
                String poemTextBlock = """
                                       ^
Main.java:5: warning: [text-blocks] trailing white space will be removed
                String poemTextBlock = """
                                       ^
2 warnings



Sample code used in this post can be downloaded from https://github.com/ashokkumarta/awesomely-java/tree/main/2021/03/Language-Features/Text-blocks/Using--Xlinttext-blocks-compiler-option

New escape sequence - \

This new escape sequence "\<line terminator>" can be used when we do not want to include a new line character at the end of a line within a text block. 

When used, this escape sequence effectively suppresses the new line character that gets implicitly included at the end of that line.

Below code shows the usage of this escape sequence

public class Main {

    public static void main(String[] args) {

        String poemTextBlock = """
                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.
                """;
        System.out.println(poemTextBlock);
    
    }
}

In this code, we have used the "\<line terminator>" escape sequence on 1st and 3rd lines within the text block. 

This suppresses the new line character on the 1st and 3rd lines and produces the below output


When using this, take care to ensure that the "\" at the end of the line is immediately followed by the line terminator without leaving any blank spaces after the "\". 

Leaving a blank space at the end accidentally will throw a compilation error stating "illegal escape character"

 

Sample code used in this post can be downloaded from https://github.com/ashokkumarta/awesomely-java/tree/main/2021/03/Language-Features/Text-blocks/New-escape-sequence-2

New escape sequence - \s

Two new escape sequences got introduced with text blocks

  • \s
  • \<line terminator> 

First lets see how to use "\s"

"\s" is the escape sequence for adding a space character within the string. It can be used in both regular strings and in text blocks. 

Below code shows the usage of "\s" when used within a text block and a regular string. 

public class Main {

    public static void main(String[] args) {

        String poemTextBlock = """
                The\swoods\sare\slovely,\sdark\sand\sdeep\s""";
        String poemString = "The\swoods\sare\slovely,\sdark\sand\sdeep\s";

        System.out.println(poemTextBlock);
        System.out.println(poemString);
    
    }
}


Strings produced by both this text block and the regular string expression are the same. The output is shown below 




We can see that each of the "\s" is replaced by a single space, including one at the end of the line (Remember trailing spaces at the end of the line gets stripped off in text blocks, but not when escape sequence equivalent is used for providing space)

"\s" can be used to include trailing spaces within text block, The escape sequence approach or fencing approach can be used with "\s" to include the needed spaces as explained here. All the techniques given in this post for the usage of octal escape sequence "\040" can be applied with "\s" as well.

We will see the other new escape sequence introduced text blocks - \<line terminator> 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/New-escape-sequence-1

Techniques for including trailing whitespaces into text blocks

 Trailing whitespaces can be included in a text block using one of the following approaches

Character substitution 

Here we include a special character in the text block for trailing whitespaces and replace them with space after the text block is processed by the compiler. Code for this shown below

public class CharacterSubstitution {

    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>""".replace('#',' ');
    
        System.out.println(poemTextBlock);
    }
}

Character fencing

Here we including the needed trailing spaces. But instead of ending the line with the space, include a special fence character at the end so that the spaces are not considered trailing spaces and hence are not stripped away. 

We remove this fence character after the text block is processed using the replace method as shown in the code below

public class CharacterFencing {

    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>""".replace("#\n","\n");
    
        System.out.println(poemTextBlock);
    }
}

Escape sequence for space:

Here we use the octal escape sequence for space, in the text block where we need trailing spaces. Sample code for this shown below

public class EscapeSequence {

    public static void main(String[] args) {

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

Note that unicode escape sequence for space cannot be used as they are translated prior to lexical analysis where as octal escape sequence gets processed after lexical analysis. 

What exactly happens if we use unicode escape sequence inside of text block? That's a topic to explore in a separate post. 

Since the escape sequences gets processed later in the processing, octal escape sequence for space can be used as a fencing character to include trailing blank spaces. Here we do not have to replace the fencing character as it is also a space character that we want to include. 

The below code shows this. Here we use two regular white space characters followed by a octal whitespace escape sequence to include one more additional whitespace. 
public class EscapeSequence1 {

    public static void main(String[] args) {

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

The output here includes three whitespaces at the end lines 4 to 7. 







So far, we have used only space character in all our examples. But tab character also represent whitespace and they are widely used for code indentation and formatting. How does the tab character behave when used within a text block? We will explore that in our 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/Techniques-for-including-trailing-whitespaces

Escape sequence in text blocks - \"

So we want to include three double quotes in the string contained within a text block. 

Say if we want the processed string to be as the one shown here

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.

We can use three double quotes with escape sequence like \""". Here \""" is not a new escape sequence. In fact, the escape sequence characters here is only \" - the escape sequence for double quote. The next two double quotes are the actual characters included in the string. 

The escaped double quote can be used for any of the three double quotes. The below code shows this. This code produces the same output string that is shown above.

public class Main {

    public static void main(String[] args) {

        String poemTextBlock = """
                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.
                """;
        System.out.println("Text block: \n"+poemTextBlock);

    }
}

In this program, we escape the double quote at different positions in each line and for the last line, we use escape sequence for each of the three double quote characters. 

Where we need to include three or more continuous double quotes within a text block, we will have to use escape sequence so as to avoid having three continuous double quotes which will end the text block.

Below code includes five continuous double quote before the word 'lovely'

        String poemTextBlock = """
                The woods are \"""\""lovely, dark and deep,
                """;



Sample code used in this post can be downloaded from https://github.com/ashokkumarta/awesomely-java/tree/main/2021/03/Language-Features/Text-blocks/Escape-sequences-in-text-blocks-2

Friday, March 05, 2021

Escape sequences in text blocks - '\n'

All the escape sequences that can be used with the String, can be used in text blocks as well. 

But some escape sequences are not required to be used within text blocks. The actual character can be used directly instead. The most common escape sequence that can and should be avoided where possible in text blocks is the new line character '\n'.

At the end of each line of the multi-line string literal represented by the text block, new line character '\n' is included by Java compiler when processing the text block. 

We saw many examples of this in the previous posts.

There are a few tricks that we need to be aware of. First, lets see what happens if we explicitly include '\n' at the end of each line inside the text block

Below code shows a regular text block and the same with '\n' included at the end of each line 

public class Main {

    public static void main(String[] args) {

        String poemTextBlock = """
                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.
                """;

        String poemTextBlockWithNewLine = """
                The woods are lovely, dark and deep,\n
                But I have promises to keep,\n
                And miles to go before I sleep,\n
                And miles to go before I sleep.
                """;

        System.out.println("Text block: \n"+poemTextBlock);
        System.out.println("Text block with new line: \n"+poemTextBlockWithNewLine);

    }
}

The '\n' at the end of each line introduces an additional new line between each of the lines and produces the output shown below


A new line character '\n' is not a whitespace and is not stripped away by the Java compiler when processing the text block.

Now consider the below snippet of code.  

Here we have two '\n' on the first line of text block, with a tab included in between.  

How does this get processed? There are four leading tab spaces in each of the lines of the text block, but between the two new line characters there is just one tab space. Does this impact the indentation of the lines making the text block. More specifically, will this modify the position of left margin for incidental whitespace stripping? 

The above text block when printed has a value shown below


As you can see, the left margin is not affected by the whitespaces included between '\n' characters. Also note the presence of tab characters at the beginning of the 2nd line, indicating it is preserved and has not got stripped away in the processing. 

This is because the escape translation happens as a last step in the compilation process. 

The left margin gets identified and incidental whitespaces gets stripped away before '\n' escape sequence gets processed in our example. Escape sequence processing happens as a last step, making the '\n' characters include additional line feeds within the string. 

This is also the reason why we may have to use '\n' explicitly - to include empty line with specific no. of whitespace characters without impacting the margin of other lines within a text block. 

There is no other way of doing this when defining a text block.   


Sample code used in this post can be downloaded from https://github.com/ashokkumarta/awesomely-java/tree/main/2021/03/Language-Features/Text-blocks/Escape-sequences-in-text-blocks-1

Thursday, March 04, 2021

Normalization of platform specific line terminator characters

Line terminator character is platform specific. 

You can find the line termination character for your platform using System.lineSeparator()API call

On my windows machine, I get "\r\n" as the line termination character. 

jshell> System.lineSeparator()
$1 ==> "\r\n"

Unix & Linux uses "\n" as line termination character & some older versions of Mac OS uses "\r" as line termination character.

This poses a few issues with handling multi-line string literals represented by text blocks

  • Some editor used may automatically change the line termination character
  • When the source file gets edited on different platforms, there is a chance of getting different line termination characters getting used within the same text block. 

To avoid these issues, Java compiler normalizes line termination character inside the multi-line string literal in text blocks to '\n' while processing. So, all the different line termination characters "\r", "\r\n" and "\n" becomes "\n" after processing a text block.

Let us check this with the below program:


Code is shown as an image to make the line termination characters visible. Here the line termination character is "\r\n" represented by CR|LF

This produces the following output

Comparing with \n:true
Comparing with \r\n:false

indicating that \r\n line termination character in the source code is converted to \n after the text block is processed.

Below is the version of the code for copy/pasting if needed. 

public class Main {

    public static void main(String[] args) {

        String poemTextBlock = """
                 And miles to go before I sleep.
                 """;
 
        System.out.println("Comparing with \\n:" + "And miles to go before I sleep.\n".equals(poemTextBlock));
        System.out.println("Comparing with \\r\\n:" + "And miles to go before I sleep.\r\n".equals(poemTextBlock));
    }
}

In the next post, we will see if and how of using escape sequences within text blocks


Sample code used in this post can be downloaded from https://github.com/ashokkumarta/awesomely-java/tree/main/2021/03/Language-Features/Text-blocks/Normalization-of-platform-specific-line-terminator-characters

Wednesday, March 03, 2021

Tab character in text blocks

The problem with tab character is that there is no standard definition for how many spaces it represents. Different editors use different no. of spaces to display the tab character and most editors give this choice to the users to configure it as per his/her preference.

For this reason, Java treats tab characters as of size 1 when processing the text block. Irrespective of any no. of spaces that a tab may occupy when displayed in your editor, when the text block gets processed by the Java compiler, its whitespace size is counted as 1.

Consider the code snippet shown below 


Tab character here is represented by a long arrow ---->

In the editor I use, tab character occupies 4 spaces. When looking at this code in the editor, it has a well indented text block defined, as 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);
    }
}

But when executed, the output of the above program is


Since Java compiler considers only one character size for tabs, lines 4-7 contains only 7 leading whitespace characters (7 tab characters). 

The visibly least indented line 1 contains 16 whitespace characters (16 space characters). 

To the Java compiler, lines 4-7 are least indented and hence the start of these lines is taken as the left margin. 

Note that the Java compiler does not convert the tab character into a space character when processing. It only counts the size of the whitespaces represented by the tab character as 1 for the purpose of fixing the left margin and stripping away the incidental white spaces from text block.

Below code demonstrates this


This code has different no. of tabs for each of the lines 5, 6, 7 & 8. 

Line 5 has the least no. of tabs and is taken as the left margin by the Java compiler. 

When this text block is printed, it produces the below output, indicating that the tab characters are preserved and when printed on console, they are represented by as many spaces as per the console configuration


Full code for the above example from my editor for your reference. 

public class Main1 {

    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: While copy/pasting the code samples from this post, you might have to edit the code to make sure that tab and space characters are correctly pasted for you to see it working as explained here. 


Sample code used in this post can be downloaded from https://github.com/ashokkumarta/awesomely-java/tree/main/2021/03/Language-Features/Text-blocks/Tab-character-in-text-blocks


Tuesday, March 02, 2021

Techniques for including leading white spaces into text blocks

We saw one approach for controlling leading indentation by moving the ending three double quotes position as required. 

But a scenario in which this approach would not work is when we do not want a new line after the last line of the text block. The code then becomes

        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>""";

Here we will not be able to use the position of """ to dictate leading indentation required. 

We will have to use the indent() method on string to provide the necessary indentation. Code for this  shown in the below sample 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>""".indent(8);
    
        System.out.println(poemTextBlock);
    }
}


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


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

Monday, March 01, 2021

Text Block Syntax - Deep Dive

We mentioned in the previous post about the subtle difference between the string formed through Text Block syntax and the one formed through regular String syntax. 

Lets examine that through this sample code

public class Main {

    public static void main(String[] args) {
        
        String poemTextBlock = """
                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.
                """;
        
        String poemString = "The woods are lovely, dark and deep,\n"
                + "But I have promises to keep,\n"
                + "And miles to go before I sleep,\n"
                + "And miles to go before I sleep.";
        
        System.out.println("Text Block: "+poemTextBlock);
        System.out.println("String: "+poemString);
        
        if (poemString.equals(poemTextBlock)) {
            System.out.println("Textblock and String are equal");
        } else {
            System.out.println("Textblock and String are NOT equal");
        }

    }
}.

Here we are comparing the two strings and printing if they are equal or not. 

Output of this code is 

Text Block: 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.

String: 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.
Textblock and String are NOT equal

Yes. They are not equal. It is due to the new line at the end of the string formed by the Text Block. 

The strings will show as equal when we form the text block string, with the ending three double quotes on the same line as shown below

        String poemTextBlock = """
                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.""";

This avoids introducing a line terminator (\n) character to the last line of the string. 

But then, what about the first line. Wouldn't the code above introduce a \n before the first line? 

Turns out that the three double-quote and a line terminator marks the beginning of the text block. We cannot start a text block content in the same line as that of the beginning three double quotes. 

Below code would throw a compile time error

        String poemTextBlock = """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.""";

So a text block begins from the next line of the beginning three double-quotes. And the placement of ending three double-quotes on the same line as the last line of the text block avoids adding a line terminator to the last line. 

What about the spaces used for indentation of the text block content? Would those spaces become part of the text block content? 

We see from the code above that they have not been part of the content in this example. We will explore how the indentation behaves in the text block in our 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/Text-Block-Syntax

Sunday, February 28, 2021

The Text Blocks

Java 13 introduced Text Blocks as a preview feature. It got enhanced and continued as a preview feature in Java 14 release. Java 15 has made this a permanent feature of the language. 

So what is a text block?

Short answer is it is a multi-line string with special syntax. The purpose of introducing it is to simplify and minimize the code required to create a multi-line strings.

Assume for example, we want to capture this famous last stanza of Robert Frost's poem as a Java String. 

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.

Below code snippet captures this

        String poemString = "The woods are lovely, dark and deep,\n"
                + "But I have promises to keep,\n"
                + "And miles to go before I sleep,\n"
                + "And miles to go before I sleep.";

But this has multiple strings appended through + operator. Also note the '\n' included at the end of each line to capture the new line into the String. 

Things would get more complicated for lengthy string literals, which is not uncommon with HTMLs,  XMLs & JSONs often getting embedded in code. And not to forget the performance implication of many String appends leading to usage of StringBuilder and StringBuffer for optimization. 

Wouldn't it be better if we can get rid of this and have a simpler syntax to capture such multi-line strings? 

This essentially is what the Text Block feature provides. 

Below snippet shows how to use a Text Block to capture the same String

        String poemTextBlock = """
                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.
                """;

We start and end a Text Block with three double quotes as in """. Format of the text inside of the Text Block is preserved and there is no need to add additional '\n' for the new lines. 

This will greatly simplify the code when embedding HTML, XML, JSON, SQL, JavaScript or other such code snippet in a string literal. 

The full code is embedded below

public class Main {

    public static void main(String[] args) {
        
        String poemTextBlock = """
                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.
                """;
        
        String poemString = "The woods are lovely, dark and deep,\n"
                + "But I have promises to keep,\n"
                + "And miles to go before I sleep,\n"
                + "And miles to go before I sleep.";
        
        System.out.println("Text Block: "+poemTextBlock);
        System.out.println("String: "+poemString);

    }
}

Note that there is a minor difference in the values represented by poemString & poemTextBlock in the above code.

Try to figure out that difference... We will uncover that in our next post.


Sample code used in this post can be downloaded from https://github.com/ashokkumarta/awesomely-java/tree/main/2021/02/Language-Features/Text-blocks/The-Text-Blocks