Editable LDMs
Mac/PC Text
RTF
Multiuser
Scrolling List Trigonometry
2D Vectors

Manipulating Formatted Text

Director's #text members have an .rtf property. This can be used to determine how the contents of the text member is formatted. This article will explain how to manipulate the RTF syntax so that you can produce text display effects which are not accessible through Lingo alone.
The article itself covers the theory. To see this in practice, I suggest you download the source file (Mac and Win), and look at the code. The download contains a movie that you will see later: this lets you modify the RTF data directly, and demonstrates all the different RTF syntax elements that can be used.

Rich Text Format

RTF stands for Rich Text Format. The full specifications for version 1.2 can be found at <URL>. Text members provide rather limited support for Rich Text Format syntax, so we won't be concerned with the full specifications here.
Basically, an RTF document is divided into two sections:

  • A header which defines the fonts, colors and stylesheets used in the document
  • The contents of the document. This includes tags for the formatting of individual chunks, as well as the text itself.

Let's have a look at the rtf description of an empty document. Here's an example run on a Macintosh:

put new(#text).rtf
-- "{\rtf1\mac\deff3 {\fonttbl{\f3\fswiss Geneva;}}{\colortbl\red0\green0\blue0;}{\stylesheet{\s0\fs24 Normal Text;}}\pard \f3\fs24\par}
"

Here's what you get for the same command on Windows:

put new(#text).rtf
-- "{\rtf1\ansi\deff0 {\fonttbl{\f0\fswiss Arial;}}{\colortbl\red0\green0\blue0;}{\stylesheet{\s0\fs24 Normal Text;}}\pard \f0\fs24\par}
"

To make this easier to analyze, let's break the output up into separate lines. I'll show the Windows version, with the differences in the Macintosh version on the right, in red:

Windows Differences on Macintosh
{\rtf1\ansi\deff0
{\fonttbl{\f0\fswiss Arial;}}
{\colortbl\red0\green0\blue0;}
{\stylesheet{\s0\fs24 Normal Text;}}
\pard \f0\fs24\par}
\mac\deff3
\f3\fswiss Geneva;

The RTF specifications allow for single white space characters (SPACE or RETURN characters) to be inserted at any point, so this clearer layout is just as valid as the original output. However, Director will not always parse an RTF string with more than one consecutive white space correctly. In certain circumstances, white space in the header may be applied at the beginning of the content. Moral: take care when you are building RTF strings on the fly.

Header

In this empty document, the contents are reduced to the following:

\pard \f0\fs24\par

We'll look it this in more detail shortly. The bulk of the RTF definition of the empty document is taken up by the header. Even the shortest chunk of RTF data needs to have a header. When you paste formatted text into an existing document, you may have to modify the header to ensure that it contains all the information needed to show the pasted text properly.

Character Set

{\rtf1\ansi\deff0 \mac\deff3

The first line defines the RTF version used for the document, the character set, and the default font. You should not have to modify this part of the header.

\rtf1 means RTF version 1. There is no point in altering this, as Director only understands (a subset of) version 1.
\ansi (or \mac) indicates which character codes are used for the various characters. When a text member is transferred from one platform to another, Director automatically performs the appropriate conversion, so you don't need to worry about this either.
\deffN (where N is an integer) indicates which of the entries in the following font table is used by default. Since different fonts are used by default on Macintosh and on Windows, the entries here are different

Font table

{\fonttbl{\f0\fswiss Arial;}} \f3\fswiss Geneva;

The second line defines all the fonts used in the current document. Since the document is currently empty, only a single font appears. Additional fonts will be defined in a similar way, inside curly brackets, with a terminal semi-colon.

\fonttbl means font table. Individial font definitions follow inside curly brackets.
{ indicates the beginning of a new font definition.
\f0 or \f3 is a unique identifier for the current font definition. Notice that the same identifier is used for the deffN default font.
\fswiss indicates which font family the current font belongs to. Swiss fonts are proportionally spaced sans serif fonts. The full range of font family values is shown in Table 1.
Arial or Geneva is the name of the preferred font. If it is not available on the end-user's machine, the most similar font from the same family will be used instead.
;} required to terminate the font definition.

The font table as a whole is enclosed in curly brackets.
If the text you are pasting uses fonts not defined in the target document, then you will need to add definitions for these new fonts to the font table.

Control word
Font Family Description
Examples
\fnil Unknown or default fonts (default)  
\froman Roman, proportionally spaced serif fonts

Times Roman
Palatino

\fswiss Swiss, proportionally spaced sans serif fonts Swiss
Arial
\fmodern Fixed-pitch serif and sans serif fonts Courier
Monaco
\fscript Script fonts Lucida Handwriting
\fdecor Decorative fonts Old English,
ITC Zapf Chancery
\ftech Technical, symbol, and mathematical fonts Symbol
\fbidi Arabic, Hebrew, or other bi-directional font Miriam

Table 1: Font Families

Color Table

{\colortbl\red0\green0\blue0;}  

The third line defines all the colors used in the current document. The entire color table is enclosed in curly brackets, but the individual color definitions are separated merely by semi-colons.
The full RTF specifications allow for separate sections of the document to have different background colors. Versions of Director up to and including 10.1 only support foreground colors, that is, colors used for the text itself. If you want to set a background color, then you must do so for the entire text member itself. You cannot apply individual background colors to different sections of a given member.

\colortbl means color table.
\red0\green0\blue0 Each color definition indicates a value from 0 - 255 for red, green and blue. There should be no spaces or other characters between the name of the color and the integer value. The color defined here is black. White would be \red255\green255\blue255. Director is not bothered what order you define the color components in. You can even leave a given component out altogether, and Director will consider that component to have a value of zero. This is enough to define a dark green: \green69.
; indicates the end of a color definition.

If the text you are pasting uses colors not defined in the target document, then you will need to add definitions for these new colors to the color table.

Style Sheet

{\stylesheet{\s0\fs24 Normal Text;}}  

You can define a number of paragraph styles for an RTF document. Perhaps the best way to demonstrate this would be to set the .html property of a text member. When you do this, Director automatically defines the style sheets for HTML body text, headers and other paragraph types.
I have arranged the output below so that it is easier to read. You might like to use this example to check your understanding of the Character Set, Font Table and Color Table definitions. Note that the colors that are defined are those for standard text, unvisited links, clicked links and visited links.

tTextMember = new(#text)
tTextMember.html = tTextMember.html
put tTextMember.rtf
-- "
{\rtf1\mac\deff20
{\fonttbl
{\f20\froman Times;}
{\f4\fmodern Monaco;}}
{\colortbl
\red0\green0\blue0;
\red0\green0\blue224;
\red224\green0\blue0;
\red224\green0\blue224;}
{\stylesheet
{\s0\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 HTML Body;}
{\s2\f4\fs20\ql\li0\ri0\fi0\sb0\sa0\sl0 HTML Pre-tag;}
{\s3\f4\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 HTML Teletype;}
{\s4\f4\fs18\ql\li0\ri0\fi0\sb0\sa0\sl0 HTML Code;}
{\s5\i\f4\fs18\ql\li0\ri0\fi0\sb0\sa0\sl0 HTML Code Def;}
{\s6\i\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 HTML Var;}
{\s7\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 HTML Blockquote;}
{\s8\i\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 HTML Address;}
{\s9\i\fs24 HTML Cite;}
{\s10\b\fs48 HTML Heading 1;}
{\s11\b\fs36 HTML Heading 2;}
{\s12\b\fs28 HTML Heading 3;}
{\s13\b\fs24 HTML Heading 4;}
{\s14\b\fs20 HTML Heading 5;}
{\s15\b\fs18 HTML Heading 6;}}
\pard \f20\fs24\par}"

Paragraph formats

{\s0\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 HTML Body;}  

Let's look at the definition for HTML Body text (above) more closely. Most of entries below are optional, and the values shown are those that will be used by default anyway.

{ indicates the beginning of a new style sheet definition
\s0 is a unique identifier for the current style sheet definition. Note that identifiers start with the value 0 and are numbered sequentially
\fs24 indicates the default font size for this style. For RTF, font sizes are defined in half points, so fs24 corresponds to a Lingo fontSize of 12, and fs18 corresponds to a Lingo fontSize of 9.
\ql indicates left alignment. Other possible values are \qr (right-aligned), \qj (justified) and \qc (centered).
\li0 indicates the left indent for paragraphs in this style. Values are in twips (twentieths of a pixel). There are 1440 twips to an inch. If the left indent is too great, no text may appear. For values over 32767 (nearly 23 inches), the left indent will be ignored.
\ri0 indicates the right indent for paragraphs in this style, measured in twips. If the right indent is too great, only a single character will appear on each line. For values over 32767, the right indent will be ignored.
\fi0 indicates the first indent for paragraphs in this style, measured in twips. The first indent may be negative, but this will only be visible if the line indent is positive.
\sb0 indicates the space before paragraphs in this style, measured in twips.
\sa0 indicates the space after paragraphs in this style, measured in twips.
\sl0 indicates the space between lines in paragraphs in this style, measured in twips. If the value is 0, then spacing is determined by the tallest character in the line. If it is positive then it gives the minimum spacing for the line (though a taller character may force the spacing to be greater). If it is negative, then it gives the absolute spacing for the line: taller characters will be clipped.
HTML Body is the name of this style. Styles are identified by the style def unique identifer (\sN), so this entry is not essential.
;} indicates the end of a style sheet definition.

If the text you are pasting uses styles not defined in the target document, then you will need to add definitions for these new styles to the style sheet.
The definition of the individual elements of a style do not have to be given in any particular order, so it may take some juggling to determine whether two definitions are in fact identical. Depending on balance you want to make between performance and file size, you may prefer to allow your application to create duplicate style definitions, rather than parsing existing definitions exhaustively. However, if you organize style definitions in a consistent manner, comparisons should be rapid, allowing you to optimize both performance and file size.

Document formatting

If you pasted RTF text from another application, you may find that your Director text member contains document formatting in its RTF property. This may look something like this:

\margl1800 \margr1800 \margt1440 \margb1440

This indicates that the top and bottom margins are one inch (1440 twips), with the left and right margins being 1.25 inches. Director ignores this information, and so can you.

What Director Ignores

To see just how much RTF data Director ignores, you can try the following test.

  1. In your favourite word processor, save a short piece of text as an RTF document.
  2. Use FileIO to read in the contents of the RTF document
  3. Set the .rtf property of a text member to the raw RTF source
  4. Display the .rtf property, as Director has adapted it in the Message window.

vFileIO = xtra("fileio").new()
vRTF = vFileIO.openFile(vFileIO.displayOpen(), 1)
vRTF = vFileIO.readFile()
vText = new(#text)
vText.rtf = vRTF

Here's what Director thinks the RTF of this text member should be:

put vText.rtf
-- "{\rtf1\mac\deff2010 {\fonttbl{\f2010\fnil Times New Roman;}{\f2001\fnil Arial;}}{\colortbl\red0\green0\blue0;\red0\green0\blue224;
\red224\green0\blue0;\red224\green0\blue224;}{\stylesheet{\s0\f2001\fs24 Normal;}}\margl1800 \margr1800 \margt1440 \margb1440 \pard
\f2010\fs24{\plain\f2001\fs24 In your favourite word processor, save a short piece of text as an RTF document.\par
}}"

Here's the RTF, as read in from a document created in RTF by Word. The parts in a bold type face are the strict minimum required by Director to display the text correctly.

put vRTF
-- "{\rtf1\mac\ansicpg10000\uc1 \deff0\deflang1033\deflangfe1033{\upr{\fonttbl{\f0\fnil\fcharset256\fprq2
{\*\panose 00020206030504050203}Times New Roman;}
{\f1\fnil\fcharset256\fprq2
{\*\panose 00020b06040202020202}Arial;}}
{\*\ud{\fonttbl{\f0\fnil\fcharset256\fprq2{\*\panose 00020206030504050203}Times New Roman;}
{\f1\fnil\fcharset256\fprq2{\*\panose 00020b06040202020202}Arial;}}}}
{\colortbl;\red0\green0\blue0;\red0\green0\blue255;
\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;
\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;
\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;
\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;
\red128\green128\blue128;\red192\green192\blue192;}
{\stylesheet{\sb120\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0
\lin0\itap0 \f1\lang2057\cgrid \snext0 Normal;}
{\*\cs10 \additive Default Paragraph Font;}}
{\info
{\title In your favourite word processor, save a short piece of text as an RTF document}
{\author James Newton}{\operator James Newton}
{\creatim\yr2004\mo11\dy25\hr11\min10}{\revtim\yr2004\mo11\dy25\hr11\
min10 {\version1}{\edmins0}{\nofpages1}{\nofwords0}
{\nofchars0}{\*\company OpenSpark Interactive Ltd}
{\nofcharsws0}{\vern16553}}\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc
\dntblnsbdb\nospaceforul\formshade\horzdoc\dghspace180\dgvspace180
\dghorigin1701\dgvorigin1984\dghshow0\dgvshow0\jexpand\viewkind4
\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp
\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule
\fet0\sectd \linex0\headery708\footery708\colsx708\endnhere
\sectdefaultcl
{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta.}}
{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta.}}
{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta.}}
{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta)}}
{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}
{\pntxta )}}
{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}
{\pntxta )}}
{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}
{\pntxta )}}
{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang
{\pntxtb (}
{\pntxta )}}
{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}
{\pntxta )}}
\pard
\plain\sb120\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0
\lin0\itap0 \f1\lang2057\cgrid {
In your favourite word processor, save a short piece of text as an
RTF document.
}{
\par }}"

