KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lowagie > text > html > HtmlWriter


1 /*
2  * $Id: HtmlWriter.java 2752 2007-05-15 14:58:33Z blowagie $
3  * $Name$
4  *
5  * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
6  *
7  * The contents of this file are subject to the Mozilla Public License Version 1.1
8  * (the "License"); you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the License.
14  *
15  * The Original Code is 'iText, a free JAVA-PDF library'.
16  *
17  * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
18  * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
19  * All Rights Reserved.
20  * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
21  * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
22  *
23  * Contributor(s): all the names of the contributors are added in the source code
24  * where applicable.
25  *
26  * Alternatively, the contents of this file may be used under the terms of the
27  * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
28  * provisions of LGPL are applicable instead of those above. If you wish to
29  * allow use of your version of this file only under the terms of the LGPL
30  * License and not to allow others to use your version of this file under
31  * the MPL, indicate your decision by deleting the provisions above and
32  * replace them with the notice and other provisions required by the LGPL.
33  * If you do not delete the provisions above, a recipient may use your version
34  * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE
35  *
36  * This library is free software; you can redistribute it and/or modify it
37  * under the terms of the MPL as stated above or under the terms of the GNU
38  * Library General Public License as published by the Free Software Foundation;
39  * either version 2 of the License, or any later version.
40  *
41  * This library is distributed in the hope that it will be useful, but WITHOUT
42  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
43  * FOR A PARTICULAR PURPOSE. See the GNU LIBRARY GENERAL PUBLIC LICENSE for more
44  * details.
45  *
46  * If you didn't download this code from the following link, you should check if
47  * you aren't using an obsolete version:
48  * http://www.lowagie.com/iText/
49  */

50
51 package com.lowagie.text.html;
52
53 import java.io.IOException JavaDoc;
54 import java.io.OutputStream JavaDoc;
55 import java.util.Date JavaDoc;
56 import java.util.EmptyStackException JavaDoc;
57 import java.util.Enumeration JavaDoc;
58 import java.util.HashMap JavaDoc;
59 import java.util.Iterator JavaDoc;
60 import java.util.Properties JavaDoc;
61 import java.util.Stack JavaDoc;
62
63 import com.lowagie.text.Anchor;
64 import com.lowagie.text.Annotation;
65 import com.lowagie.text.BadElementException;
66 import com.lowagie.text.Cell;
67 import com.lowagie.text.Chunk;
68 import com.lowagie.text.DocWriter;
69 import com.lowagie.text.Document;
70 import com.lowagie.text.DocumentException;
71 import com.lowagie.text.Element;
72 import com.lowagie.text.ExceptionConverter;
73 import com.lowagie.text.Font;
74 import com.lowagie.text.Header;
75 import com.lowagie.text.HeaderFooter;
76 import com.lowagie.text.Image;
77 import com.lowagie.text.List;
78 import com.lowagie.text.ListItem;
79 import com.lowagie.text.MarkedObject;
80 import com.lowagie.text.MarkedSection;
81 import com.lowagie.text.Meta;
82 import com.lowagie.text.Paragraph;
83 import com.lowagie.text.Phrase;
84 import com.lowagie.text.Rectangle;
85 import com.lowagie.text.Row;
86 import com.lowagie.text.Section;
87 import com.lowagie.text.SimpleTable;
88 import com.lowagie.text.Table;
89 import com.lowagie.text.pdf.BaseFont;
90
91 /**
92  * A <CODE>DocWriter</CODE> class for HTML.
93  * <P>
94  * An <CODE>HtmlWriter</CODE> can be added as a <CODE>DocListener</CODE>
95  * to a certain <CODE>Document</CODE> by getting an instance.
96  * Every <CODE>Element</CODE> added to the original <CODE>Document</CODE>
97  * will be written to the <CODE>OutputStream</CODE> of this <CODE>HtmlWriter</CODE>.
98  * <P>
99  * Example:
100  * <BLOCKQUOTE><PRE>
101  * // creation of the document with a certain size and certain margins
102  * Document document = new Document(PageSize.A4, 50, 50, 50, 50);
103  * try {
104  * // this will write HTML to the Standard OutputStream
105  * <STRONG>HtmlWriter.getInstance(document, System.out);</STRONG>
106  * // this will write HTML to a file called text.html
107  * <STRONG>HtmlWriter.getInstance(document, new FileOutputStream("text.html"));</STRONG>
108  * // this will write HTML to for instance the OutputStream of a HttpServletResponse-object
109  * <STRONG>HtmlWriter.getInstance(document, response.getOutputStream());</STRONG>
110  * }
111  * catch(DocumentException de) {
112  * System.err.println(de.getMessage());
113  * }
114  * // this will close the document and all the OutputStreams listening to it
115  * <STRONG>document.close();</CODE>
116  * </PRE></BLOCKQUOTE>
117  */

