AppyPrinciplesGetting started
appy.pod Writing ODT templates The « text » function

This section is about rendering pure text into a POD result. Rendering chunks of XHTML texts is covered by the previous section.

By "pure text", I mean standard ASCII text, or text encoded using UTF-8 or other similar encodings. UTF-8 is the base onto which Appy is built.

Such text contains only standard ASCII or encoding-specific characters, plus some special characters like tabs (\t) or carriage returns (\n and possibly \r).

Preamble: inserting pure text via a POD expression

First of all, note that variables containing pure text can simply be rendered using standard POD expressions.

Suppose you have the following template:

If variable chunk contains:

chunk = "Line 1\n2nd line\n\rThird line"

, you will get this result:

Several element must be commented here.

  • Sequences \n or \n\r are treated the same way.
  • The chunk of text has been inserted into the target paragraph. The resulting POD still contains a single paragraph; carriage returns have been converted to the ODF equivalent of <br/> tags (ie, <text:line-break/> tags). This can be seen on the previous screenshot, showing formatting marks: the 2 first lines end up with converted carriage returns, where the third line ends up with a real paragraph end symbol. While this may not be a problem in most cases, this approach has the following drawbacks.
    • When using justfied text, the last paragraph line may be gracelessly stretched.
    • You don't have any control over the possibility to apply styles to the inserted text.

For those reasons, a specific text function is available.

The « text » function

Inserting pure text via the text function allows you to have more control on how the text will be formatted. Here is an example.

If you execute this template with variable chunk from the previous example, you will get this result.

This approach differs from inserting pure text via a POD expression:

  • as usual with statements, the part of the document being the target of the statement is completely removed and replaced with the statement's result;
  • every time a carriage return is encountered, a new paragraph is created. The formatting marks show that the POD result contains 3 real paragraphs.

Styling pure text in the POD result

A first, simple way to apply style to the pure text as inserted into the POD result is via the tag parameter, allowing to specify a sequence of single-letter HTML tags.

If, for example, you want the whole chunk to appear in bold and italic, call the text function with this parameter:

The result will be the following.

If you want more control, you may want to define CSS classes to the paragraphs. As for the xhtml function, for every such class, if a style with the same name exists in the POD template, it will be applied to the dumped paragraph.

3 different classes ma be defined:

  • one for the first paragraph (parameter firstCss);
  • one for the last paragraph (parameter lastCss);
  • one for any other paragraph (parameter otherCss).

There is no replacement for missing parameters: if, for example, you do not specify a CSS class in parameter firstCss, the first paragraph will not get the CSS class defined in parameter otherCss. All parameters must be explicitly passed, even if they all refer to the same CSS class.

Having the possibility to define 3 different classes is convenient, especially if you want to insert additional space before and after the complete chunk of pure text. Indeed, in that case, firstCss may refer to a style defined with a top margin, lastCss may refer to a style defined with a bottom margin, while otherCss may be None or mapped to a style defining no margin at all.

To tell the truth, internally, the text function produces a chunk of XHTML code and calls the xhtml function. Suppose you call the text function that way:

do text
from text(chunk, firstCss='first', otherCss='other', lastCss='last')

The input chunk:

chunk = "Line 1\n2nd line\n\rThird line"

will be internally converted the XHTML chunk:

<p class="first">Line 1</p>
<p class="other">2nd line</p>
<p class="last">Third line</p>

This is why you may also go further with styling, by passing a styles mapping to the text function, in attribute stylesMapping, exactly as you would do with the xhtml function.


The text function as available in the default POD context corresponds to method renderText defined on class Renderer.

    def renderText(self, s, prefix=None, tags=None, firstCss=None,
                   otherCss=None, lastCss=None, stylesMapping={}):
        '''Renders the pure text s in the ODF result. For every carriage
           return character present in s, a new paragraph is created in the
           ODF result.'''

        # prefix, if passed, must be a string that will be inserted before
        # s's first line, followed by a tab.

        # tags can be a sequence of XHTML single-letter tags (ie, "bu" for
        # "bold" + "underline"). If passed, formatting as defined by these
        # letters will be applied to the whole s (the prefix excepted).

        # You may go further by applying CSS classes to the paragraphs produced
        # by s's conversion to ODF. For every such class, if a style having
        # the same name is found on the ODF template, it will be applied to the
        # corresponding paragraph. The CSS class:

        #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        # defined in      | will be
        # attribute ...   | applied to ...
        #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        # firstCss      | the ODF result's first paragraph;
        # lastCss       | the ODF result's last paragraph;
        # otherCss      | any other paragraph in between.
        #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

        # Moreover, because, internally, s is converted to a chunk of XHTML
        # code, and passed to method renderXhtml, a stylesMapping can be
        # passed to renderText, exactly as you would do for renderXhtml.
        # Determine the prefix to insert before the first line