HL7 v2 defines an FT data type, but it’s very poorly documented. Worse, the documentation is focused on managing text and cursor on a terminal screen. The basic idea of the FT data type is that you have a stream of text with a series of embedded commands such as |This is a line\.br\This is a new line|. The | characters mark the start and end of the content (HL7 v2 syntax) and the embedded commands begin and end with the specified escape character, which is usually “\”.
The following commands are defined:
|.sp[N]||End current output line and skip <number> vertical spaces. <number> is a positive integer or absent. If<number> is absent, skip one space. The horizontal character position remains unchanged. Note that only for
purposes of compatibility with previous versions of HL7, “^\.sp\” is equivalent to “\.br\.”
|.br||Begin new output line. Set the horizontal position to the current left margin and increment the vertical position by 1.|
|.fi||Begin word wrap or fill mode. This is the default state. It can be changed to a no-wrap mode using the .nf command.|
|.nf||Begin no-wrap mode|
|.in[N]||Indent <number> of spaces, where <number> is a positive or negative integer. This command cannot appear after the first printable character of a line.|
|.ti[N]|| Temporarily indent <number> of spaces where number is a positive or negative integer. This command
cannot appear after the first printable character of a line.
|.sk[N]||Skip <number> spaces to the right.|
|.ce||End current output line and center the next line|
Fill mode appears to be a synonym for word wrap (EMACS still uses the term). The documentation for the FT type says that the FT type is broken into sections by the component delimiter (^) (I’m not exactly sure how that works in something like the CF type, where the FT type is used as a subcomponent). Such sections reset the temporary indent, and mark the beginning of a new line in no wrap mode.
Formatted Text Documentation
The problem with all this is that no one uses terminals anymore. If you’re going to display the FT data type to a human, it’s going to parsed and converted to another display format – probably either HTML or RTF. From there, it might be rendered to PDF or directly using a RTF or HTML rendering engine (MS word or a browser). And the documentation above is rather obtuse from this point of view. So here’s some updated documentation:
|.sp[N]||Don’t use or ignore. You can’t go down x number of rows and not reset the cursor in any of the common display formats|
|.br||End of paragraph – \par(d) in rtf,<p> in HTML. In plain text, this would be|
|.fi||Default (normal text).|
|.nf||no wrap. This is appropriate when the text is really a table laid out using spaces. A non-proportional font should be used (i.e. Courier New). In HTML, a <pre> tag should be used. There’s no real equivalent for preventing wrapping in RTF – mainly the trick is to make sure that the font size is small enough to force wrapping.|
|.in[N]||Indent <number> of spaces, where <number> is a positive or negative integer. This command cannot appear after the first printable character of a line.add [n] to the current indent. The result must be 0 or greater. For HTML, <blockquote> can be used for indent, but it’s a crude tool. Better to use CSS and the left-margin attribute. For RTF: todo.|
|.ti[N]||This is really synonymous with .in except that the effect resets on ^.|
|.sk[N]||Insert N spaces. N must be a positive number. In HTML, use |
|.ce||I think it’s better not to use this. The problem is that this is just not well documented – does it carry past the next line? How does it interact with indents? is the centering affected by leading and trailing spaces?|
|h||highlighting – usually interpreted as bold (<b>/\b)|
|n||turns highlighting off.|
Here in Australia, we’ve added a few more rules:
- Don’t break the FT using ^. If you want a new line, use \.br\.
- Use a fixed width font whether wrapping is on or not. (It’s hard enough getting compliance with simple stuff, let alone subtle stuff like font switching).
- Reset highlighting using \n\ at the end of the line. (Avoids confusion about whether it is automatically reset or not)
- A weird precursor to HL7 called PIT is still used, and when used, is rendered using FT. That’s really a mis-use of the FT data type, and we’re trying to phase it out
These rules have been adopted by convention and/or fixed in the forthcoming MSIA clinical messaging profile.
Sample Test Cases
Here’s a simple case:
|This is a line\.br\This is a new line|
in HTML, this is
<p> This is a line </p> <p> This is a new line </p
which should be rendered as
This is a line
This is a new line
Here’s a more complex case:
|First line.\.br\\in4\Second line (Indented)\.br\ \.nf\\h\Table mode:\n\\.br\+------------+-----------+\.br\ | cell 1/1 | cell 2/1 |\.br\+------------+-----------+\.br\ | cell 1/2 | cell 2/2 |\.br\+------------+-----------+\.br\ \.br\
This doesn’t have line breaks in a real HL7 message, but I added them for readability here.
In HTML, this one is
<p> First line. </p> <p style="padding-left: 60px;"> Second Line (Indented) </p> <pre> <b>Table Mode</b> +------------+-----------+ | cell 1/1 | cell 2/1 | +------------+-----------+ | cell 1/2 | cell 2/2 | +------------+-----------+ </pre>
The actually amount of indenting for inN depends on many factors (font, screen size, application layout policy). Note that I haven’t added <p> tags in the table mode – it’s likely to introduce inappropriate white space
Which should be rendered as:
Second Line (Indented)
Table Mode +------------+-----------+ | cell 1/1 | cell 2/1 | +------------+-----------+ | cell 1/2 | cell 2/2 | +------------+-----------+