File handling

Introduction

One of the primary features of the teletext script is in creating file output. The script itself is designed for loading teletext frame off-air and outputting them to file, either as-is or with some sort of editing.

In the teletext script, there is a "user I/O file" which may be opened, written to, and then closed. You can only have the one file open at a time, however there is nothing to stop you from creating multiple files, one after the other. There is no concept of 'file handle', as the write commands write to the open file.

When we talk of frame and page, there are some complications with this terminology, hence:

 

Opening and closing files

There are two ways to open a file. Which you pick depends on whether you wish to append information to an existing file, or create a new (empty) file.

Creating a new file is performed using the filewrite() command. It will open the output file, which is empty, and set the output pointer to the beginning of the file. If the file specified already exists, it will be erased and a new version created.

filewrite("#TEMP#\tempfile.txt")

Appending to an existing file is performed using the fileupdate() command. It will open the output file, which may already contain data, and set the output pointer to the end of the file so anything you now add will be written after previous content.

fileupdate("#PAGES#\currencylog.txt")

Closing the output file is the same in either case, you use the fileclose() command.

fileclose()

Please note that there is a difference between path specifiers on RISC OS, where the following would be quite valid:

filewrite("<Teletext$Pages>.mypage")
and Windows, where the following would be valid:
filewrite("#PAGES#\mypage.ttx")
There is no attempt at translating between the two forms, as the variety of possibilities does not make a translation viable; and furthermore filenames under Windows require a type extension while those under RISC OS require a filetype value to be applied.
You can read more about path specifiers.

As just mentioned, while Windows file 'types' are self-contained in the file extension (i.e. ".txt", etc), RISC OS requires a metadata setting. This should be performed once the output file has been closed, using the filetype() command.

filetype("<Teletext$Pages>.mypage", &FAF)
Note that the type can be applied multiple times, it won't hurt, however it really only needs to be done after a filewrite() to create the file, as files opened with fileupdate() will presumably already have a type.

General notes:

 

Tidying up teletext frames

Before writing to some types of file (details of available formats are provided further down), you can 'tidy' the frame by removing unwanted mosaic codes and/or unwanted lines.

The removal of unwanted mosaic codes is performed using the smartclear() command. This is because only the creation of teletext files is able to preserve the mosaic characters. They cannot be represented in text.
You can smartclear() individual lines, or you can under Windows pass the line number -1 to smartclear the entire frame.

The removal of blank lines is more useful. With the exception of teletext files, the output methods permit the complete omission of lines marked as 'blank', so you can only output the content you want and the rest will be discarded. This is acheived with the omitline() command.
Note that you must omit the header (line 1) for any other omissions to take effect. If the header is present, omitted lines will be retained, and this might have some odd side effects under Windows - namely lots of "OMITTHIS" markers!

You can also read characters from the frame using set <var> to char(<x>, <y>) and write characters to the frame using setchar().

When a frame has been modified, you must push it back to the cache, as attempts to write the frame to file will cause the frame to be loaded from the cache, and hence the older cached version would overwrite the one you just amended. Don't worry if that sounds confusing, just be sure to call storeframe() after any alteration to the frame's content.

 

Writing to files - different options

There are a number of ways you can write to the file.

To output entire frames (with optional omission of unwanted lines), you can use appendframe() or appendframes(); the difference being that the former will write the frame specified and the latter will write all the integral subframes of the page specified.

To write individual bytes to the file, you would use filewritebyte(). This is perhaps most useful for outputting newlines.

You can write string literals (that is a fixed string that you specify in the script) using filewritestring(). You cannot copy strings from teletext frames, this can be achieved using a roundabout method (described below).

Floating point values (either literal or from a variable) may be written using filewritefloat(), and variables (either integer or float) may be written using filewritevar().
It may seem as if when we are speaking of a float variable, that filewritefloat() and filewritevar() may do much the same thing. This is mostly correct, however there are slight differences in the control of output style.

 

Writing to files - different formats

You can write to the output file in one of four different formats (three under RISC OS).

1 Teletext frame This will output a teletext frame. It is perhaps the least useful option as only WinTTX would be able to reload this sort of file, and if you write more than one frame to a file it will be a file that could not be correctly loaded.
2 ASCII text This will output in plain ASCII text. This is useful for simple tables and charts and things where the information content is more important than any visual aspect.
3 OvationPro DDL This will create a document script file suitable for loading into the OvationPro desktop publisher by David Pilling (more details on his website). It will attempt to recreate the look of the teletext page, complete with colours and black background. Italicised text will be used in place of flashing.
4 HTML document
(Windows only)
This works in much the same way as the aforementioned OvationPro output, only the type of file created is a web document. It is fairly abusive regarding styles and effects in order to generate a good representation of a teletext frame, however it has been tested and shown to render correctly on both MSIE6 and Firefox. Correct display on other browsers, especially those of more minority platforms, is not guaranteed.

 

OvationPro DDL output hints

To output an OvationPro DDL file, you would...

filewrite("<filename>")  ; "filename.dpd" under Windows
filewriteovnhead()       ; must be the FIRST thing you output

; output the frames, ie:
;  appendframe(x, 3)
; in a loop, or whatever

