]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
MIF Document description
authorarved <arved@unknown>
Sat, 10 Feb 2001 03:20:32 +0000 (03:20 +0000)
committerarved <arved@unknown>
Sat, 10 Feb 2001 03:20:32 +0000 (03:20 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194035 13f79535-47bb-0310-9956-ffa450edef68

src/org/apache/fop/mif/MIFDocument.java [new file with mode: 0644]

diff --git a/src/org/apache/fop/mif/MIFDocument.java b/src/org/apache/fop/mif/MIFDocument.java
new file mode 100644 (file)
index 0000000..0ec698d
--- /dev/null
@@ -0,0 +1,1185 @@
+/*-- $Id$ --
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following     acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 4. The names "FOP" and  "Apache Software Foundation"  must not be used to
+    endorse  or promote  products derived  from this  software without prior
+    written permission. For written permission, please contact
+    apache@apache.org.
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR     PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,     WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR     OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This software consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software     Foundation and was      originally created by
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache
+ Software Foundation, please see <http://www.apache.org/>.
+
+ */
+
+
+//Author : Seshadri G
+
+
+
+package org.apache.fop.mif;
+
+// images are the one place that FOP classes outside this package get
+// referenced and I'd rather not do it
+
+import org.apache.fop.image.FopImage;
+import org.apache.fop.messaging.MessageHandler;
+import org.apache.fop.layout.LinkSet;
+import org.apache.fop.datatypes.ColorSpace;
+
+import org.apache.fop.datatypes.IDReferences;
+import org.apache.fop.layout.Page;
+import org.apache.fop.layout.FontMetric;
+import org.apache.fop.layout.FontDescriptor;
+// Java
+import java.io.*;
+import java.io.PrintWriter;
+import java.util.*;
+import java.awt.Rectangle;
+
+/**
+ * class representing a MIF document.
+ *
+ * The document is built up by calling various methods and then finally
+ * output to given filehandle using output method.
+ *
+ */ 
+public class MIFDocument {
+
+    /** the version of MIF supported */
+
+
+    protected static final String mifVersion = "5.5";
+    protected BookComponent bookComponent;
+    private Flow curFlow;    // this is a ref to the current flow which could be a textflow or 
+                            // a table 
+    private ID curIDCounter=new ID();  
+
+    class ID {
+
+       private int idCounter=1;
+       public int getnewID() {
+
+               return idCounter++;
+       }
+       
+    }  
+
+    class FontFormat {    
+
+       public FontFormat() { }
+
+    }
+
+    class ParagraphFormat extends FontFormat {
+
+       public ParagraphFormat() {}
+       int startIndent;
+       int endIndent;
+
+
+
+    }
+
+    class Document {
+       protected int height;
+       protected int width;
+       public Document() {}
+
+       public void output(OutputStream stream) throws IOException {    
+
+               String mif="\n<Document " + "\n<DPageSize " + width/1000f + " " + height/1000f + " >\n>";
+               byte buf[]=mif.getBytes();      
+
+               stream.write(buf);
+               
+       }
+
+    }
+
+    
+    class PolyLine {
+
+       public PolyLine() {}
+    }
+
+    class ImportObject {
+
+       private String url;
+       private int x,y,w,h;
+
+       public ImportObject(String url,int x,int y,int w,int h) {
+
+               this.url=url;   
+               this.x=x;
+               this.y=y;
+               this.w=w;
+               this.h=h;
+
+       }
+
+
+       public void output(OutputStream stream) throws IOException {    
+
+
+               String path=this.url;
+
+               //Strip 'file:'
+               path= path.substring(5);
+               String result="";
+               int i;
+               do { // replace all matching '/'
+
+                       i=path.indexOf("/");
+                       if (i != -1) {
+                               result=path.substring(0,i);
+                               result += "<c\\>";
+                               result += path.substring(i + 1);
+                               path=result;
+                       }
+
+               } while (i!= -1);
+               
+               String mif="\n<ImportObject" + "\n<ImportObFixedSize Yes>";
+               mif += "\n\t<ImportObFileDI " + "`<c\\>" + path + "'" + " >";
+               mif +="\n\t<ShapeRect " + this.x/1000f + " " + this.y/1000f + " " + this.w/1000f + " " + this.h/1000f + " >";
+
+               mif += "\n> #End ImportObj";                    
+               stream.write(mif.getBytes());           
+
+       }
+
+    }
+
+       
+    class Frame {
+
+       private int ID;
+       private int x,y,w,h;
+       Vector content=new Vector();
+       public Frame(int x, int y, int w, int h) {
+
+               this.ID=curIDCounter.getnewID();
+               this.x=x;
+               this.y=y;
+               this.w=w;
+               this.h=h;
+
+       }
+       
+       public void addContent(ImportObject obj) {
+
+               content.addElement(obj);                
+
+       }
+
+       public void output(OutputStream stream) throws IOException {
+
+               String mif="\n<Frame" + "\n\t<ID " + this.ID + " >";
+               mif += "\n\t<Pen 15>\n\t<Fill 7>\n\t<PenWidth  1.0 >\n\t<Separation 0>\n\t<ObColor `Black'>\n\t<DashedPattern \n\t <DashedStyle Solid> \n >";
+
+               mif +="\n\t<RunaroundGap  6.0 pt>\n\t<RunaroundType None>\n\t<Angle  360.0>\n\t<Float No>\n\t<NSOffset  0.0>\n\t<BLOffset  0>\n\t<Cropped No>\n\t<FrameType Below>\n\t<AnchorAlign Center>";
+
+               mif += "\n\t<ShapeRect " + this.x/1000f + " " + this.y/1000f + " " + this.w/1000f + " "  + this.h/1000f + " >";
+       
+
+               stream.write(mif.getBytes());
+
+               Enumeration e=content.elements();
+               while (e.hasMoreElements()) {
+
+                       ((ImportObject) e.nextElement()).output(stream);
+               }
+               mif ="\n> #End Frame";
+               stream.write(mif.getBytes());
+
+
+
+       }       
+       public int getID() {
+       
+               return this.ID;
+       }       
+
+    }
+  
+    class TextRect {
+       private int rx,ry,w,h;
+       private int numCols;
+       private int curCol=0; //Current column being processed
+       private int colGap=0;
+       private int textRectID;
+       public TextRect(int numCols) {
+
+               this.numCols=numCols;
+               this.curCol=0;
+               this.textRectID=curIDCounter.getnewID();
+               
+       }
+
+
+       public int getTextRectID() {
+       
+               return textRectID;
+       
+       }
+
+
+       public void setTextRectProp(int left,int top,int width,int height) {
+               
+               if (curCol==0) {
+
+                       //Use the left and top margins
+
+                       rx=left;
+                       ry=top;
+                       w=width; // current column width , not the entire span
+                       h=height;
+                       curCol++;
+                       
+               }
+               else if (curCol==1) {
+                       // Figure out the column gap and the span of the textrect
+                       colGap=left-rx-width;
+                       // Next the entire width
+                       w=numCols*width + (numCols-1)*colGap;
+                       curCol++;
+                       
+
+               }
+                               
+       }
+
+
+       public void output(OutputStream stream) throws IOException {    
+
+               String mif="\n<TextRect" + "\n\t<ID " + textRectID + ">" + "\n\t<ShapeRect " + rx/1000f + " " +  ry/1000f + " " + w/1000f + " " + h/1000f + ">" ;
+
+               if (numCols>1) {
+                       mif += "\n<TRNumColumns " + numCols + ">";
+                       mif += "\n<TRColumnGap " + colGap/1000f + ">";
+               }
+
+               mif += "\n> #End TextRect" ;
+               byte buf[]=mif.getBytes();
+               stream.write(buf);
+       }
+
+    }
+
+    class Page {
+       private String pageType;
+       private String pageTag;
+       private String pageBackground;
+       private Vector textRects;
+       public Page(String pageType, String pageTag, String pageBackground) {
+       
+               this.pageType=pageType;
+               this.pageTag=pageTag;
+               this.pageBackground=pageBackground;
+               this.textRects=new Vector();
+       }
+
+       public Page() {
+
+               this.pageType="BodyPage";
+               this.pageBackground="Default";
+               this.textRects=new Vector();
+
+       }
+
+
+       public void addTextRect(int numCols) {
+                               
+               TextRect textRect=new TextRect(numCols);
+               this.textRects.addElement(textRect);
+       }
+
+       public TextRect curTextRect() {
+
+               return (TextRect) textRects.lastElement();
+
+       }
+
+
+       
+       public void output(OutputStream stream) throws IOException {
+
+
+               String mif="\n<Page" + "\n\t<PageType " + pageType + ">" + "\n\t<PageBackground " + "`" + pageBackground + "'" + ">";
+
+               byte  buf[]=mif.getBytes();
+
+               stream.write(buf);
+               
+               Enumeration e=textRects.elements();
+
+               while (e.hasMoreElements()) {
+
+                       ((TextRect) e.nextElement()).output(stream);
+
+               }
+               mif="\n>  #End Page\n";
+               stream.write(mif.getBytes()); 
+
+       }
+
+       
+     }
+
+    abstract class Flow {    
+
+       public Flow() {}
+       public abstract Para curPara();
+       public abstract void startPara();
+    }
+
+
+    class TextFlow extends Flow {
+       
+       Vector paras;           
+       private int ID;         // This ID is used within ParaLine, however it is 
+                               // logical to keep it unique    to a textflow
+
+       public TextFlow() {
+               
+               
+               //The current textrect into which the textflow goes
+               //is the last created.
+
+               this.ID=((bookComponent.curPage()).curTextRect()).getTextRectID();
+               this.paras=new Vector();
+               
+       }
+       
+
+       public int getTextRectID() {
+
+               return ID;
+
+       }
+
+       public Para curPara() {
+
+               return (Para) paras.lastElement();
+       }
+
+       public void startPara() {
+
+               this.paras.addElement(new Para(ID));
+       }
+
+       public void output(OutputStream stream) throws IOException {    
+               String mif="\n<TextFlow";
+               stream.write(mif.getBytes());
+               Enumeration e=paras.elements();
+               while (e.hasMoreElements()) {
+
+                       ((Para) e.nextElement()).output(stream);
+               }
+               mif="\n> #End TextFlow";
+               stream.write(mif.getBytes());
+       }
+
+     }
+       
+
+     class Para  {          
+       
+       Vector paraLines;
+       int ID; // Same as TextRectID
+       ParagraphFormat pgf=null; // This corresponds to to the block properties
+       public Para() {
+
+               this.ID=0;
+               this.paraLines=new Vector();
+       }
+
+
+       public Para(int ID) {
+       
+               this.ID=ID;
+               this.paraLines=new Vector();
+               
+       }
+
+       public ParaLine curParaLine() {
+               if (paraLines.isEmpty()) {
+                       return null;
+               }
+               else {
+                       return (ParaLine) paraLines.lastElement();
+               }
+       }
+
+       void startParaLine() {
+               
+               this.paraLines.addElement(new ParaLine(ID));
+
+       }
+
+
+       public void setBlockProp(int startIndent,int endIndent) {
+
+               pgf=new ParagraphFormat();
+               pgf.startIndent=startIndent;
+               pgf.endIndent=endIndent;
+                               
+
+       }
+
+
+       public void output(OutputStream stream) throws IOException {    
+
+               String mif="\n<Para";
+               //Is there a block property?
+
+               if (pgf != null) {
+                       mif += "\n<Pgf" ;
+                       mif += "\n<PgfTag `Body'>";
+                       mif += "\n<PgfLIndent " + pgf.startIndent/1000f + ">";
+                       mif += "\n<PgfRIndent " + pgf.endIndent/1000f + ">";
+                       mif += "\n>";
+               }
+               stream.write(mif.getBytes());
+               Enumeration e=paraLines.elements();
+               while (e.hasMoreElements()) {
+
+                       ((ParaLine) e.nextElement()).output(stream);
+               }
+               mif="\n> #End ParaLine";
+               stream.write(mif.getBytes());
+
+       }
+       
+     }
+
+     class ParaLine {
+       Vector content; 
+       int textRectID;
+       String tableID;
+       String aFrameID;
+       public ParaLine(int textRectID) {
+
+               this.textRectID=textRectID;
+               this.content=new Vector();
+
+       }
+       public ParaLine () {
+
+               this.textRectID=0; // There is no ID used, in tables
+               this.content=new Vector();
+       }
+
+       public void addContent(Object obj) {
+
+               this.content.addElement(obj);
+
+       }
+       public void output(OutputStream stream) throws IOException {
+       
+               String mif="\n<ParaLine"; 
+
+               // tables dont need the textrectid
+               if (textRectID != 0) 
+                       mif += "\n\t<TextRectID " + textRectID + ">";   
+
+               stream.write(mif.getBytes());
+               Enumeration e = this.content.elements();
+               while (e.hasMoreElements()) {
+
+                       Object elem=(Object) e.nextElement();
+                       if (elem instanceof String) {
+                                                       
+                               // Output newlines as char hard return
+                               
+                               if (elem == "\n") {
+
+                                       mif ="\n<Char HardReturn>";
+                               }
+                               else {
+                                       mif="\n\t<String `" + elem + "'>";
+                               }
+                               stream.write(mif.getBytes()); 
+                               
+                       }
+                       else 
+                       if (elem instanceof Frame) {
+                               
+                               mif="\n\t<AFrame " + ((Frame) elem).getID() + " >";
+                               stream.write(mif.getBytes()); 
+                       }               
+                       else
+                       if (elem instanceof Tbl) {
+                               mif="\n\t<ATbl " + ((Tbl) elem).getID() + " >";
+                               stream.write(mif.getBytes()); 
+                       }       
+               }
+               mif="\n> #End ParaLine";
+               stream.write(mif.getBytes());
+       
+       }
+     }
+     
+     class PgfCatalog {
+
+       Vector pgfs; // Paragraph formats
+       public PgfCatalog() {}
+
+       public void output(OutputStream stream) throws IOException {
+               String mif="\n<PgfCatalog" + "\n<Pgf" + "\n<PgfTag `Body'>" + "\n>" + "\n>";
+               stream.write(mif.getBytes());
+       }
+
+     }
+
+     class Color {
+
+       public Color() {}
+     }
+
+     class ColorCatalog {
+
+       public ColorCatalog() {}
+     }
+
+
+     class Ruling {
+
+       int penWidth;
+       int pen;
+       int lines;
+       public Ruling() {
+       // Default ruling
+               penWidth=1;
+               pen=0;
+               lines=1;
+       
+
+       }
+
+       public void output(OutputStream stream) throws IOException {
+
+               String mif = "\n<Ruling \n<RulingTag `Default'>";
+               mif +="\n<RulingPenWidth " + penWidth + ">";
+               mif +="\n<RulingPen " + pen + ">";
+               mif +="\n<RulingLines " + lines + ">";
+               mif +="\n>";
+               stream.write(mif.getBytes());
+       }
+
+     }
+
+     class RulingCatalog {
+       // Contains multiple rulings
+
+       Vector ruling = new Vector();
+       public RulingCatalog() {
+       
+       // Add the defualt ruling to the catalog
+
+               ruling.addElement(new Ruling());        
+
+       }
+
+       public void output(OutputStream stream) throws IOException {
+
+               String mif="\n<RulingCatalog";
+               stream.write(mif.getBytes());
+               Enumeration e=ruling.elements();        
+               while (e.hasMoreElements()) {           
+                       ((Ruling) e.nextElement()).output(stream);
+               }
+               mif="\n> #End RulingCatalog";
+               stream.write(mif.getBytes());
+                                       
+       }
+
+
+     }
+
+          
+     class TblFormat {
+
+       public TblFormat() {}
+     }
+
+     class TblCatalog {
+
+       public TblCatalog() {}
+
+     }
+       
+     class Tbl extends Flow {
+
+       class TblColumn {
+               private int width;
+               public TblColumn(int width) {
+
+                       this.width=width;
+
+               }
+               public void output(OutputStream stream) throws IOException {
+
+
+                       String mif="\n\t<TblColumnWidth " + width + " >";
+                       stream.write(mif.getBytes());                           
+
+               }
+
+               
+       }
+
+       class Row {
+               
+               class Cell {
+
+                       private int rowSpan,colSpan;
+                       private Vector paras; // Paras
+                       public Cell(int rowSpan,int colSpan) {
+
+                               this.rowSpan=rowSpan;
+                               this.colSpan=colSpan;
+                               paras=new Vector();
+
+                       }
+                       public void startPara() {
+
+                               this.paras.addElement(new Para());
+                       }
+                       public void output(OutputStream stream) throws IOException {
+
+                               String mif="\n\t\t<Cell" + "\n\t\t<CellContent";
+                               stream.write(mif.getBytes());   
+                               Enumeration e=paras.elements(); 
+                               while (e.hasMoreElements()) {           
+                                       ((Para) e.nextElement()).output(stream);
+                               }                       
+                               mif="\n\t\t> #End CellContent";
+                               mif +="\n\t> #End Cell";
+                               stream.write(mif.getBytes());                   
+                       }
+
+               }       
+               private Vector cells; 
+
+               public void addCell(int rowSpan, int colSpan) {
+
+                       cells.addElement(new Cell(rowSpan,colSpan));
+               }
+
+               public Row() {
+
+                       cells=new Vector();
+       
+               }
+               public Cell curCell() {
+
+                       return (Cell) this.cells.lastElement();
+               }
+
+               public void output(OutputStream stream) throws IOException {
+
+                       String mif="\n\t<Row";
+                       stream.write(mif.getBytes());
+                       Enumeration e=cells.elements(); 
+                       while (e.hasMoreElements()) {           
+                               ((Cell) e.nextElement()).output(stream);
+                       }                       
+                       mif="\n\t> #End Row";
+                       stream.write(mif.getBytes());                   
+
+               }
+
+
+       }
+
+       private int ID;
+       private Vector tblColumns=new Vector();
+       private Vector tblBody,tblHead,tblFoot;
+       private Vector current; // is a reference to one of tblHead,tblBody or tblFoot
+       public void addColumn(int colWidth) {
+
+               tblColumns.addElement(new TblColumn(colWidth));
+
+       }
+       public void setCurrent(String current) {
+
+               if (current == "fo:table-body") {
+                       this.current=this.tblBody;
+               }
+               else
+               if (current == "tablehead") {
+                       this.current=this.tblHead;
+               }
+               else
+               if (current == "tablefoot") {
+                       this.current=this.tblFoot;
+               }
+       }
+       public void startRow() {
+
+               this.current.addElement(new Row());
+       }
+
+       public void startCell(int rowSpan,int colSpan) {
+
+               //Add a cell into the current row
+
+               ((Row) this.current.lastElement()).addCell(rowSpan,colSpan);
+
+       }
+
+       public Tbl() {
+
+               this.ID=curIDCounter.getnewID();
+               tblBody=new Vector();
+               tblHead=new Vector();
+               tblFoot=new Vector();
+
+       }
+
+       public int getID() {
+
+               return this.ID;
+       }       
+       public Para curPara() {
+
+               // Return the last para of the current cell
+
+               Row curRow;
+               curRow= (Row) this.current.lastElement();
+               return (Para) curRow.curCell().paras.lastElement();
+
+
+       }
+       public void startPara() {
+
+               // start a new para in the current cell
+               Row curRow;
+               curRow= (Row) this.current.lastElement();
+               curRow.curCell().startPara();
+
+       }
+
+
+       public void output(OutputStream stream) throws IOException {
+
+               String mif="\n<Tbl" + "\n\t<TblID " + ID + " >";
+
+               // note tbl format to be added in a later release
+               mif += "\n<TblTag Body>" + "\n<TblFormat";
+               mif +="\n<TblColumnRuling `Default'>";
+               mif +="\n<TblBodyRowRuling `Default'>";
+               mif +="\n<TblLRuling `Default'>";
+               mif +="\n<TblBRuling `Default'>";
+               mif +="\n<TblRRuling `Default'>";
+               mif +="\n<TblTRuling `Default'>";
+
+               mif += "\n> #End TblFormat";
+ ;
+               mif +="\n\t<TblNumColumns " + tblColumns.size() + " >";                         
+               stream.write(mif.getBytes());
+               
+               if (! tblHead.isEmpty()) {
+                       Enumeration e=tblHead.elements();       
+                       while (e.hasMoreElements()) {           
+                               ((Row) e.nextElement()).output(stream);
+                       }
+               }
+               if (! tblFoot.isEmpty()) {
+                       Enumeration e=tblFoot.elements();       
+                       while (e.hasMoreElements()) {           
+                               ((Row) e.nextElement()).output(stream);
+                       }
+               }
+               if (! tblBody.isEmpty()) {
+                       mif="\n\t<TblBody";
+                       stream.write(mif.getBytes());
+                       Enumeration e=tblBody.elements();       
+                       while (e.hasMoreElements()) {           
+                               ((Row) e.nextElement()).output(stream);
+                       }
+                       mif="\n\t> #End tblBody";
+               }
+               mif +="\n> #End Table";
+               stream.write(mif.getBytes());   
+       }
+
+     }
+
+     class XRefFormat {
+
+       public XRefFormat() {}
+     }
+
+     class CrossRefInfo {
+
+       public CrossRefInfo() {}
+     }
+
+     class XRef {
+
+       public XRef() {}
+     }
+
+     class Marker {
+
+       public Marker() {}
+
+     }
+
+     class BookComponent {
+
+       Document document;
+       ColorCatalog colorCatalog;
+       RulingCatalog rulingCatalog;
+       PgfCatalog pgfCatalog;
+       TblCatalog tblCatalog;
+       Vector aFrames =  new Vector();
+        Vector tables =  new Vector();
+       Vector pages =  new Vector();
+       Vector textFlows =  new Vector();       
+       
+       
+       public BookComponent() {
+       
+               document=null; // Initially no values are available    
+               pgfCatalog = new PgfCatalog();
+               rulingCatalog=new RulingCatalog();
+       }
+
+
+       public Frame createFrame(int x, int y,int w,int h) {
+
+               Frame frame=new Frame(x,y,w,h);
+               aFrames.addElement(frame);      
+               return frame;
+               
+       }
+
+       public Frame curFrame() {
+
+               return (Frame) aFrames.lastElement();
+
+       }
+
+       public TextFlow curTextFlow() {
+
+               return (TextFlow) textFlows.lastElement();
+
+       }
+
+       public Tbl createTable() {
+
+               Tbl table=new Tbl();
+               tables.addElement(table);
+               return table;
+       }
+       public Tbl curTable() {
+               
+               return (Tbl) tables.lastElement();
+       }
+
+       public void output(OutputStream stream) throws IOException {
+           String mif="<MIFFile 5.00>" + "\n<Units Upt>"       ;               
+           stream.write(mif.getBytes());
+           pgfCatalog.output(stream);  
+           rulingCatalog.output(stream);       
+           document.output(stream);    
+
+           if (! aFrames.isEmpty()) {
+
+               mif="\n<AFrames";
+               stream.write(mif.getBytes());
+               Enumeration e=aFrames.elements();       
+               while (e.hasMoreElements()) {           
+
+                       ((Frame) e.nextElement()).output(stream);
+               }
+               
+               mif="\n>";
+               stream.write(mif.getBytes());
+           }
+
+           if (! tables.isEmpty()) {
+
+               mif="\n<Tbls";
+               stream.write(mif.getBytes());
+               Enumeration e=tables.elements();        
+               while (e.hasMoreElements()) {           
+
+                       ((Tbl) e.nextElement()).output(stream);
+               }
+               
+               mif="\n>";
+               stream.write(mif.getBytes());
+           }
+       
+    
+           Enumeration e = pages.elements();
+           while (e.hasMoreElements()) {
+
+               ((Page) e.nextElement()).output(stream);
+           }
+
+           e=textFlows.elements();
+           while (e.hasMoreElements()) {
+
+               ((TextFlow) e.nextElement()).output(stream);
+
+           }
+       
+                               
+       }
+
+
+       private Page curPage() {
+
+           return (Page) pages.lastElement();                  
+
+       }
+
+
+
+     }
+
+     class ElementSet {
+
+       public ElementSet() {}
+
+     }
+
+           
+    /**
+     * creates an empty MIF document
+     */
+    public MIFDocument() {
+               
+       bookComponent = new BookComponent();
+      
+    }
+       
+    public void createPage () {
+
+       bookComponent.pages.addElement(new Page());
+       
+    }
+
+    
+    public void addToStream(String s) {
+
+       //Add this string to the curent flow
+       
+       Para para= curFlow.curPara();
+       ParaLine paraLine= para.curParaLine();
+       paraLine.addContent(s);
+
+    }
+
+
+       
+
+    public void output(OutputStream stream) throws IOException {
+
+
+       //Output the contents of bookComponent
+
+       this.bookComponent.output(stream);
+
+   }
+
+
+    public void setDocumentHeightWidth (int height, int width) {
+
+       if (bookComponent.document == null) {
+
+               bookComponent.document=new Document();
+               bookComponent.document.height=height;
+               bookComponent.document.width=width;
+       }
+
+       else if(bookComponent.document.height != height || bookComponent.document.width != width)       {
+
+               MessageHandler.logln("Warning : FrameMaker doesnt support different page-sizes          in a document");                
+       }
+
+   }
+
+
+
+   public void createTextRect(int numCols) {
+       
+       
+       //Create a textrect on the bodypage with these dimensions
+       //This default behaviour will later be changed to reflect on 
+       //the master-page
+
+       
+       (bookComponent.curPage()).addTextRect(numCols); 
+
+
+       // Then create a textflow corresponding to this textrect
+
+       curFlow=new TextFlow();
+       bookComponent.textFlows.addElement(curFlow);
+
+   }
+
+
+   public void setTextRectProp(int left,int top, int width,int height) {
+       
+       
+       (bookComponent.curPage()).curTextRect().setTextRectProp(left,top,width,height);
+
+   
+   } 
+
+
+    public void startLine() {
+
+                               
+       if (curFlow.curPara().curParaLine() != null) {
+               this.addToStream("\n");
+               curFlow.curPara().startParaLine();
+       }
+       else 
+               curFlow.curPara().startParaLine();
+                               
+       
+  }
+               
+
+  public void setBlockProp(int startIndent,int endIndent) {
+
+       
+       curFlow.startPara(); //Start a para
+       curFlow.curPara().setBlockProp(startIndent,endIndent);
+       
+  }
+
+  public void createFrame(int x, int y, int w, int h) {
+
+       //Create a new anchored frame 
+
+       bookComponent.createFrame(x,y,w,h);     
+
+  }
+
+
+
+  public void addImage(String url,int x,int y,int w,int h) {
+
+       Frame frame=bookComponent.createFrame(x,y,w,h);
+       ImportObject imageObject=new ImportObject(url,0,0,w,h);
+       frame.addContent(imageObject);
+       if (curFlow.curPara().curParaLine() == null) {
+               curFlow.curPara().startParaLine();
+               
+       }
+       curFlow.curPara().curParaLine().addContent(frame);
+                       
+               
+  }
+
+  public void createTable() {
+
+       // First create a table with an ID, then add it to the textflow
+
+       Tbl table=bookComponent.createTable();
+       if (curFlow.curPara().curParaLine() == null) {
+               curFlow.curPara().startParaLine();
+               
+       }
+       curFlow.curPara().curParaLine().addContent(table);
+
+       /* The above would have added the table to the textflow
+          But now the flow goes into the table, so ... */
+
+       curFlow=table;
+
+  }
+
+  public void setColumnProp(int colWidth) {
+
+
+       //Get the current table
+
+       Tbl table=bookComponent.curTable();
+       table.addColumn(colWidth);
+
+
+  } 
+
+  public void setCurrent(String current) {
+
+       //Start the table body or header or footer
+       Tbl table=bookComponent.curTable();
+       table.setCurrent(current);
+
+  }
+
+  public void startRow() {
+
+       Tbl table=bookComponent.curTable();
+       table.startRow();       
+
+
+  }
+
+  public void startCell(int rowSpan,int colSpan) {
+       
+       Tbl table=bookComponent.curTable();
+       table.startCell(rowSpan,colSpan);
+
+  }
+
+  public void endTable() {
+
+       // Switch the ref back to the current textflow
+
+       curFlow=bookComponent.curTextFlow();
+
+  }
+
+
+     
+ }