SeamFramework.orgCommunity Documentation

Chapter 17. Seam Text

17.1. Basic fomatting
17.2. Entering code and text with special characters
17.3. Links
17.4. Entering HTML
17.5. Using the SeamTextParser

Collaboration-oriented websites require a human-friendly markup language for easy entry of formatted text in forum posts, wiki pages, blogs, comments, etc. Seam provides the <s:formattedText/> control for display of formatted text that conforms to the Seam Text language. Seam Text is implemented using an ANTLR-based parser. You don't need to know anything about ANTLR to use it, however.

Here is a simple example:

It's easy to make *emphasis*, |monospace|,
~deleted text~, super^scripts^ or _underlines_.

If we display this using <s:formattedText/>, we will get the following HTML produced:

It's easy to make <i>emphasis</i><tt>monospace</tt>
<del>deleted text</del>, super<sup>scripts</sup> or <u>underlines</u>.

We can use a blank line to indicate a new paragraph, and + to indicate a heading:

+This is a big heading
You /must/ have some text following a heading!
++This is a smaller heading
This is the first paragraph. We can split it across multiple 
lines, but we must end it with a blank line.

This is the second paragraph.

(Note that a simple newline is ignored, you need an additional blank line to wrap text into a new paragraph.) This is the HTML that results:

<h1>This is a big heading</h1>
You <i>must</i> have some text following a heading!
<h2>This is a smaller heading</h2>
This is the first paragraph. We can split it across multiple 
lines, but we must end it with a blank line.

This is the second paragraph.

Ordered lists are created using the # character. Unordered lists use the = character:

An ordered list:
#first item
#second item
#and even the /third/ item

An unordered list:

=an item
=another item

An ordered list:
<li>first item</li>
<li>second item</li>
<li>and even the <i>third</i> item</li>

An unordered list:

<li>an item</li>
<li>another item</li>

Quoted sections should be surrounded in double quotes:

The other guy said:
"Nyeah nyeah-nee 
/nyeah/ nyeah!"

But what do you think he means by "nyeah-nee"?

The other guy said:
<q>Nyeah nyeah-nee
<i>nyeah</i> nyeah!</q>

But what do you think he means by <q>nyeah-nee</q>?

Special characters such as *, | and #, along with HTML characters such as <, > and & may be escaped using \:

You can write down equations like 2\*3\=6 and HTML tags
like \<body\> using the escape character: \\.

You can write down equations like 2*3=6 and HTML tags
like &lt;body&gt; using the escape character: \.

And we can quote code blocks using backticks:

My code doesn't work:

`for (int i=0; i<100; i--)

Any ideas?

My code doesn't work:

<pre>for (int i=0; i&lt;100; i--)

Any ideas?

Note that inline monospace formatting always escapes (most monospace formatted text is in fact code or tags with many special characters). So you can, for example, write:

This is a |<tag attribute="value"/>| example.

without escaping any of the characters inside the monospace bars. The downside is that you can't format inline monospace text in any other way (italics, underscore, and so on).

A link may be created using the following syntax:

Go to the Seam website at [=>].

Or, if you want to specify the text of the link:

Go to [the Seam website=>].

For advanced users, it is even possible to customize the Seam Text parser to understand wikiword links written using this syntax.

Text may even include a certain limited subset of HTML (don't worry, the subset is chosen to be safe from cross-site scripting attacks). This is useful for creating links:

You might want to link to <a href="">something
cool</a>, or even include an image: <img src="/logo.jpg"/>

And for creating tables:

    <tr><td>First name:</td><td>Gavin</td></tr>
    <tr><td>Last name:</td><td>King</td></tr>

But you can do much more if you want!

The <s:formattedText/> JSF component internally uses the org.jboss.seam.text.SeamTextParser. You can use that class directly and implement your own text parsing, rendering, or HTML sanitation procedure. This is especially useful if you have a custom frontend for entering rich text, such as a Javascript-based HTML editor, and you want to validate user input to protect your website against Cross-Site Scripting (XSS) attacks. Another usecase are custom wiki text parsing and rendering engines.

The following example defines a custom text parser that overrides the default HTML sanitizer:

public class MyTextParser extends SeamTextParser {

    public MyTextParser(String myText) {
        super(new SeamTextLexer(new StringReader(myText)));
            new DefaultSanitizer() {
                public void validateHtmlElement(Token element) throws SemanticException {
                    // TODO: I want to validate HTML elements myself!
    // Customizes rendering of Seam text links such as [Some Text=>]
    protected String linkTag(String descriptionText, String linkText) {
        return "<a href=\"" + linkText + "\">My Custom Link: " + descriptionText + "</a>";
    // Renders a <p> or equivalent tag
    protected String paragraphOpenTag() {
        return "<p class=\"myCustomStyle\">";
    public void parse() throws ANTLRException {

The linkTag() and paragraphOpenTag() methods are just some of many you can override to customize rendered output. These methods generally return String. See the Javadoc for more details.

Also consult the Javadoc of org.jboss.seam.text.SeamTextParser.DefaultSanitizer for more information on what HTML elements, attributes, and attribute values or filtered by default.