filewriteovntail()       ; must be the LAST thing you output
fileclose()

filetype("<path>", &B25) ; only under RISC OS

The filewriteovnhead command outputs (with small modifications depending on platform):

// minimal OvationPro DDL script created by Teletext (1.49)
 
COL_00={colour "Ttx Black" {rgb 0x0 0x0 0x0}}
COL_01={colour "Ttx Red" {rgb 0x10000 0x0 0x0}}
COL_02={colour "Ttx Green" {rgb 0x0 0x10000 0x0}}
COL_03={colour "Ttx Yellow" {rgb 0x10000 0x10000 0x0}}
COL_04={colour "Ttx Blue" {rgb 0x0 0x0 0x10000}}
COL_05={colour "Ttx Magenta" {rgb 0x10000 0x0 0x10000}}
COL_06={colour "Ttx Cyan" {rgb 0x0 0x10000 0x10000}}
COL_07={colour "Ttx White" {rgb 0x10000 0x10000 0x10000}}
 
STORY_001={story

You can replace this with your own header if you wish, however you must define the colours as above, because the output frames will expect them to be present.

The append[given]frame[s] commands, with type 3 output, write the frames exactly as for the OvationPro DDL output from the Save dialogue. Please refer to any saved file for an example.

The filewriteovntail command outputs:

{endoftext}
}

This tells OvationPro that the DDL file has finished. The minimum you can get away with is a single '}' character, but you might as well call this function and end properly...

A suggestion is to 'centre' the output. For this, you should:

filewrite("<filename>")
filewriteovnhead()
filewritestring("{align 1}")

; output follows...

The alignment types are:

left 0
centre 1
right 2
justified   3

You might like to output headings before each group of pages. The example below shows outputting a heading, and then outputting the pages 101 to 110.

; NEWS
filewritestring("{newpara}{textsize 16000}{bold 1}{underline 1}")
filewritebyte(34)
filewritestring("Headlines")
filewritebyte(34)
filewritestring("{bold 0}{underline 0}{textsize 12000}")
filewritebyte(34)
filewritestring(" (from CNN)")
filewritebyte(34)
filewritebyte(10)   ; or you can output <13><10> under Windows
filewritestring("{textsize}{bold}{underline}{newpara}")

set A to 101
.writenews
  appendframe(A, 3)
  A++
  if (A [ 110) go("writenews")

You have various commands at your disposal. A command with no parameter will restore the option to the default for the current style (which will probably be Trinity.Medium, 12pt, left aligned, no bold/italic/underline).

{align #} Sets the alignment to that specified (0-left, 1-centre, 2-right, 3-justified).
{bold #} Use {bold 1} to switch bold on, and {bold 0} to switch it off.
{italic #} Use {italic 1} to switch italics on, and {italic 0} to switch it off.
{newpara} If you want a line break, use {newpara}.
{textsize #} The text size is 'pointsize * 1000', so 12000 is 12pt, and 24000 is 24pt...
{underline #} Use {underline 1} to switch underline on, {underline 0} for off...

All text must be enclosed in "quotes", including spaces between items. The following is valid:

{bold 1} "this text is in bold" {bold 0}

Even the following would work:

{bold 1}
"this "
"text "
"is "
"in "
"bold"
{bold 0}

This, however, won't work:

{bold 1} this text is in bold {bold 0}

If you need to include the characters '{', '\', or '"' in the DDL, you will need to escape them, as shown:

For: Use:
{ \{
\ \\
" \"

There are all sorts of nifty things possible, such as tab-aligned results from a calculation, but these things require a deeper knowledge of the OvationPro DDL script, and that is outside of the scope of this document.

Remember, you can always 'fake' what you'd like to see in OvationPro, then save the document in DDL format to an editor such as !Edit (Notepad in Windows). This will allow you to see how something was achieved, and thus allow you to use it in your own generated output.

A useful suggestion is to save a number of 'desired' frames to a directory, and then load them in using the cache_loaddirectory() command. This will save you waiting for each frame fetch while testing and tweaking your teletext script to produce exactly the DDL script that you want.
(this command has not been implemented under Windows, however you can use the cache_loadfile() command to load files individually to acheive the same result.

 

And for HTML?

To output an HTML file, you would...

filewrite("<filename>")  ; "filename.html" under Windows
filewritehtmlhead()      ; must be the FIRST thing you output

; output the frames, ie:
;  appendframe(x, 4)
; in a loop, or whatever

filewritehtmltail()      ; must be the LAST thing you output
fileclose()

filetype("<path>", &FAF) ; only under RISC OS

All of the remaining comments are much the same as already given for the OvationPro output. If you know HTML mark-up, you can patch in a lot of custom HTML.

 

Copying strings from a teletext page

It is not possible to copy strings out of the teletext page. This action should be performed by reading the frame character by character and writing bytewise to file, as this example shows:
filewritestring("                  Sky  = ")
set A to 30
.reportloop
  set B to char(A, 17)
  filewritebyte(B)
  A++
  if (A [ 40) go("reportloop")
filewritebyte(13)
filewritebyte(10)
This example copies the weather 'forecast' word (cloudy, rain, snow, etc) from the frame.