Director is not entirely consistent in the way it interprets RTF. Here's the RTF that I get if I copy the formatted string in Word and paste it into a text member in Director. If you compare this to the value for vText.rtf shown above, you may notice that:

  • There is an additional font definition (in italics)
  • There is only one color definition
  • The stylesheet is simplified.
  • Document margin information is omitted.

{\rtf1\mac\deff3 {\fonttbl{\f3\fswiss Geneva;}{\f2010\fnil Times New Roman;}{\f2001\fnil Arial;}}{\colortbl\red0\green0\blue0;}{\stylesheet
{\s0 Normal;}}\pard \f3\fs24{\pard \plain\f2001\fs24\sb120 In your favourite word processor, save a short piece of text as an RTF document.
\par}}

The display is the same but the RTF data is different. The moral of the story is: overkill is easy. If you don't need a particular RTF expression in the header, don't include it. But if you do include it, it doesn't do any harm (unless it's badly formatted).
You can often get away with less than Director thinks is the strict minimum. The following (in bold in the Word RTF above) is enough for Director to display the formatted text correctly:

{\rtf1\mac\deff0 {\fonttbl{\f0\fnil Arial;}}{\colortbl\red0\green0\blue0;}}\pard In your favourite word processor, save a short piece of text as an RTF document.}

