Copyright 1994-1998 David E. Cortesi
All Rights Reserved
See license and conditions of use
below
MIFFEd is a library of C functions that simplify the task of writing programs to read, generate, and/or write data in the Maker Interchange Format (MIF) defined by Adobe, Inc. as a portable exchange format for FrameMaker(tm) documents.
MIFFEd presents a unified view of MIF syntax as a simple list-based language.
MIFFEd supplies functions to read MIF as text from files, and to generate MIF from program data. The MIF items are stored as objects in memory.
Your program accesses the stored items using opaque "handles." You can navigate the items in memory, finding items of specified kinds (like Frame catalogs), inserting and deleting items, and changing the contents of items. You can extract the text of lines and paragraphs, with or without Frame formatting information.
Finally, a MIFFEd output function takes an item handle and a file, and writes an entire sequence of MIF in ASCII form.
The MIFFEd package, comprising source code, header files, and documentation, is Copyright (C) 1994-1998 David Cortesi, 2340 Tasso St., Palo Alto CA 94301. Permission is hereby granted to reproduce the MIFFEd package and to incorporate parts of it into other programs without charge subject to two conditions: first, when any part of MIFFEd is incorporated as an executable part of any software that is sold or distributed for use by others, the documentation both printed and electronic of the incorporating product must cite the use of "The MIFFEd package by David Cortesi"; second, that whenever MIFFEd or any part of it is distributed in readable or source form by any means, this notice must be included verbatim.
MIFFEd is a spare-time project of its author. It is distributed without charge, and you receive it AS IS WITHOUT WARRANTEE OF ANY KIND. You must make an informed judgement as to whether MIFFEd is suitable for any use. If for any reason you cannot make that judgement, you should not use MIFFEd.
MIFFEd (rhymes with "rift") provides C functions with which you can:
These abilities open the way writing interesting kinds of programs:
To write such programs you still must have in-depth knowledge of Frame document contents and conventions. You also must have C programming skills. But the idea is that MIF programming is easier with MIFFEd than without it. As an example here is the simplest MIFFEd filter:
#include <stdio.h>
#include "miffed.h"
main()
{
writeMIF(stdout,OUT_EOL+OUT_INDENT, readMIF(stdin,0) );
}
This reads MIF from standard input and writes it to standard output. The only difference between the input and output is that all redundant spaces and end-of-line comments in the input will be omitted from the output. (You can code the example to preserve the comments.)
Besides this file, MIFFEd is documented by a 100pp hypertext manual. The manual (a Frame document of course) is designed to be read on-line. The 32pp tutorial and the 50+ "man" pages to MIFFEd functions are extensively linked with hypertext references.
The functions in the MIFFEd library can be summarized in the following groups. (For a complete tutorial, download the documentation file.)
Two functions read MIF syntax from a stream file handle and store the MIF statements in memory as linked items. readMIF() takes a file handle and option flags, reads all MIF to end of file, and stores it, returning the handle for the first item read. This function is used to bring an entire document into memory in one operation. readOneItem() takes a stream file handle and option flags, and reads only one, outer-level, MIF statement. It returns the handle of that statement in memory. You use this function to read a MIF file in sections, for example, if you want the <PgfCatalog> and later the <FontCatalog> in separate operations.
Once all or part of a document is in memory your program can navigate it using several functions. The two most-used functions are firstOfName() and nextSameName() which together scan all the lists of a particular name within a containing list -- for example, all <Pgf> lists inside the <PgfCatalog> list. The following loop form is found again and again in the example programs:
itemHandle hContainer, hUnit;
...
for( hUnit = firstOfName(hContainer,"name-of-thing");
(hUnit);
hUnit = nextSameName(hUnit))
{
// process one instance of hUnit
}
Code like this is used to scan every font in the font catalog, every row in a table, every cell in a row, every line in a paragraph, and in general every repeated instance of similar units in a containing list.
Although MIF is a document medium, it takes complex programming to extract the document text from a MIF file. This is due to the great richness of the Frame document format, where the text within a paragraph can be interrupted at any point by special characters, font changes, anchored frames, equations, variables, and so forth. MIFFEd includes a highly generalized set of functions for extracting the text from a MIF <Para>.
MIFFEd adopts the object-oriented programming model and treats the <Para> as a container. The paraScanInit() function initializes an object that acts as an iterator over the text in the container. The iterator can be initialized to the start of any line within the paragraph; and a wide variety of option flags let you tailor the amount of detail that will be returned in the scan. You can request the return of all characters or only the basic ASCII set; you can have tabs returned as tabs or as spaces; special characters can be returned using the Frame encoding, or ISO-8859 coding, or in \xnn form.
After the iterator is set up, each call to paraScan() returns the next character from the paragraph, with end of paragraph signalled by a null return. Since a frequent need is to simply "copy the first n ASCII bytes to my buffer," another function, patterned after fgets(), is supplied to do just that.
A variety of functions are provided for fetching, comparing, and changing the content of an item, for example changing the value of a word from "No" to "Yes." Especially useful are functions for working with MIF numbers, which always have an associated unit of measure such as "pt" for points, "pc" for picas, etc. You can fetch the unit of measure, or you can change the unit of measure with automatic conversion of the numeric value.
A variety of functions are provided to generate new instances of the four kinds of MIF items: words, strings, numbers, and lists. For example, newWord("Yes") returns the handle of a word item, and newList("Para") returns the handle of a new, empty list <Para>. But it is tedious to construct MIF at this level. You usually want to construct a whole MIF statement, customized with a small amount of program data. The patToMIF() function serves this need: like sprintf(), it takes a pattern with substitution points, and a varying number of arguments. For example,
char *weight = "Bold"
double size = 9.5;
itemHandle hFont = patToMIF("<Font<FWeight %s><FSize %d pt>>",
weight, size);
generates a MIF list <Font<FWeight Bold><FSize 9.5 pt>> and returns its handle.
When MIF is ready for output, the function writeMIF() takes a stream file handle and a MIF item handle and writes all the MIF to the file in ASCII form. Optionally the output can be indented as Frame indents MIF, and the Frame-generated comments reproduced.
Some quite elaborate example programs are included, including a suite of programs that help you analyze the template usage of an unfamiliar document and automatically conform it to your own house templates. You can review all the examples by downloading the source using the links in the MIFFEd Access page.
MIFFEd can be compared to at least three other ways of dealing with Frame documents. There are other tools to be had; explore the FrameUsers page.
Frame supports a "client API," a programming interface to the interactive FrameMaker, FrameViewer and FrameBuilder products. The Client API lets you write extensions to the interactive Frame products , adding menus, dialogs, and interactive features. (By contrast, MIFFEd helps you write batch-mode command line utilities.)
Client API programs are compiled programs in C, which load as part of Frame. They access Frame documents as Frame products maintain them in memory.
The FrameScript product by Finite Matters, Inc. is a scripting extension to FrameMaker which makes the capabilities of the Client API easily accessible. You write scripts to perform actions on documents, using a high-level scripting language. The scripts are executed in FrameMaker, using the facilities of the Client API. FrameScript is available for both Windows and Mac operating systems, and is an excellent way to apply the power of the Client API without having to write programs in C.
MifMucker is a set of Perl programs and modules written by Ken Harward. For full details and access to MifMucker, refer to the MifMucker WWW page, MifMucker is written in Perl. MifMucker converts Frame documents into MIF for you. With MIFFEd, you have to make this happen using a Save As or fmbatch.
MifMucker parses the names of MIF statements as well as their surface syntax so it "knows" the names of the parts of a document and is dependent on seeing these names in the right places. MIFFEd is very innocent about MIF semantics; it accepts almost anything that has properly balanced <>'s, and leaves it to you to figure out the meaning by navigating the resulting lists.