Any note in Family Historian (or other field that, like notes, can store rich text) is stored internally in FTF format - that is, it is formatted using FTF syntax. 'FTF' stands for 'Family Historian Text Format'. RichText objects, in the Family Historian API, can store both plain text and rich text. To add rich text to a RichText object, you normally use the SetText and AddText methods, and supply the text in eFTF format. 'eFTF' stands for 'Enhanced FTF'. eFTF is a superset of FTF. It supports all features of FTF syntax, but adds some additional ones. If you create a RichText object in a plugin and give it contents which include eFTF features that are not supported in FTF, and then assign the RichText object as a value to a rich text field in a record, the extra features that are not supported in FTF syntax will be ignored. eFTF syntax is used, and is only used, when constructing a report in a Report plugin. To learn more about eFTF syntax, see the eFTF Syntax page.
For the convenience of plugin authors, there is also a text-only variant of eFTF syntax: tFTF syntax. This is only currently supported in the context of the SetText method for RichText objects.
The left angle bracket (<) is used to indicate the start of a command in FTF syntax. If Family Historian does not recognise a command, it will simply ignore it. Consequently, any occurrence of the left angle bracket as ordinary text (i.e. not the start of a command), must be 'escaped' by putting the escape character (a backslash) in front of it. If you want to insert a backslash as plain text, its special meaning as the escape character must also be removed by escaping it too (i.e. by putting another backslash in front of it). The asterisk character (*) and the right angle bracket (>) both also have a special meaning if used at start of a paragraph. If you wish to remove this special meaning, these two must be escaped. Finally, the vertical bar has a special meaning within the cell of a table row. If you want to insert a vertical bar as plain text, this too must be escaped.
The escape character can be placed in front of any character (and as we've seen, that includes itself). Doing so removes any special meaning that the character might otherwise have had.
As we will see below, the FTF syntax allows you to insert commands into text. Sometimes these commands take parameters, and some parameters can be textual. Parameters must be in double quotes if they contain one or more space characters, commas, right angle brackets, backslash characters or double quotes. Otherwise double quotes around them are permitted but optional. Within quoted parameters, backslash characters and double quote characters must be preceded by an additional backslash character.
To make life easier, Family Historian provides two functions that take care of special characters for you. The function fhFtfEncode puts an escape character (i.e. a backslash) in front of any special FTF characters (that is, "\|<>*). The function fhFtfParamEncode puts a backslash in front of any double quote or backslash character. You can avoid the need to use fhFtfEncode however, when you add text to a RichText object. If you want to add plain text using the rt:AddText function, set the bRich parameter to false and Family Historian will automatically take care of any necessary escaping for you.
Formatting syntax applies to an entire paragraph - either in the main body of text or within the cell of a table. You can also use indent and alignment formatting syntax with tables (as a whole, this is - i.e. not just within a cell), if you want a table to be indented, centred or right-aligned say. Setting the alignment of a table to 'justified' has no effect however.
You can combine formatting commands. If you do so, indent must proceed alignment, followed by bullet or table (the last two are mutually exclusive alternatives). For example, >>* This paragraph is indented twice and bulleted .
Tables can have any number of rows and columns. Within FTF syntax, you cannot have a table within a table - i.e. you cannot have a table within a cell (this is, however, permitted within eFTF syntax). This section describes basic FTF syntax for tables only.
To make the text easier to read, you can optionally include a single space character before or after the cell separator character (the vertical bar). You can also optionally include a single space after the <row> command or before the </row> command. These single character spaces will be ignored (as long they don't compound - if a cell is empty, at most one space character will be ignored). This means that if you want a cell to begin or end with a space character, you must add an extra one, to allow for the space character that will be ignored.
This is an example of a table that contains 2 rows and 3 columns. The first row has the words 'apple', 'pear' and 'orange' in the 3 cells of the first row, and the words 'house', 'tree' and 'car' in the 3 cells of the second row. None of the cells contain any spaces. The table is preceded by the sentence: "This comes before the table." and is followed, on a new line, by the sentence "this comes after the table."
This comes before the
table.
<table="800|800|800">
<row> apple | pear | orange </row>
<row> house| tree | car </row>
</table>
This comes after the table.
Use the <web=(params)> command to insert a web link - that is a link to a web page. Within the Rich Text editor, you can click on a web link to open a web-browser, to view the web page. If you include a web link within a report, the link is not clickable. But it may become clickable if you save the report in HTML format as a web page (e.g. if generating a website). The web command takes up to two parameters: the URL and (optionally) display text. The URL gives the address of the web page. The display text, if supplied, gives the text that is displayed for the link. For example, <web="www.family-historian.co.uk"> (with one parameter) inserts a link to the Family Historian website, and displays as "www.family-historian.co.uk". Alternatively, <web="www.family-historian.co.uk","Family Historian Website"> (with two parameters) inserts a link to the Family Historian website, and displays as "Family Historian Website".
Whereas a web link can be specified entirely textually, a record link is more complex. This is because each record link stores an index into a record link table that is associated with the rich text. If you have a RichText object, the record link table is held internally within the RichText object and managed by it. To create a record link, two things have to happen: an appropriate entry has to be added to the record link table, and an appropriate text command has to be inserted into the text. To make life easier, Family Historian provides a method, AddRecordLink, for inserting record links into a RichText object, which does both jobs. However, it is nevertheless useful to understand the textual component of a record link, as this will be visible in the text if, for example, you use the GetText method to extract the text from a RichText object.
Record links are marked by the <rec=(params)> command. This has three parameters: an index into the record table, display text, and a flag to indicate whether the link is automatic or not. The index into the record table is a value that is supplied by the AddRecordLink method. The display text is used if the record link is invalid or missing (if, say, the record has been deleted) or if the link is not automatic. The flag (the 3rd parameter) is set to 'auto' if the link is automatic and 'text' if it isn't. If a link is automatic, this means that the link is displayed as the record's display name, and it is updated automatically if that changes. If the flag is 'text', the display text is always shown as the display for the link. This is an example of what a record link might look like: <rec=6,"my father",text>; and this is another example: <rec=6,"Ian Stephen Munro",auto>. Remember that you cannot create a record link just by inserting text into a RichText object, because the required record links table entry will not be created if you do that. You must use the AddRecordLink method to do it.
If you want to append the contents of one RichText object into another, you must use the AddRichText method to do it. This will take care of merging the two record link tables, and making any necessary updates to the text.
Note: Rich text record links are always saved in the format described above, but, as mentioned in the Introduction above, for the convenience of plugin authors, the SetText method of RichText objects supports an alternative to FTF syntax which provides a text-only way of entering record links. This is tFTF syntax.
Source citations are like record links in that they too cannot be simply created by inserting text into a RichText object. You need a special method, AddCitation, to insert them. This is because source citations include an index into a citations table which, like the record links table, is stored internally within the RichText object and managed by it. To create a source citation, two things have to happen: an appropriate entry has to be added to the source citations table, and an appropriate text command has to be inserted into the text. The AddCitation method does both jobs. However, it is nevertheless useful to understand the textual component of a source citation, as this will be visible in the text if, for example, you use the GetText method to extract the text from a RichText object.
Source citations are marked by the <cit=(param)> command. The single parameter is the index into the source citation table. This is an example of what a source citation might look like in the text: <cit=2>. Remember that you cannot create a source citation just by inserting this text into a RichText object, because the required source citation table entry will not be created if you do that. You must use the AddCitation method to do it.
As noted above, if you want to append the contents of one RichText object into another, you must use the AddRichText method to do it. As well as (as discussed previously) taking care of merging the two record link tables, and updating the text appropriately if necessary, the same method will also take care of handling all source citations appropriately too.