Content

Before you can see any of the elements described above in action, you will need to add some content to your text member.
Here's a movie that lets you modify the header and content data separately. Experiment with changing the font table, the color table and the style sheet, and try applying these options to the content. Try adding white space (SPACE and RETURN characters) to the header in a variety of places, to see where this has an impact on the display.

Source:
Macintosh
Windows

Test Cases

The movie contains a popup menu containing prepared situations for you to test.. Selecting an item from this menu will set the contents of the Character Set, Font, Color and Style Sheet and Contents fields, and refresh the RTF text member, overwriting any changes that you may have previously made.
Explore the different cases to get a better understanding of how Director copes with the RTF syntax.

Special characters

There must be a space between the last character in a mark-up string and the visible content.

RTF:

\qc Centered Text\par\qlThe first word will be ignored, as will the 'align left' tag.

Display:

Centered Text
first word will be ignored, as will the 'align left' tag.

As you might have guessed, curly brackets {} and backslashes \ have a special meaning in RTF syntax. To display one of these characters, you need to escape it with a backslash.

RTF:

\qc A backslash \\ will make a curly bracket or a second backslash visible: \{ \\ \}

Display:

A backslash \ will make a curly bracket or a second backslash visible: { \ }

If Director cannot interpret the string immediately following a mark-up tag, it will ignore it. It will start treating content after the next white space.

RTF:

\Director cannot interpret the tag \\Director

Display:

cannot interpret the tag \Director

Tables

Un-American Alphabets

RTF examples in various languages

Журнал Forbes опубликовал список перспективных (если использовать терминологию Михаил Борисовича) бизнесменов российского разлива.
How do you get Cyrillic or East European alphabets to display correctly inside Director?