mif.pl Read Routines

#

Read Routines

The following routines to read Frame MIF are defined in mif.pl:

- main'MIFread_mif

Note:
  Remember that ALL Perl variables mentioned are defined within the scope of package mif unless statements state/imply otherwise.

## Routine Descriptions

### MIFread_mif

`&'MIFread_mif(`FILEHANDLE`);`

`MIFread_mif` handles the parsing of the Frame MIF specified by FILEHANDLE and calls token callback routines defined by the caller of `MIFread_mif` for each token encountered in the MIF.

#### Token Callbacks

Token callback routines are registered via the `%mif'MIFToken` associative array. The keys of the array are any legal MIF tokens of interest. The values of the array are the names of the routines to be invoked when key/token is encountered in the MIF markup.

Example:
  `$mif'MIFToken{`ParaLine'} = `paragraph_line';` When `MIFread_mif` encounters a `ParaLine`, it will call the routine `paragraph_line`.

Note:
  Token callbacks are called within the scope of package mif. Therefore, if token routines are defined within the scope of another package, the routine name should be prefixed with the package qualifier string (Eg. `main'paragraph_line`) when stored in the `%mif'MIFToken`.

A token callback is invoked as follows:

`&`token_func`($token, $mode, *data);`

Where token_func is a token routine defined in `%mif'MIFToken`.

Argument descriptions:

`$token`
  MIF name of token.

`$mode`
  Flag telling routine if it is being called during a open statement (i.e. token contains nested MIF statements); token is being closed; or token has non-MIF statement data. Each mode is represented by `$mif'MOpen`, `$mif'MClose`, `$mif'MLine`, respectively.

`*data`
  Pointer to data string if mode is `$MLine`, or `$MClose` if the storing option is in effect. The data string contains the data content of the token specified by `$token`. The exception is when storing is done (see Storing MIF below for more info).

The token routine never see the ``<`` and ``>`' markup delimiters, with the following exceptions:

- The above characters are in a MIF string.
- When in storing mode.

#### Storing MIF

`MIFread_mif` will store MIF markup if the routine for a token is prefixed by the value, `$MStore`, and the ``,`' character.

Example:
  `$mif'MIFToken{`ParaLine'} = "$mif'MStore,paragraph_line";`

The ``,`' character is needed to separate the `$MStore` string from the routine name.

Once the token closes, the named routine is called with mode `$MClose`, and the `*data` argument contains the MIF. The store routine may also be called if the token specified does not contain nested MIF or is empty. In this case, `$MLine` is passed as the mode, and the markup delimiters, ``<`` and ``>`', are not in the `*data` argument string (i.e. The behavior is the same if `$MStore` was not specified).

#### Import Data

A special token exists for data imported by copy: `$mif'MImportData`. If a routine is registered for this token, than it will be invoked as follows:

`&`token_func`($MImportData, $MLine, *data);`

Where `*data` is a pointer to the string that contains the imported data. The imported data is passed "as is", and it is up to the calling routine to process it.

Warning:
  Specifying `$MStore` for `$MImportData` is not supported since `*data` contains the import data as it appears in the MIF document. If `$MStore` is used, Perl will cause program termination since it will try to execute the routine "`$MStore,$MIFToken{$MImportData}`".

#### Token Stack

The `@mif'OpenTokens` array is updated like a stack by `MIFread_mif` telling which tokens are currently opened. `MIFread_mif` will die if a pop is done on an empty `@OpenTokens` (i.e. an extra `>' was found). One can check the stack after parsing is done to determine if tokens were not closed.

Note:
  `MIFread_mif` is not intended as a MIF validator. If the routine dies, it outputs a terse message. For validation, it is best to use FrameMaker/Builder.

#### Behavior Modification

There are two special variables defined in package mif that can be set to change the behavior of `MIFread_mif`:

`$mif'fast`
  If set to a non-zero value, `MIFread_mif` will not process ``#`' end-of-line comments. By default, `MIFread_mif` strips out all ``#`' comments to avoid any MIF markup that could be contained in them. Setting `$fast` to non-zero approximately doubles speed performance.

`$mif'no_import_data`
  If set to a non-zero value, `MIFread_mif` will not check for import data. This is useful if the MIF file contains no import data. There is a slight increase in performance if this variable is set.

By default, the both variables are set zero.

In most cases, setting `$fast` is safe to do. If one is parsing MIF generated from FrameMaker/Builder, the comments in the MIF do not contain markup that will cause `MIFread_mif` behave incorrectly.

Note:
  These variables should be set before `MIFread_mif` is invoked. However, they can be modified within registered token callbacks. For example, one might want to set `$no_import_data` to 1 before calling `MIFread_mif`. Then when the "`AFrames`" token callback is called with a mode of `$MOpen`, it can set `$no_import_data` back to zero so `MIFread_mif` will catch import data. Then when the "`AFrames`" token callback is called with a mode of `$MClose`, it can set `$no_import_data` to 1. The same thing can be done for "`Frame`" tokens.

#### Notes

- `MIFread_mif` tries its best to preserve the original formatting (i.e. indenting) when storing MIF.

- If a token does not have a callback defined for it, then it, and its data, (which may include nested MIF statements) are ignored.

- A token specified for storing causes any nested tokens to be ignored for the purposes of executing registered token callbacks. I.e. If a token has a registered callback, but the token is in a parent token specified for storing, the (child) token will not have its routine called.

- `<Comment>` statements are treated like any other MIF statement. Therefore, if `<Comment>`s are embedded in a token specified for storing, the comments will be preserved. One can register a token callback for `<Comment>` if desired.

#### Bugs

- `MIFread_mif` does not handle MIF macro statements.

- If comments are being stripped and import data is being checked, the following will occur:

             <Token
             &  # This comment will NOT get removed
             # This comment will get removed
             >

- `MIFread_mif` treats lines starting with ``&`' as import data, and therefore, does not process it.

Go back to mif.pl.