118
119 public class HtmlWriter extends DocWriter {
120     
121     // static membervariables (tags)
122

123 /** This is a possible HTML-tag. */
124     public static final byte[] BEGINCOMMENT = getISOBytes("<!-- ");
125     
126 /** This is a possible HTML-tag. */
127     public static final byte[] ENDCOMMENT = getISOBytes(" -->");
128     
129 /** This is a possible HTML-tag. */
130     public static final String JavaDoc NBSP = "&nbsp;";
131     
132     // membervariables
133

134 /** This is the current font of the HTML. */
135     protected Stack JavaDoc currentfont = new Stack JavaDoc();
136     
137 /** This is the standard font of the HTML. */
138     protected Font standardfont = new Font();
139     
140 /** This is a path for images. */
141     protected String JavaDoc imagepath = null;
142     
143 /** Stores the page number. */
144     protected int pageN = 0;
145     
146 /** This is the textual part of a header */
147     protected HeaderFooter header = null;
148     
149 /** This is the textual part of the footer */
150     protected HeaderFooter footer = null;
151     
152 /** Store the markup properties of a MarkedObject. */
153     protected Properties JavaDoc markup = new Properties JavaDoc();
154     
155     // constructor
156

157 /**
158  * Constructs a <CODE>HtmlWriter</CODE>.
159  *
160  * @param doc The <CODE>Document</CODE> that has to be written as HTML
161  * @param os The <CODE>OutputStream</CODE> the writer has to write to.
162  */

163     
164     protected HtmlWriter(Document doc, OutputStream JavaDoc os) {
165         super(doc, os);
166         
167         document.addDocListener(this);
168         this.pageN = document.getPageNumber();
169         try {
170             os.write(LT);
171             os.write(getISOBytes(HtmlTags.HTML));
172             os.write(GT);
173             os.write(NEWLINE);
174             os.write(TAB);
175             os.write(LT);
176             os.write(getISOBytes(HtmlTags.HEAD));
177             os.write(GT);
178         }
179         catch(IOException JavaDoc ioe) {
180             throw new ExceptionConverter(ioe);
181         }
182     }
183     
184     // get an instance of the HtmlWriter
185

186 /**
187  * Gets an instance of the <CODE>HtmlWriter</CODE>.
188  *
189  * @param document The <CODE>Document</CODE> that has to be written
190  * @param os The <CODE>OutputStream</CODE> the writer has to write to.
191  * @return a new <CODE>HtmlWriter</CODE>
192  */

193     
194     public static HtmlWriter getInstance(Document document, OutputStream JavaDoc os) {
195         return new HtmlWriter(document, os);
196     }
197     
198     // implementation of the DocListener methods
199

200 /**
201  * Signals that an new page has to be started.
202  *
203  * @return <CODE>true</CODE> if this action succeeded, <CODE>false</CODE> if not.
204  * @throws DocumentException when a document isn't open yet, or has been closed
205  */

206     
207     public boolean newPage() {
208         try {
209             writeStart(HtmlTags.DIV);
210             write(" ");
211             write(HtmlTags.STYLE);
212             write("=\"");
213             writeCssProperty(Markup.CSS_KEY_PAGE_BREAK_BEFORE, Markup.CSS_VALUE_ALWAYS);
214             write("\" /");
215             os.write(GT);
216         }
217         catch(IOException JavaDoc ioe) {
218             throw new ExceptionConverter(ioe);
219         }
220         return true;
221     }
222     
223 /**
224  * Signals that an <CODE>Element</CODE> was added to the <CODE>Document</CODE>.
225  *
226  * @param element a high level object that has to be translated to HTML
227  * @return <CODE>true</CODE> if the element was added, <CODE>false</CODE> if not.
228  * @throws DocumentException when a document isn't open yet, or has been closed
229  */

230     
231     public boolean add(Element element) throws DocumentException {
232         if (pause) {
233             return false;
234         }
235         try {
236             switch(element.type()) {
237                 case Element.HEADER:
238                     try {
239                         Header h = (Header) element;
240                         if (HtmlTags.STYLESHEET.equals(h.getName())) {
241                             writeLink(h);
242                         }
243                         else if (HtmlTags.JAVASCRIPT.equals(h.getName())) {
244                             writeJavaScript(h);
245                         }
246                         else {
247                             writeHeader(h);
248                         }
249                     }
250                     catch(ClassCastException JavaDoc cce) {
251                     }
252                     return true;
253                 case Element.SUBJECT:
254                 case Element.KEYWORDS:
255                 case Element.AUTHOR:
256                     Meta meta = (Meta) element;
257                     writeHeader(meta);
258                     return true;
259                 case Element.TITLE:
260                     addTabs(2);
261                     writeStart(HtmlTags.TITLE);
262                     os.write(GT);
263                     addTabs(3);
264                     write(HtmlEncoder.encode(((Meta)element).getContent()));
265                     addTabs(2);
266                     writeEnd(HtmlTags.TITLE);
267                     return true;
268                 case Element.CREATOR:
269                     writeComment("Creator: " + HtmlEncoder.encode(((Meta)element).getContent()));
270                     return true;
271                 case Element.PRODUCER:
272                     writeComment("Producer: " + HtmlEncoder.encode(((Meta)element).getContent()));
273                     return true;
274                 case Element.CREATIONDATE:
275                     writeComment("Creationdate: " + HtmlEncoder.encode(((Meta)element).getContent()));
276                     return true;
277                 case Element.MARKED:
278                     if (element instanceof MarkedSection) {
279                         MarkedSection ms = (MarkedSection)element;
280                         addTabs(1);
281                         writeStart(HtmlTags.DIV);
282                         writeMarkupAttributes(ms.getMarkupAttributes());
283                         os.write(GT);
284                         MarkedObject mo = ((MarkedSection)element).title();
285                         if (mo != null) {
286                             markup = mo.getMarkupAttributes();
287                             mo.process(this);
288                         }
289                         ms.process(this);
290                         writeEnd(HtmlTags.DIV);
291                         return true;
292                     }
293                     else {
294                         MarkedObject mo = (MarkedObject) element;
295                         markup = mo.getMarkupAttributes();
296                         return mo.process(this);
297                     }
298                 default:
299                     write(element, 2);
300                     return true;
301             }
302         }
303         catch(IOException JavaDoc ioe) {
304             throw new ExceptionConverter(ioe);
305         }
306     }
307     
308 /**
309  * Signals that the <CODE>Document</CODE> has been opened and that
310  * <CODE>Elements</CODE> can be added.
311  * <P>
312  * The <CODE>HEAD</CODE>-section of the HTML-document is written.
313  */

314     
315     public void open() {
316         super.open();
317         try {
318             writeComment(Document.getVersion());
319             writeComment("CreationDate: " + new Date JavaDoc().toString());
320             addTabs(1);
321             writeEnd(HtmlTags.HEAD);
322             addTabs(1);
323             writeStart(HtmlTags.BODY);
324             if (document.leftMargin() > 0) {
325                 write(HtmlTags.LEFTMARGIN, String.valueOf(document.leftMargin()));
326             }
327             if (document.rightMargin() > 0) {
328                 write(HtmlTags.RIGHTMARGIN, String.valueOf(document.rightMargin()));
329             }
330             if (document.topMargin() > 0) {
331                 write(HtmlTags.TOPMARGIN, String.valueOf(document.topMargin()));
332             }
333             if (document.bottomMargin() > 0) {
334                 write(HtmlTags.BOTTOMMARGIN, String.valueOf(document.bottomMargin()));
335             }
336             if (pageSize.getBackgroundColor() != null) {
337                 write(HtmlTags.BACKGROUNDCOLOR, HtmlEncoder.encode(pageSize.getBackgroundColor()));
338             }
339             if (document.getJavaScript_onLoad() != null) {
340                 write(HtmlTags.JAVASCRIPT_ONLOAD, HtmlEncoder.encode(document.getJavaScript_onLoad()));
341             }
342             if (document.getJavaScript_onUnLoad() != null) {
343                 write(HtmlTags.JAVASCRIPT_ONUNLOAD, HtmlEncoder.encode(document.getJavaScript_onUnLoad()));
344             }
345             if (document.getHtmlStyleClass() != null) {
346                 write(Markup.HTML_ATTR_CSS_CLASS, document.getHtmlStyleClass());
347             }
348             os.write(GT);
349             initHeader(); // line added by David Freels
350
}
351         catch(IOException JavaDoc ioe) {
352             throw new ExceptionConverter(ioe);
353         }
354     }
355     
356 /**
357  * Signals that the <CODE>Document</CODE> was closed and that no other
358  * <CODE>Elements</CODE> will be added.
359  */

360     
361     public void close() {
362         try {
363             initFooter(); // line added by David Freels
364
addTabs(1);
365             writeEnd(HtmlTags.BODY);
366             os.write(NEWLINE);
367             writeEnd(HtmlTags.HTML);
368             super.close();
369         }
370         catch(IOException JavaDoc ioe) {
371             throw new ExceptionConverter(ioe);
372         }
373     }
374     
375     // some protected methods
376

377 /**
378  * Adds the header to the top of the </CODE>Document</CODE>
379  */

380     
381     protected void initHeader() {
382         if (header != null) {
383             try {
384                 add(header.paragraph());
385             }
386             catch(Exception JavaDoc e) {
387                 throw new ExceptionConverter(e);
388             }
389         }
390     }
391     
392 /**
393  * Adds the header to the top of the </CODE>Document</CODE>
394  */

395     
396     protected void initFooter() {
397         if (footer != null) {
398             try {
399                 // Set the page number. HTML has no notion of a page, so it should always
400
// add up to 1
401
footer.setPageNumber(pageN + 1);
402                 add(footer.paragraph());
403             }
404             catch(Exception JavaDoc e) {
405                 throw new ExceptionConverter(e);
406             }
407         }
408     }
409     
410 /**
411  * Writes a Metatag in the header.
412  *
413  * @param meta the element that has to be written
414  * @throws IOException
415  */

416     
417     protected void writeHeader(Meta meta) throws IOException JavaDoc {
418         addTabs(2);
419         writeStart(HtmlTags.META);
420         switch(meta.type()) {
421             case Element.HEADER:
422                 write(HtmlTags.NAME, ((Header) meta).getName());
423                 break;
424             case Element.SUBJECT:
425                 write(HtmlTags.NAME, HtmlTags.SUBJECT);
426                 break;
427             case Element.KEYWORDS:
428                 write(HtmlTags.NAME, HtmlTags.KEYWORDS);
429                 break;
430             case Element.AUTHOR:
431                 write(HtmlTags.NAME, HtmlTags.AUTHOR);
432                 break;
433         }
434         write(HtmlTags.CONTENT, HtmlEncoder.encode(meta.getContent()));
435         writeEnd();
436     }
437     
438 /**
439  * Writes a link in the header.
440  *
441  * @param header the element that has to be written
442  * @throws IOException
443  */

444     
445     protected void writeLink(Header header) throws IOException JavaDoc {
446         addTabs(2);
447         writeStart(HtmlTags.LINK);
448         write(HtmlTags.REL, header.getName());
449         write(HtmlTags.TYPE, HtmlTags.TEXT_CSS);
450         write(HtmlTags.REFERENCE, header.getContent());
451         writeEnd();
452     }
453     
454 /**
455  * Writes a JavaScript section or, if the markup attribute HtmlTags.URL is set, a JavaScript reference in the header.
456  *
457  * @param header the element that has to be written
458  * @throws IOException
459  */

460     
461     protected void writeJavaScript(Header header) throws IOException JavaDoc {
462         addTabs(2);
463         writeStart(HtmlTags.SCRIPT);
464         write(HtmlTags.LANGUAGE, HtmlTags.JAVASCRIPT);
465         if (markup.size() > 0) {
466           /* JavaScript reference example:
467            *
468            * <script language="JavaScript" SRC="../../../../../myPath/MyFunctions.js"/>
469            */

470           writeMarkupAttributes(markup);
471           os.write(GT);
472           writeEnd(HtmlTags.SCRIPT);
473         }
474         else {
475           /* JavaScript coding convention:
476            *
477            * <script language="JavaScript" type="text/javascript">
478            * <!--
479            * // ... JavaScript methods ...
480            * //-->
481            * </script>
482            */

483           write(HtmlTags.TYPE, Markup.HTML_VALUE_JAVASCRIPT);
484           os.write(GT);
485           addTabs(2);
486           write(new String JavaDoc(BEGINCOMMENT) + "\n");
487           write(header.getContent());
488           addTabs(2);
489           write("//" + new String JavaDoc(ENDCOMMENT));
490           addTabs(2);
491           writeEnd(HtmlTags.SCRIPT);
492         }
493     }
494     
495 /**
496  * Writes some comment.
497  * <P>
498  * This method writes some comment.
499  *
500  * @param comment the comment that has to be written
501  * @throws IOException
502  */

503     
504     protected void writeComment(String JavaDoc comment) throws IOException JavaDoc {
505         addTabs(2);
506         os.write(BEGINCOMMENT);
507         write(comment);
508         os.write(ENDCOMMENT);
509     }
510     
511     // public methods
512

513 /**
514  * Changes the standardfont.
515  *
516  * @param standardfont The font
517  */

518     
519     public void setStandardFont(Font standardfont) {
520         this.standardfont = standardfont;
521     }
522     
523 /**
524  * Checks if a given font is the same as the font that was last used.
525  *
526  * @param font the font of an object
527  * @return true if the font differs
528  */

529     
530     public boolean isOtherFont(Font font) {
531         try {
532             Font cFont = (Font) currentfont.peek();
533             if (cFont.compareTo(font) == 0) return false;
534             return true;
535         }
536         catch(EmptyStackException JavaDoc ese) {
537             if (standardfont.compareTo(font) == 0) return false;
538             return true;
539         }
540     }
541     
542 /**
543  * Sets the basepath for images.
544  * <P>
545  * This is especially useful if you add images using a file,
546  * rather than an URL. In PDF there is no problem, since
547  * the images are added inline, but in HTML it is sometimes
548  * necessary to use a relative path or a special path to some
549  * images directory.
550  *
551  * @param imagepath the new imagepath
552  */

553     
554     public void setImagepath(String JavaDoc imagepath) {
555         this.imagepath = imagepath;
556     }
557     
558 /**
559  * Resets the imagepath.
560  */

561     
562     public void resetImagepath() {
563         imagepath = null;
564     }
565     
566 /**
567  * Changes the header of this document.
568  *
569  * @param header the new header
570  */

571     
572     public void setHeader(HeaderFooter header) {
573         this.header = header;
574     }
575     
576 /**
577  * Changes the footer of this document.
578  *
579  * @param footer the new footer
580  */

581     
582     public void setFooter(HeaderFooter footer) {
583         this.footer = footer;
584     }
585     
586 /**
587  * Signals that a <CODE>String</CODE> was added to the <CODE>Document</CODE>.
588  *
589  * @param string a String to add to the HTML
590  * @return <CODE>true</CODE> if the string was added, <CODE>false</CODE> if not.
591  * @throws DocumentException when a document isn't open yet, or has been closed
592  */

593     
594     public boolean add(String JavaDoc string) {
595         if (pause) {
596             return false;
597         }
598         try
599         {
600             write(string);
601             return true;
602         }
603         catch(IOException JavaDoc ioe) {
604             throw new ExceptionConverter(ioe);
605         }
606     }
607     
608 /**
609  * Writes the HTML representation of an element.
610  *
611  * @param element the element
612  * @param indent the indentation
613  * @throws IOException
614  */

615     
616     protected void write(Element element, int indent) throws IOException JavaDoc {
617         Properties JavaDoc styleAttributes = null;
618         switch(element.type()) {
619             case Element.MARKED: {
620                 try {
621                     add(element);
622                 } catch (DocumentException e) {
623                     e.printStackTrace();
624                 }
625                 return;
626             }
627             case Element.CHUNK:
628             {
629                 Chunk chunk = (Chunk) element;
630                 // if the chunk contains an image, return the image representation
631
Image image = chunk.getImage();
632                 if (image != null) {
633                     write(image, indent);
634                     return;
635                 }
636                 
637                 if (chunk.isEmpty()) return;
638                 HashMap JavaDoc attributes = chunk.getAttributes();
639                 if (attributes != null && attributes.get(Chunk.NEWPAGE) != null) {
640                     return;
641                 }
642                 boolean tag = isOtherFont(chunk.getFont()) || markup.size() > 0;
643                 if (tag) {
644                     // start span tag
645
addTabs(indent);
646                     writeStart(HtmlTags.SPAN);
647                     if (isOtherFont(chunk.getFont())) {
648                         write(chunk.getFont(), null);
649                     }
650                     writeMarkupAttributes(markup);
651                     os.write(GT);
652                 }
653                 if (attributes != null && attributes.get(Chunk.SUBSUPSCRIPT) != null) {
654                     // start sup or sub tag
655
if (((Float JavaDoc)attributes.get(Chunk.SUBSUPSCRIPT)).floatValue() > 0) {
656                         writeStart(HtmlTags.SUP);
657                     }
658                     else {
659                         writeStart(HtmlTags.SUB);
660                     }
661                     os.write(GT);
662                 }
663                 // contents
664
write(HtmlEncoder.encode(chunk.getContent()));
665                 if (attributes != null && attributes.get(Chunk.SUBSUPSCRIPT) != null) {
666                     // end sup or sub tag
667
os.write(LT);
668                     os.write(FORWARD);
669                     if (((Float JavaDoc)attributes.get(Chunk.SUBSUPSCRIPT)).floatValue() > 0) {
670                         write(HtmlTags.SUP);
671                     }
672                     else {
673                         write(HtmlTags.SUB);
674                     }
675                     os.write(GT);
676                 }
677                 if (tag) {
678                     // end tag
679
writeEnd(Markup.HTML_TAG_SPAN);
680                 }
681                 return;
682             }
683             case Element.PHRASE:
684             {
685                 Phrase phrase = (Phrase) element;
686                 styleAttributes = new Properties JavaDoc();
687                 if (phrase.hasLeading()) styleAttributes.setProperty(Markup.CSS_KEY_LINEHEIGHT, phrase.getLeading() + "pt");
688                 
689                 // start tag
690
addTabs(indent);
691                 writeStart(Markup.HTML_TAG_SPAN);
692                 writeMarkupAttributes(markup);
693                 write(phrase.getFont(), styleAttributes);
694                 os.write(GT);
695                 currentfont.push(phrase.getFont());
696                 // contents
697
for (Iterator JavaDoc i = phrase.iterator(); i.hasNext(); ) {
698                     write((Element) i.next(), indent + 1);
699                 }
700                 // end tag
701
addTabs(indent);
702                 writeEnd(Markup.HTML_TAG_SPAN);
703                 currentfont.pop();
704                 return;
705             }
706             case Element.ANCHOR:
707             {
708                 Anchor anchor = (Anchor) element;
709                 styleAttributes = new Properties JavaDoc();
710                 if (anchor.hasLeading()) styleAttributes.setProperty(Markup.CSS_KEY_LINEHEIGHT, anchor.getLeading() + "pt");
711                 
712                 // start tag
713
addTabs(indent);
714                 writeStart(HtmlTags.ANCHOR);
715                 if (anchor.getName() != null) {
716                     write(HtmlTags.NAME, anchor.getName());
717                 }
718                 if (anchor.getReference() != null) {
719                     write(HtmlTags.REFERENCE, anchor.getReference());
720                 }
721                 writeMarkupAttributes(markup);
722                 write(anchor.getFont(), styleAttributes);
723                 os.write(GT);
724                 currentfont.push(anchor.getFont());
725                 // contents
726
for (Iterator JavaDoc i = anchor.iterator(); i.hasNext(); ) {
727                     write((Element) i.next(), indent + 1);
728                 }
729                 // end tag
730
addTabs(indent);
731                 writeEnd(HtmlTags.ANCHOR);
732                 currentfont.pop();
733                 return;
734             }
735             case Element.PARAGRAPH:
736             {
737                 Paragraph paragraph = (Paragraph) element;
738                 styleAttributes = new Properties JavaDoc();
739                 if (paragraph.hasLeading()) styleAttributes.setProperty(Markup.CSS_KEY_LINEHEIGHT, paragraph.getTotalLeading() + "pt");
740                 // start tag
741
addTabs(indent);
742                 writeStart(HtmlTags.DIV);
743                 writeMarkupAttributes(markup);
744                 String JavaDoc alignment = HtmlEncoder.getAlignment(paragraph.getAlignment());
745                 if (!"".equals(alignment)) {
746                     write(HtmlTags.ALIGN, alignment);
747                 }
748                 write(paragraph.getFont(), styleAttributes);
749                 os.write(GT);
750                 currentfont.push(paragraph.getFont());
751                 // contents
752
for (Iterator JavaDoc i = paragraph.iterator(); i.hasNext(); ) {
753                     write((Element)i.next(), indent + 1);
754                 }
755                 // end tag
756
addTabs(indent);
757                 writeEnd(HtmlTags.DIV);
758                 currentfont.pop();
759                 return;
760             }
761             case Element.SECTION:
762             case Element.CHAPTER:
763             {
764                 // part of the start tag + contents
765
writeSection((Section) element, indent);
766                 return;
767             }
768             case Element.LIST:
769             {
770                 List list = (List) element;
771                 // start tag
772
addTabs(indent);
773                 if (list.isNumbered()) {
774                     writeStart(HtmlTags.ORDEREDLIST);
775                 }
776                 else {
777                     writeStart(HtmlTags.UNORDEREDLIST);
778                 }
779                 writeMarkupAttributes(markup);
780                 os.write(GT);
781                 // contents
782
for (Iterator JavaDoc i = list.getItems().iterator(); i.hasNext(); ) {
783                     write((Element) i.next(), indent + 1);
784                 }
785                 // end tag
786
addTabs(indent);
787                 if (list.isNumbered()) {
788                     writeEnd(HtmlTags.ORDEREDLIST);
789                 }
790                 else {
791                     writeEnd(HtmlTags.UNORDEREDLIST);
792                 }
793                 return;
794             }
795             case Element.LISTITEM:
796             {
797                 ListItem listItem = (ListItem) element;
798                 styleAttributes = new Properties JavaDoc();
799                 if (listItem.hasLeading()) styleAttributes.setProperty(Markup.CSS_KEY_LINEHEIGHT, listItem.getTotalLeading() + "pt");
800                 
801                 // start tag
802
addTabs(indent);
803                 writeStart(HtmlTags.LISTITEM);
804                 writeMarkupAttributes(markup);
805                 write(listItem.getFont(), styleAttributes);
806                 os.write(GT);
807                 currentfont.push(listItem.getFont());
808                 // contents
809
for (Iterator JavaDoc i = listItem.iterator(); i.hasNext(); ) {
810                     write((Element) i.next(), indent + 1);
811                 }
812                 // end tag
813
addTabs(indent);
814                 writeEnd(HtmlTags.LISTITEM);
815                 currentfont.pop();
816                 return;
817             }
818             case Element.CELL:
819             {
820                 Cell cell = (Cell) element;
821                 
822                 // start tag
823
addTabs(indent);
824                 if (cell.isHeader()) {
825                     writeStart(HtmlTags.HEADERCELL);
826                 }
827                 else {
828                     writeStart(HtmlTags.CELL);
829                 }
830                 writeMarkupAttributes(markup);
831                 if (cell.getBorderWidth() != Rectangle.UNDEFINED) {
832                     write(HtmlTags.BORDERWIDTH, String.valueOf(cell.getBorderWidth()));
833                 }
834                 if (cell.getBorderColor() != null) {
835                     write(HtmlTags.BORDERCOLOR, HtmlEncoder.encode(cell.getBorderColor()));
836                 }
837                 if (cell.getBackgroundColor() != null) {
838                     write(HtmlTags.BACKGROUNDCOLOR, HtmlEncoder.encode(cell.getBackgroundColor()));
839                 }
840                 String JavaDoc alignment = HtmlEncoder.getAlignment(cell.getHorizontalAlignment());
841                 if (!"".equals(alignment)) {
842                     write(HtmlTags.HORIZONTALALIGN, alignment);
843                 }
844                 alignment = HtmlEncoder.getAlignment(cell.getVerticalAlignment());
845                 if (!"".equals(alignment)) {
846                     write(HtmlTags.VERTICALALIGN, alignment);
847                 }
848                 if (cell.getWidthAsString() != null) {
849                     write(HtmlTags.WIDTH, cell.getWidthAsString());
850                 }
851                 if (cell.getColspan() != 1) {
852                     write(HtmlTags.COLSPAN, String.valueOf(cell.getColspan()));
853                 }
854                 if (cell.getRowspan() != 1) {
855                     write(HtmlTags.ROWSPAN, String.valueOf(cell.getRowspan()));
856                 }
857                 if (cell.getMaxLines() == 1) {
858                     write(HtmlTags.NOWRAP, String.valueOf(true));
859                 }
860                 os.write(GT);
861                 // contents
862
if (cell.isEmpty()) {
863                     write(NBSP);
864                 } else {
865                     for (Iterator JavaDoc i = cell.getElements(); i.hasNext(); ) {
866                         write((Element) i.next(), indent + 1);
867                     }
868                 }
869                 // end tag
870
addTabs(indent);
871                 if (cell.isHeader()) {
872                     writeEnd(HtmlTags.HEADERCELL);
873                 }
874                 else {
875                     writeEnd(HtmlTags.CELL);
876                 }
877                 return;
878             }
879             case Element.ROW:
880             {
881                 Row row = (Row) element;
882                 
883                 // start tag
884
addTabs(indent);
885                 writeStart(HtmlTags.ROW);
886                 writeMarkupAttributes(markup);
887                 os.write(GT);
888                 // contents
889
Element cell;
890                 for (int i = 0; i < row.getColumns(); i++) {
891                     if ((cell = (Element)row.getCell(i)) != null) {
892                         write(cell, indent + 1);
893                     }
894                 }
895                 // end tag
896
addTabs(indent);
897                 writeEnd(HtmlTags.ROW);
898                 return;
899             }
900             case Element.TABLE:
901             {
902                 Table table;
903                 try {
904                     table = (Table) element;
905                 }
906                 catch(ClassCastException JavaDoc cce) {
907                     try {
908                         table = ((SimpleTable)element).createTable();
909                     } catch (BadElementException e) {
910                         throw new ExceptionConverter(e);
911                     }
912                 }
913                 table.complete();
914                 // start tag
915
addTabs(indent);
916                 writeStart(HtmlTags.TABLE);
917                 writeMarkupAttributes(markup);
918                 os.write(SPACE);
919                 write(HtmlTags.WIDTH);
920                 os.write(EQUALS);
921                 os.write(QUOTE);
922                 write(String.valueOf(table.getWidth()));
923                 if (!table.isLocked()){
924                     write("%");
925                 }
926                 os.write(QUOTE);
927                 String JavaDoc alignment = HtmlEncoder.getAlignment(table.getAlignment());
928                 if (!"".equals(alignment)) {
929                     write(HtmlTags.ALIGN, alignment);
930                 }
931                 write(HtmlTags.CELLPADDING, String.valueOf(table.getPadding()));
932                 write(HtmlTags.CELLSPACING, String.valueOf(table.getSpacing()));
933                 if (table.getBorderWidth() != Rectangle.UNDEFINED) {
934                     write(HtmlTags.BORDERWIDTH, String.valueOf(table.getBorderWidth()));
935                 }
936                 if (table.getBorderColor() != null) {
937                     write(HtmlTags.BORDERCOLOR, HtmlEncoder.encode(table.getBorderColor()));
938                 }
939                 if (table.getBackgroundColor() != null) {
940                     write(HtmlTags.BACKGROUNDCOLOR, HtmlEncoder.encode(table.getBackgroundColor()));
941                 }
942                 os.write(GT);
943                 // contents
944
Row row;
945                 for (Iterator JavaDoc iterator = table.iterator(); iterator.hasNext(); ) {
946                     row = (Row) iterator.next();
947                     write(row, indent + 1);
948                 }
949                 // end tag
950
addTabs(indent);
951                 writeEnd(HtmlTags.TABLE);
952                 return;
953             }
954             case Element.ANNOTATION:
955             {
956                 Annotation annotation = (Annotation) element;
957                 writeComment(annotation.title() + ": " + annotation.content());
958                 return;
959             }
960             case Element.IMGRAW:
961             case Element.JPEG:
962             case Element.IMGTEMPLATE:
963             {
964                 Image image = (Image) element;
965                 if (image.getUrl() == null) {
966                     return;
967                 }
968                 
969                 // start tag
970
addTabs(indent);
971                 writeStart(HtmlTags.IMAGE);
972                 String JavaDoc path = image.getUrl().toString();
973                 if (imagepath != null) {
974                     if (path.indexOf('/') > 0) {
975                         path = imagepath + path.substring(path.lastIndexOf('/') + 1);
976                     }
977                     else {
978                         path = imagepath + path;
979                     }
980                 }
981                 write(HtmlTags.URL, path);
982                 if ((image.getAlignment() & Image.RIGHT) > 0) {
983                     write(HtmlTags.ALIGN, HtmlTags.ALIGN_RIGHT);
984                 }
985                 else if ((image.getAlignment() & Image.MIDDLE) > 0) {
986                     write(HtmlTags.ALIGN, HtmlTags.ALIGN_MIDDLE);
987                 }
988                 else {
989                     write(HtmlTags.ALIGN, HtmlTags.ALIGN_LEFT);
990                 }
991                 if (image.getAlt() != null) {
992                     write(HtmlTags.ALT, image.getAlt());
993                 }
994                 write(HtmlTags.PLAINWIDTH, String.valueOf(image.getScaledWidth()));
995                 write(HtmlTags.PLAINHEIGHT, String.valueOf(image.getScaledHeight()));
996                 writeMarkupAttributes(markup);
997                 writeEnd();
998                 return;
999             }
1000            
1001            default:
1002                return;
1003        }
1004    }
1005    
1006/**
1007 * Writes the HTML representation of a section.
1008 *
1009 * @param section the section to write
1010 * @param indent the indentation
1011 * @throws IOException
1012 */

1013    
1014    protected void writeSection(Section section, int indent) throws IOException JavaDoc {
1015        if (section.getTitle() != null) {
1016            int depth = section.getDepth() - 1;
1017            if (depth > 5) {
1018                depth = 5;
1019            }
1020            Properties JavaDoc styleAttributes = new Properties JavaDoc();
1021            if (section.getTitle().hasLeading()) styleAttributes.setProperty(Markup.CSS_KEY_LINEHEIGHT, section.getTitle().getTotalLeading() + "pt");
1022            // start tag
1023
addTabs(indent);
1024            writeStart(HtmlTags.H[depth]);
1025            write(section.getTitle().getFont(), styleAttributes);
1026            String JavaDoc alignment = HtmlEncoder.getAlignment(section.getTitle().getAlignment());
1027            if (!"".equals(alignment)) {
1028                write(HtmlTags.ALIGN, alignment);
1029            }
1030            writeMarkupAttributes(markup);
1031            os.write(GT);
1032            currentfont.push(section.getTitle().getFont());
1033            // contents
1034
for (Iterator JavaDoc i = section.getTitle().iterator(); i.hasNext(); ) {
1035                write((Element)i.next(), indent + 1);
1036            }
1037            // end tag
1038
addTabs(indent);
1039            writeEnd(HtmlTags.H[depth]);
1040            currentfont.pop();
1041        }
1042        for (Iterator JavaDoc i = section.iterator(); i.hasNext(); ) {
1043            write((Element) i.next(), indent);
1044        }
1045    }
1046    
1047    /**
1048     * Writes the representation of a <CODE>Font</CODE>.
1049     *
1050     * @param font a <CODE>Font</CODE>
1051     * @param styleAttributes the style of the font
1052     * @throws IOException
1053     */

1054    
1055    protected void write(Font font, Properties JavaDoc styleAttributes) throws IOException JavaDoc {
1056        if (font == null || !isOtherFont(font) /* || styleAttributes == null*/) return;
1057        write(" ");
1058        write(HtmlTags.STYLE);
1059        write("=\"");
1060        if (styleAttributes != null) {
1061            String JavaDoc key;
1062            for (Enumeration JavaDoc e = styleAttributes.propertyNames(); e.hasMoreElements(); ) {
1063                key = (String JavaDoc)e.nextElement();
1064                writeCssProperty(key, styleAttributes.getProperty(key));
1065            }
1066        }
1067        if (isOtherFont(font)) {
1068            writeCssProperty(Markup.CSS_KEY_FONTFAMILY, font.getFamilyname());
1069            
1070            if (font.getSize() != Font.UNDEFINED) {
1071                writeCssProperty(Markup.CSS_KEY_FONTSIZE, font.getSize() + "pt");
1072            }
1073            if (font.getColor() != null) {
1074                writeCssProperty(Markup.CSS_KEY_COLOR, HtmlEncoder.encode(font.getColor()));
1075            }
1076            
1077            int fontstyle = font.getStyle();
1078            BaseFont bf = font.getBaseFont();
1079            if (bf != null) {
1080                String JavaDoc ps = bf.getPostscriptFontName().toLowerCase();
1081                if (ps.indexOf("bold") >= 0) {
1082                    if (fontstyle == Font.UNDEFINED)
1083                        fontstyle = 0;
1084                    fontstyle |= Font.BOLD;
1085                }
1086                if (ps.indexOf("italic") >= 0 || ps.indexOf("oblique") >= 0) {
1087                    if (fontstyle == Font.UNDEFINED)
1088                        fontstyle = 0;
1089                    fontstyle |= Font.ITALIC;
1090                }
1091            }
1092            if (fontstyle != Font.UNDEFINED && fontstyle != Font.NORMAL) {
1093                switch (fontstyle & Font.BOLDITALIC) {
1094                    case Font.BOLD:
1095                        writeCssProperty(Markup.CSS_KEY_FONTWEIGHT, Markup.CSS_VALUE_BOLD);
1096                        break;
1097                    case Font.ITALIC:
1098                        writeCssProperty(Markup.CSS_KEY_FONTSTYLE, Markup.CSS_VALUE_ITALIC);
1099                        break;
1100                    case Font.BOLDITALIC:
1101                        writeCssProperty(Markup.CSS_KEY_FONTWEIGHT, Markup.CSS_VALUE_BOLD);
1102                        writeCssProperty(Markup.CSS_KEY_FONTSTYLE, Markup.CSS_VALUE_ITALIC);
1103                        break;
1104                }
1105                
1106                // CSS only supports one decoration tag so if both are specified
1107
// only one of the two will display
1108
if ((fontstyle & Font.UNDERLINE) > 0) {
1109                    writeCssProperty(Markup.CSS_KEY_TEXTDECORATION, Markup.CSS_VALUE_UNDERLINE);
1110                }
1111                if ((fontstyle & Font.STRIKETHRU) > 0) {
1112                    writeCssProperty(Markup.CSS_KEY_TEXTDECORATION, Markup.CSS_VALUE_LINETHROUGH);
1113                }
1114            }
1115        }
1116        write("\"");
1117    }
1118    
1119    /**
1120     * Writes out a CSS property.
1121     * @param prop a CSS property
1122     * @param value the value of the CSS property
1123     * @throws IOException
1124     */

1125    protected void writeCssProperty(String JavaDoc prop, String JavaDoc value) throws IOException JavaDoc {
1126        write(new StringBuffer JavaDoc(prop).append(": ").append(value).append("; ").toString());
1127    }
1128}
Popular Tags