From 6025b6016517c6d898d8957d1d7e03ba71431912 Mon Sep 17 00:00:00 2001 From: tknall Date: Fri, 1 Dec 2006 12:20:24 +0000 Subject: Initial import of release 2.2. git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@4 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../java/com/lowagie/text/html/HtmlEncoder.java | 211 ++++ .../java/com/lowagie/text/html/HtmlParser.java | 206 ++++ src/main/java/com/lowagie/text/html/HtmlPeer.java | 112 ++ .../java/com/lowagie/text/html/HtmlTagMap.java | 296 ++++++ src/main/java/com/lowagie/text/html/HtmlTags.java | 331 ++++++ .../java/com/lowagie/text/html/HtmlWriter.java | 1094 ++++++++++++++++++++ .../com/lowagie/text/html/SAXmyHtmlHandler.java | 293 ++++++ .../com/lowagie/text/html/simpleparser/ALink.java | 57 + .../text/html/simpleparser/ChainedProperties.java | 127 +++ .../text/html/simpleparser/FactoryProperties.java | 244 +++++ .../lowagie/text/html/simpleparser/HTMLWorker.java | 623 +++++++++++ .../com/lowagie/text/html/simpleparser/Img.java | 60 ++ .../lowagie/text/html/simpleparser/IncCell.java | 124 +++ .../lowagie/text/html/simpleparser/IncTable.java | 121 +++ .../lowagie/text/html/simpleparser/StyleSheet.java | 112 ++ 15 files changed, 4011 insertions(+) create mode 100644 src/main/java/com/lowagie/text/html/HtmlEncoder.java create mode 100644 src/main/java/com/lowagie/text/html/HtmlParser.java create mode 100644 src/main/java/com/lowagie/text/html/HtmlPeer.java create mode 100644 src/main/java/com/lowagie/text/html/HtmlTagMap.java create mode 100644 src/main/java/com/lowagie/text/html/HtmlTags.java create mode 100644 src/main/java/com/lowagie/text/html/HtmlWriter.java create mode 100644 src/main/java/com/lowagie/text/html/SAXmyHtmlHandler.java create mode 100644 src/main/java/com/lowagie/text/html/simpleparser/ALink.java create mode 100644 src/main/java/com/lowagie/text/html/simpleparser/ChainedProperties.java create mode 100644 src/main/java/com/lowagie/text/html/simpleparser/FactoryProperties.java create mode 100644 src/main/java/com/lowagie/text/html/simpleparser/HTMLWorker.java create mode 100644 src/main/java/com/lowagie/text/html/simpleparser/Img.java create mode 100644 src/main/java/com/lowagie/text/html/simpleparser/IncCell.java create mode 100644 src/main/java/com/lowagie/text/html/simpleparser/IncTable.java create mode 100644 src/main/java/com/lowagie/text/html/simpleparser/StyleSheet.java (limited to 'src/main/java/com/lowagie/text/html') diff --git a/src/main/java/com/lowagie/text/html/HtmlEncoder.java b/src/main/java/com/lowagie/text/html/HtmlEncoder.java new file mode 100644 index 0000000..2501815 --- /dev/null +++ b/src/main/java/com/lowagie/text/html/HtmlEncoder.java @@ -0,0 +1,211 @@ +/* + * $Id: HtmlEncoder.java,v 1.56 2005/05/04 14:33:47 blowagie Exp $ + * $Name: $ + * + * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html; + +import java.awt.Color; + +import com.lowagie.text.Element; + +/** + * This class converts a String to the HTML-format of a String. + *

+ * To convert the String, each character is examined: + *

+ *

+ * Example: + *

+ *    String htmlPresentation = HtmlEncoder.encode("Marie-Thérèse Sørensen");
+ * 

+ * for more info: see O'Reilly; "HTML: The Definitive Guide" (page 164) + * + * @author mario.maccarini@rug.ac.be + */ + +public class HtmlEncoder { + + // membervariables + +/** List with the HTML translation of all the characters. */ + private static final String[] htmlCode = new String[256]; + + static { + for (int i = 0; i < 10; i++) { + htmlCode[i] = "�" + i + ";"; + } + + for (int i = 10; i < 32; i++) { + htmlCode[i] = "�" + i + ";"; + } + + for (int i = 32; i < 128; i++) { + htmlCode[i] = String.valueOf((char)i); + } + + // Special characters + htmlCode['\t'] = "\t"; + htmlCode['\n'] = "<" + HtmlTags.NEWLINE + " />\n"; + htmlCode['\"'] = """; // double quote + htmlCode['&'] = "&"; // ampersand + htmlCode['<'] = "<"; // lower than + htmlCode['>'] = ">"; // greater than + + for (int i = 128; i < 256; i++) { + htmlCode[i] = "&#" + i + ";"; + } + } + + + // constructors + +/** + * This class will never be constructed. + *

+ * HtmlEncoder only contains static methods. + */ + + private HtmlEncoder () { } + + // methods + +/** + * Converts a String to the HTML-format of this String. + * + * @param string The String to convert + * @return a String + */ + + public static String encode(String string) { + int n = string.length(); + char character; + StringBuffer buffer = new StringBuffer(); + // loop over all the characters of the String. + for (int i = 0; i < n; i++) { + character = string.charAt(i); + // the Htmlcode of these characters are added to a StringBuffer one by one + if (character < 256) { + buffer.append(htmlCode[character]); + } + else { + // Improvement posted by Joachim Eyrich + buffer.append("&#").append((int)character).append(";"); + } + } + return buffer.toString().trim(); + } + +/** + * Converts a Color into a HTML representation of this Color. + * + * @param color the Color that has to be converted. + * @return the HTML representation of this Color + */ + + public static String encode(Color color) { + StringBuffer buffer = new StringBuffer("#"); + if (color.getRed() < 16) { + buffer.append('0'); + } + buffer.append(Integer.toString(color.getRed(), 16)); + if (color.getGreen() < 16) { + buffer.append('0'); + } + buffer.append(Integer.toString(color.getGreen(), 16)); + if (color.getBlue() < 16) { + buffer.append('0'); + } + buffer.append(Integer.toString(color.getBlue(), 16)); + return buffer.toString(); + } + +/** + * Translates the alignment value. + * + * @param alignment the alignment value + * @return the translated value + */ + + public static String getAlignment(int alignment) { + switch(alignment) { + case Element.ALIGN_LEFT: + return HtmlTags.ALIGN_LEFT; + case Element.ALIGN_CENTER: + return HtmlTags.ALIGN_CENTER; + case Element.ALIGN_RIGHT: + return HtmlTags.ALIGN_RIGHT; + case Element.ALIGN_JUSTIFIED: + case Element.ALIGN_JUSTIFIED_ALL: + return HtmlTags.ALIGN_JUSTIFIED; + case Element.ALIGN_TOP: + return HtmlTags.ALIGN_TOP; + case Element.ALIGN_MIDDLE: + return HtmlTags.ALIGN_MIDDLE; + case Element.ALIGN_BOTTOM: + return HtmlTags.ALIGN_BOTTOM; + case Element.ALIGN_BASELINE: + return HtmlTags.ALIGN_BASELINE; + default: + return ""; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/html/HtmlParser.java b/src/main/java/com/lowagie/text/html/HtmlParser.java new file mode 100644 index 0000000..ba46998 --- /dev/null +++ b/src/main/java/com/lowagie/text/html/HtmlParser.java @@ -0,0 +1,206 @@ +/* + * $Id: HtmlParser.java,v 1.12 2005/11/29 16:00:10 blowagie Exp $ + * $Name: $ + * + * Copyright 2001, 2002 by Bruno Lowagie. + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import com.lowagie.text.DocumentException; +import com.lowagie.text.ExceptionConverter; +import com.lowagie.text.DocListener; +import com.lowagie.text.xml.XmlParser; + +/** + * This class can be used to parse some HTML files. + */ + +public class HtmlParser extends XmlParser { + +/** + * Constructs an HtmlParser. + */ + + public HtmlParser() { + super(); + } + +/** + * Parses a given file. + * @param document the document the parser will write to + * @param is the InputSource with the content + */ + + public void go(DocListener document, InputSource is) { + try { + parser.parse(is, new SAXmyHtmlHandler(document)); + } + catch(SAXException se) { + throw new ExceptionConverter(se); + } + catch(IOException ioe) { + throw new ExceptionConverter(ioe); + } + catch(DocumentException de) { + throw new ExceptionConverter(de); + } + } + +/** + * Parses a given file that validates with the iText DTD and writes the content to a document. + * @param document the document the parser will write to + * @param is the InputSource with the content + */ + + public static void parse(DocListener document, InputSource is) { + HtmlParser p = new HtmlParser(); + p.go(document, is); + } + +/** + * Parses a given file. + * @param document the document the parser will write to + * @param file the file with the content + */ + + public void go(DocListener document, String file) { + try { + parser.parse(file, new SAXmyHtmlHandler(document)); + } + catch(SAXException se) { + throw new ExceptionConverter(se); + } + catch(IOException ioe) { + throw new ExceptionConverter(ioe); + } + catch(DocumentException de) { + throw new ExceptionConverter(de); + } + } + +/** + * Parses a given file that validates with the iText DTD and writes the content to a document. + * @param document the document the parser will write to + * @param file the file with the content + */ + + public static void parse(DocListener document, String file) { + HtmlParser p = new HtmlParser(); + p.go(document, file); + } + +/** + * Parses a given file. + * @param document the document the parser will write to + * @param is the InputStream with the content + */ + + public void go(DocListener document, InputStream is) { + try { + parser.parse(new InputSource(is), new SAXmyHtmlHandler(document)); + } + catch(SAXException se) { + throw new ExceptionConverter(se); + } + catch(IOException ioe) { + throw new ExceptionConverter(ioe); + } + catch(DocumentException de) { + throw new ExceptionConverter(de); + } + } + +/** + * Parses a given file that validates with the iText DTD and writes the content to a document. + * @param document the document the parser will write to + * @param is the InputStream with the content + */ + + public static void parse(DocListener document, InputStream is) { + HtmlParser p = new HtmlParser(); + p.go(document, new InputSource(is)); + } + +/** + * Parses a given file. + * @param document the document the parser will write to + * @param is the Reader with the content + */ + + public void go(DocListener document, Reader is) { + try { + parser.parse(new InputSource(is), new SAXmyHtmlHandler(document)); + } + catch(SAXException se) { + throw new ExceptionConverter(se); + } + catch(IOException ioe) { + throw new ExceptionConverter(ioe); + } + catch(DocumentException de) { + throw new ExceptionConverter(de); + } + } + +/** + * Parses a given file that validates with the iText DTD and writes the content to a document. + * @param document the document the parser will write to + * @param is the Reader with the content + */ + + public static void parse(DocListener document, Reader is) { + HtmlParser p = new HtmlParser(); + p.go(document, new InputSource(is)); + } +} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/html/HtmlPeer.java b/src/main/java/com/lowagie/text/html/HtmlPeer.java new file mode 100644 index 0000000..44a7a25 --- /dev/null +++ b/src/main/java/com/lowagie/text/html/HtmlPeer.java @@ -0,0 +1,112 @@ +/* + * $Id: HtmlPeer.java,v 1.9 2006/03/23 09:51:50 blowagie Exp $ + * $Name: $ + * + * Copyright 2001, 2002 by Bruno Lowagie. + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html; + +import java.util.Properties; + +import org.xml.sax.Attributes; + +import com.lowagie.text.ElementTags; +import com.lowagie.text.xml.XmlPeer; + +/** + * This interface is implemented by the peer of all the iText objects. + */ + +public class HtmlPeer extends XmlPeer { + + /** + * Creates a XmlPeer. + * + * @param name + * the iText name of the tag + * @param alias + * the Html name of the tag + */ + + public HtmlPeer(String name, String alias) { + super(name, alias.toLowerCase()); + } + + /** + * Sets an alias for an attribute. + * + * @param name + * the iText tagname + * @param alias + * the custom tagname + */ + + public void addAlias(String name, String alias) { + attributeAliases.put(alias.toLowerCase(), name); + } + + /** + * @see com.lowagie.text.xml.XmlPeer#getAttributes(org.xml.sax.Attributes) + */ + public Properties getAttributes(Attributes attrs) { + Properties attributes = new Properties(); + attributes.putAll(attributeValues); + if (defaultContent != null) { + attributes.put(ElementTags.ITEXT, defaultContent); + } + if (attrs != null) { + String attribute, value; + for (int i = 0; i < attrs.getLength(); i++) { + attribute = getName(attrs.getQName(i).toLowerCase()); + value = attrs.getValue(i).toLowerCase(); + attributes.setProperty(attribute, value); + } + } + return attributes; + } +} + diff --git a/src/main/java/com/lowagie/text/html/HtmlTagMap.java b/src/main/java/com/lowagie/text/html/HtmlTagMap.java new file mode 100644 index 0000000..bd7ef81 --- /dev/null +++ b/src/main/java/com/lowagie/text/html/HtmlTagMap.java @@ -0,0 +1,296 @@ +/* + * $Id: HtmlTagMap.java,v 1.15 2005/05/03 14:43:59 blowagie Exp $ + * $Name: $ + * + * Copyright 2001, 2002 by Bruno Lowagie. + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html; + +import java.util.HashMap; + +import com.lowagie.text.ElementTags; +import com.lowagie.text.FontFactory; +import com.lowagie.text.markup.MarkupTags; + +/** + * The Tags-class maps several XHTML-tags to iText-objects. + */ + +public class HtmlTagMap extends HashMap { + +/** + * Constructs an HtmlTagMap. + */ + + public HtmlTagMap() { + super(); + HtmlPeer peer; + + peer = new HtmlPeer(ElementTags.ITEXT, HtmlTags.HTML); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.SPAN); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.CHUNK, HtmlTags.CHUNK); + peer.addAlias(ElementTags.FONT, HtmlTags.FONT); + peer.addAlias(ElementTags.SIZE, HtmlTags.SIZE); + peer.addAlias(ElementTags.COLOR, HtmlTags.COLOR); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.ANCHOR, HtmlTags.ANCHOR); + peer.addAlias(ElementTags.NAME, HtmlTags.NAME); + peer.addAlias(ElementTags.REFERENCE, HtmlTags.REFERENCE); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.PARAGRAPH); + peer.addAlias(ElementTags.ALIGN, HtmlTags.ALIGN); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.DIV); + peer.addAlias(ElementTags.ALIGN, HtmlTags.ALIGN); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[0]); + peer.addValue(ElementTags.SIZE, "20"); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[1]); + peer.addValue(ElementTags.SIZE, "18"); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[2]); + peer.addValue(ElementTags.SIZE, "16"); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[3]); + peer.addValue(ElementTags.SIZE, "14"); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[4]); + peer.addValue(ElementTags.SIZE, "12"); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[5]); + peer.addValue(ElementTags.SIZE, "10"); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.LIST, HtmlTags.ORDEREDLIST); + peer.addValue(ElementTags.NUMBERED, "true"); + peer.addValue(ElementTags.SYMBOLINDENT, "20"); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.LIST, HtmlTags.UNORDEREDLIST); + peer.addValue(ElementTags.NUMBERED, "false"); + peer.addValue(ElementTags.SYMBOLINDENT, "20"); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.LISTITEM, HtmlTags.LISTITEM); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.I); + peer.addValue(ElementTags.STYLE, MarkupTags.CSS_VALUE_ITALIC); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.EM); + peer.addValue(ElementTags.STYLE, MarkupTags.CSS_VALUE_ITALIC); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.B); + peer.addValue(ElementTags.STYLE, MarkupTags.CSS_VALUE_BOLD); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.STRONG); + peer.addValue(ElementTags.STYLE, MarkupTags.CSS_VALUE_BOLD); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.S); + peer.addValue(ElementTags.STYLE, MarkupTags.CSS_VALUE_LINETHROUGH); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.CODE); + peer.addValue(ElementTags.FONT, FontFactory.COURIER); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.VAR); + peer.addValue(ElementTags.FONT, FontFactory.COURIER); + peer.addValue(ElementTags.STYLE, MarkupTags.CSS_VALUE_ITALIC); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.U); + peer.addValue(ElementTags.STYLE, MarkupTags.CSS_VALUE_UNDERLINE); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.CHUNK, HtmlTags.SUP); + peer.addValue(ElementTags.SUBSUPSCRIPT, "6.0"); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.CHUNK, HtmlTags.SUB); + peer.addValue(ElementTags.SUBSUPSCRIPT, "-6.0"); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.HORIZONTALRULE, HtmlTags.HORIZONTALRULE); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.TABLE, HtmlTags.TABLE); + peer.addAlias(ElementTags.WIDTH, HtmlTags.WIDTH); + peer.addAlias(ElementTags.BACKGROUNDCOLOR, HtmlTags.BACKGROUNDCOLOR); + peer.addAlias(ElementTags.BORDERCOLOR, HtmlTags.BORDERCOLOR); + peer.addAlias(ElementTags.COLUMNS, HtmlTags.COLUMNS); + peer.addAlias(ElementTags.CELLPADDING, HtmlTags.CELLPADDING); + peer.addAlias(ElementTags.CELLSPACING, HtmlTags.CELLSPACING); + peer.addAlias(ElementTags.BORDERWIDTH, HtmlTags.BORDERWIDTH); + peer.addAlias(ElementTags.ALIGN, HtmlTags.ALIGN); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.ROW, HtmlTags.ROW); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.CELL, HtmlTags.CELL); + peer.addAlias(ElementTags.WIDTH, HtmlTags.WIDTH); + peer.addAlias(ElementTags.BACKGROUNDCOLOR, HtmlTags.BACKGROUNDCOLOR); + peer.addAlias(ElementTags.BORDERCOLOR, HtmlTags.BORDERCOLOR); + peer.addAlias(ElementTags.COLSPAN, HtmlTags.COLSPAN); + peer.addAlias(ElementTags.ROWSPAN, HtmlTags.ROWSPAN); + peer.addAlias(ElementTags.NOWRAP, HtmlTags.NOWRAP); + peer.addAlias(ElementTags.HORIZONTALALIGN, HtmlTags.HORIZONTALALIGN); + peer.addAlias(ElementTags.VERTICALALIGN, HtmlTags.VERTICALALIGN); + peer.addValue(ElementTags.HEADER, "false"); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.CELL, HtmlTags.HEADERCELL); + peer.addAlias(ElementTags.WIDTH, HtmlTags.WIDTH); + peer.addAlias(ElementTags.BACKGROUNDCOLOR, HtmlTags.BACKGROUNDCOLOR); + peer.addAlias(ElementTags.BORDERCOLOR, HtmlTags.BORDERCOLOR); + peer.addAlias(ElementTags.COLSPAN, HtmlTags.COLSPAN); + peer.addAlias(ElementTags.ROWSPAN, HtmlTags.ROWSPAN); + peer.addAlias(ElementTags.NOWRAP, HtmlTags.NOWRAP); + peer.addAlias(ElementTags.HORIZONTALALIGN, HtmlTags.HORIZONTALALIGN); + peer.addAlias(ElementTags.VERTICALALIGN, HtmlTags.VERTICALALIGN); + peer.addValue(ElementTags.HEADER, "true"); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.IMAGE, HtmlTags.IMAGE); + peer.addAlias(ElementTags.URL, HtmlTags.URL); + peer.addAlias(ElementTags.ALT, HtmlTags.ALT); + peer.addAlias(ElementTags.PLAINWIDTH, HtmlTags.PLAINWIDTH); + peer.addAlias(ElementTags.PLAINHEIGHT, HtmlTags.PLAINHEIGHT); + put(peer.getAlias(), peer); + + peer = new HtmlPeer(ElementTags.NEWLINE, HtmlTags.NEWLINE); + put(peer.getAlias(), peer); + } + +/** + * Checks if this is the root tag. + * @param tag a tagvalue + * @return true if tag is HTML or html + */ + + public boolean isHtml(String tag) { + return HtmlTags.HTML.equalsIgnoreCase(tag); + } + +/** + * Checks if this is the head tag. + * @param tag a tagvalue + * @return true if tag is HEAD or head + */ + + public boolean isHead(String tag) { + return HtmlTags.HEAD.equalsIgnoreCase(tag); + } + +/** + * Checks if this is the meta tag. + * @param tag a tagvalue + * @return true if tag is META or meta + */ + + public boolean isMeta(String tag) { + return HtmlTags.META.equalsIgnoreCase(tag); + } + +/** + * Checks if this is the linl tag. + * @param tag a tagvalue + * @return true if tag is LINK or link + */ + + public boolean isLink(String tag) { + return HtmlTags.LINK.equalsIgnoreCase(tag); + } + +/** + * Checks if this is the title tag. + * @param tag a tagvalue + * @return true if tag is TITLE or title + */ + + public boolean isTitle(String tag) { + return HtmlTags.TITLE.equalsIgnoreCase(tag); + } + +/** + * Checks if this is the root tag. + * @param tag a tagvalue + * @return true if tag is BODY or body + */ + + public boolean isBody(String tag) { + return HtmlTags.BODY.equalsIgnoreCase(tag); + } + +/** + * Checks if this is a special tag. + * @param tag a tagvalue + * @return true if tag is a HTML, HEAD, META, LINK or BODY tag (case insensitive) + */ + public boolean isSpecialTag(String tag) { + return isHtml(tag) || isHead(tag) || isMeta(tag) || isLink(tag) || isBody(tag); + } +} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/html/HtmlTags.java b/src/main/java/com/lowagie/text/html/HtmlTags.java new file mode 100644 index 0000000..43dbcc4 --- /dev/null +++ b/src/main/java/com/lowagie/text/html/HtmlTags.java @@ -0,0 +1,331 @@ +/* + * $Id: HtmlTags.java,v 1.69 2005/05/03 14:43:58 blowagie Exp $ + * $Name: $ + * + * Copyright 2001, 2002 by Bruno Lowagie. + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html; + +/** + * A class that contains all the possible tagnames and their attributes. + */ + +public class HtmlTags { + +/** the root tag. */ + public static final String HTML = "html"; + +/** the head tag */ + public static final String HEAD = "head"; + +/** This is a possible HTML attribute for the HEAD tag. */ + public static final String CONTENT = "content"; + +/** the meta tag */ + public static final String META = "meta"; + +/** attribute of the root tag */ + public static final String SUBJECT = "subject"; + +/** attribute of the root tag */ + public static final String KEYWORDS = "keywords"; + +/** attribute of the root tag */ + public static final String AUTHOR = "author"; + +/** the title tag. */ + public static final String TITLE = "title"; + +/** the script tag. */ + public static final String SCRIPT = "script"; + +/** This is a possible HTML attribute for the SCRIPT tag. */ + public static final String LANGUAGE = "language"; + +/** This is a possible value for the LANGUAGE attribute. */ + public static final String JAVASCRIPT = "JavaScript"; + +/** the body tag. */ + public static final String BODY = "body"; + +/** This is a possible HTML attribute for the BODY tag */ + public static final String JAVASCRIPT_ONLOAD = "onLoad"; + +/** This is a possible HTML attribute for the BODY tag */ + public static final String JAVASCRIPT_ONUNLOAD = "onUnLoad"; + +/** This is a possible HTML attribute for the BODY tag. */ + public static final String TOPMARGIN = "topmargin"; + +/** This is a possible HTML attribute for the BODY tag. */ + public static final String BOTTOMMARGIN = "bottommargin"; + +/** This is a possible HTML attribute for the BODY tag. */ + public static final String LEFTMARGIN = "leftmargin"; + +/** This is a possible HTML attribute for the BODY tag. */ + public static final String RIGHTMARGIN = "rightmargin"; + + // Phrases, Anchors, Lists and Paragraphs + +/** the chunk tag */ + public static final String CHUNK = "font"; + +/** the phrase tag */ + public static final String CODE = "code"; + +/** the phrase tag */ + public static final String VAR = "var"; + +/** the anchor tag */ + public static final String ANCHOR = "a"; + +/** the list tag */ + public static final String ORDEREDLIST = "ol"; + +/** the list tag */ + public static final String UNORDEREDLIST = "ul"; + +/** the listitem tag */ + public static final String LISTITEM = "li"; + +/** the paragraph tag */ + public static final String PARAGRAPH = "p"; + +/** attribute of anchor tag */ + public static final String NAME = "name"; + +/** attribute of anchor tag */ + public static final String REFERENCE = "href"; + +/** attribute of anchor tag */ + public static final String[] H = new String[6]; + static { + H[0] = "h1"; + H[1] = "h2"; + H[2] = "h3"; + H[3] = "h4"; + H[4] = "h5"; + H[5] = "h6"; + } + + // Chunks + +/** attribute of the chunk tag */ + public static final String FONT = "face"; + +/** attribute of the chunk tag */ + public static final String SIZE = "point-size"; + +/** attribute of the chunk/table/cell tag */ + public static final String COLOR = "color"; + +/** some phrase tag */ + public static final String EM = "em"; + +/** some phrase tag */ + public static final String I = "i"; + +/** some phrase tag */ + public static final String STRONG = "strong"; + +/** some phrase tag */ + public static final String B = "b"; + +/** some phrase tag */ + public static final String S = "s"; + +/** some phrase tag */ + public static final String U = "u"; + +/** some phrase tag */ + public static final String SUB = "sub"; + +/** some phrase tag */ + public static final String SUP = "sup"; + +/** the possible value of a tag */ + public static final String HORIZONTALRULE = "hr"; + + // tables/cells + +/** the table tag */ + public static final String TABLE = "table"; + +/** the cell tag */ + public static final String ROW = "tr"; + +/** the cell tag */ + public static final String CELL = "td"; + +/** attribute of the cell tag */ + public static final String HEADERCELL = "th"; + +/** attribute of the table tag */ + public static final String COLUMNS = "cols"; + +/** attribute of the table tag */ + public static final String CELLPADDING = "cellpadding"; + +/** attribute of the table tag */ + public static final String CELLSPACING = "cellspacing"; + +/** attribute of the cell tag */ + public static final String COLSPAN = "colspan"; + +/** attribute of the cell tag */ + public static final String ROWSPAN = "rowspan"; + +/** attribute of the cell tag */ + public static final String NOWRAP = "nowrap"; + +/** attribute of the table/cell tag */ + public static final String BORDERWIDTH = "border"; + +/** attribute of the table/cell tag */ + public static final String WIDTH = "width"; + +/** attribute of the table/cell tag */ + public static final String BACKGROUNDCOLOR = "bgcolor"; + +/** attribute of the table/cell tag */ + public static final String BORDERCOLOR = "bordercolor"; + +/** attribute of paragraph/image/table tag */ + public static final String ALIGN = "align"; + +/** attribute of chapter/section/paragraph/table/cell tag */ + public static final String LEFT = "left"; + +/** attribute of chapter/section/paragraph/table/cell tag */ + public static final String RIGHT = "right"; + +/** attribute of the cell tag */ + public static final String HORIZONTALALIGN = "align"; + +/** attribute of the cell tag */ + public static final String VERTICALALIGN = "valign"; + +/** attribute of the table/cell tag */ + public static final String TOP = "top"; + +/** attribute of the table/cell tag */ + public static final String BOTTOM = "bottom"; + + // Misc + +/** the image tag */ + public static final String IMAGE = "img"; + +/** attribute of the image tag */ + public static final String URL = "src"; + +/** attribute of the image tag */ + public static final String ALT = "alt"; + +/** attribute of the image tag */ + public static final String PLAINWIDTH = "width"; + +/** attribute of the image tag */ + public static final String PLAINHEIGHT = "height"; + +/** the newpage tag */ + public static final String NEWLINE = "br"; + + // alignment attribute values + +/** the possible value of an alignment attribute */ + public static final String ALIGN_LEFT = "Left"; + +/** the possible value of an alignment attribute */ + public static final String ALIGN_CENTER = "Center"; + +/** the possible value of an alignment attribute */ + public static final String ALIGN_RIGHT = "Right"; + +/** the possible value of an alignment attribute */ + public static final String ALIGN_JUSTIFIED = "Justify"; + +/** the possible value of an alignment attribute */ + public static final String ALIGN_TOP = "Top"; + +/** the possible value of an alignment attribute */ + public static final String ALIGN_MIDDLE = "Middle"; + +/** the possible value of an alignment attribute */ + public static final String ALIGN_BOTTOM = "Bottom"; + +/** the possible value of an alignment attribute */ + public static final String ALIGN_BASELINE = "Baseline"; + +/** the possible value of an alignment attribute */ + public static final String DEFAULT = "Default"; + + /** The DIV tag. */ + public static final String DIV = "div"; + + /** The SPAN tag. */ + public static final String SPAN = "span"; + /** The LINK tag. */ + public static final String LINK = "link"; + + /** This is a possible HTML attribute for the LINK tag. */ + public static final String TEXT_CSS = "text/css"; + + /** This is a possible HTML attribute for the LINK tag. */ + public static final String REL = "rel"; + + /** This is used for inline css style information */ + public static final String STYLE = "style"; + + /** This is a possible HTML attribute for the LINK tag. */ + public static final String TYPE = "type"; + + /** This is a possible HTML attribute. */ + public static final String STYLESHEET = "stylesheet"; + +} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/html/HtmlWriter.java b/src/main/java/com/lowagie/text/html/HtmlWriter.java new file mode 100644 index 0000000..69ce91c --- /dev/null +++ b/src/main/java/com/lowagie/text/html/HtmlWriter.java @@ -0,0 +1,1094 @@ +/* + * $Id: HtmlWriter.java,v 1.109 2005/11/01 12:27:05 psoares33 Exp $ + * $Name: $ + * + * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU LIBRARY GENERAL PUBLIC LICENSE for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html; + +import java.io.OutputStream; +import java.io.IOException; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Properties; +import java.util.Stack; +import java.util.EmptyStackException; + +import com.lowagie.text.*; +import com.lowagie.text.markup.MarkupTags; + +/** + * A DocWriter class for HTML. + *

+ * An HtmlWriter can be added as a DocListener + * to a certain Document by getting an instance. + * Every Element added to the original Document + * will be written to the OutputStream of this HtmlWriter. + *

+ * Example: + *

+ * // creation of the document with a certain size and certain margins
+ * Document document = new Document(PageSize.A4, 50, 50, 50, 50);
+ * try {
+ *    // this will write HTML to the Standard OutputStream
+ *    HtmlWriter.getInstance(document, System.out);
+ *    // this will write HTML to a file called text.html
+ *    HtmlWriter.getInstance(document, new FileOutputStream("text.html"));
+ *    // this will write HTML to for instance the OutputStream of a HttpServletResponse-object
+ *    HtmlWriter.getInstance(document, response.getOutputStream());
+ * }
+ * catch(DocumentException de) {
+ *    System.err.println(de.getMessage());
+ * }
+ * // this will close the document and all the OutputStreams listening to it
+ * document.close();
+ * 
+ */ + +public class HtmlWriter extends DocWriter implements DocListener { + + // static membervariables (tags) + +/** This is a possible HTML-tag. */ + public static final byte[] BEGINCOMMENT = getISOBytes(""); + +/** This is a possible HTML-tag. */ + public static final String NBSP = " "; + + // membervariables + +/** This is the current font of the HTML. */ + protected Stack currentfont = new Stack(); + +/** This is the standard font of the HTML. */ + protected Font standardfont = new Font(); + +/** This is a path for images. */ + protected String imagepath = null; + +/** Stores the page number. */ + protected int pageN = 0; + +/** This is the textual part of a header */ + protected HeaderFooter header = null; + +/** This is the textual part of the footer */ + protected HeaderFooter footer = null; + + // constructor + +/** + * Constructs a HtmlWriter. + * + * @param doc The Document that has to be written as HTML + * @param os The OutputStream the writer has to write to. + */ + + protected HtmlWriter(Document doc, OutputStream os) { + super(doc, os); + + document.addDocListener(this); + this.pageN = document.getPageNumber(); + try { + os.write(LT); + os.write(getISOBytes(HtmlTags.HTML)); + os.write(GT); + os.write(NEWLINE); + os.write(TAB); + os.write(LT); + os.write(getISOBytes(HtmlTags.HEAD)); + os.write(GT); + } + catch(IOException ioe) { + throw new ExceptionConverter(ioe); + } + } + + // get an instance of the HtmlWriter + +/** + * Gets an instance of the HtmlWriter. + * + * @param document The Document that has to be written + * @param os The OutputStream the writer has to write to. + * @return a new HtmlWriter + */ + + public static HtmlWriter getInstance(Document document, OutputStream os) { + return new HtmlWriter(document, os); + } + + // implementation of the DocListener methods + +/** + * Signals that an new page has to be started. + * + * @return true if this action succeeded, false if not. + * @throws DocumentException when a document isn't open yet, or has been closed + */ + + public boolean newPage() throws DocumentException { + try { + writeStart(HtmlTags.DIV); + write(" "); + write(HtmlTags.STYLE); + write("=\""); + writeCssProperty(MarkupTags.CSS_KEY_PAGE_BREAK_BEFORE, MarkupTags.CSS_VALUE_ALWAYS); + write("\" /"); + os.write(GT); + } + catch(IOException ioe) { + throw new DocumentException(ioe); + } + return true; + } + +/** + * Signals that an Element was added to the Document. + * + * @param element a high level object that has to be translated to HTML + * @return true if the element was added, false if not. + * @throws DocumentException when a document isn't open yet, or has been closed + */ + + public boolean add(Element element) throws DocumentException { + if (pause) { + return false; + } + try { + + switch(element.type()) { + case Element.HEADER: + try { + Header h = (Header) element; + if (HtmlTags.STYLESHEET.equals(h.name())) { + writeLink(h); + } + else if (HtmlTags.JAVASCRIPT.equals(h.name())) { + writeJavaScript(h); + } + else { + writeHeader(h); + } + } + catch(ClassCastException cce) { + } + return true; + case Element.SUBJECT: + case Element.KEYWORDS: + case Element.AUTHOR: + Meta meta = (Meta) element; + writeHeader(meta); + return true; + case Element.TITLE: + addTabs(2); + writeStart(HtmlTags.TITLE); + os.write(GT); + addTabs(3); + write(HtmlEncoder.encode(((Meta)element).content())); + addTabs(2); + writeEnd(HtmlTags.TITLE); + return true; + case Element.CREATOR: + writeComment("Creator: " + HtmlEncoder.encode(((Meta)element).content())); + return true; + case Element.PRODUCER: + writeComment("Producer: " + HtmlEncoder.encode(((Meta)element).content())); + return true; + case Element.CREATIONDATE: + writeComment("Creationdate: " + HtmlEncoder.encode(((Meta)element).content())); + return true; + default: + write(element, 2); + return true; + } + } + catch(IOException ioe) { + throw new ExceptionConverter(ioe); + } + } + +/** + * Signals that the Document has been opened and that + * Elements can be added. + *

+ * The HEAD-section of the HTML-document is written. + */ + + public void open() { + super.open(); + try { + writeComment(Document.getVersion()); + writeComment("CreationDate: " + new Date().toString()); + addTabs(1); + writeEnd(HtmlTags.HEAD); + addTabs(1); + writeStart(HtmlTags.BODY); + if (document.leftMargin() > 0) { + write(HtmlTags.LEFTMARGIN, String.valueOf(document.leftMargin())); + } + if (document.rightMargin() > 0) { + write(HtmlTags.RIGHTMARGIN, String.valueOf(document.rightMargin())); + } + if (document.topMargin() > 0) { + write(HtmlTags.TOPMARGIN, String.valueOf(document.topMargin())); + } + if (document.bottomMargin() > 0) { + write(HtmlTags.BOTTOMMARGIN, String.valueOf(document.bottomMargin())); + } + if (pageSize.backgroundColor() != null) { + write(HtmlTags.BACKGROUNDCOLOR, HtmlEncoder.encode(pageSize.backgroundColor())); + } + if (document.getJavaScript_onLoad() != null) { + write(HtmlTags.JAVASCRIPT_ONLOAD, HtmlEncoder.encode(document.getJavaScript_onLoad())); + } + if (document.getJavaScript_onUnLoad() != null) { + write(HtmlTags.JAVASCRIPT_ONUNLOAD, HtmlEncoder.encode(document.getJavaScript_onUnLoad())); + } + if (document.getHtmlStyleClass() != null) { + write(MarkupTags.HTML_ATTR_CSS_CLASS, document.getHtmlStyleClass()); + } + os.write(GT); + initHeader(); // line added by David Freels + } + catch(IOException ioe) { + throw new ExceptionConverter(ioe); + } + } + +/** + * Signals that the Document was closed and that no other + * Elements will be added. + */ + + public void close() { + try { + initFooter(); // line added by David Freels + addTabs(1); + writeEnd(HtmlTags.BODY); + os.write(NEWLINE); + writeEnd(HtmlTags.HTML); + super.close(); + } + catch(IOException ioe) { + throw new ExceptionConverter(ioe); + } + } + + // some protected methods + +/** + * Adds the header to the top of the Document + */ + + protected void initHeader() { + if (header != null) { + try { + add(header.paragraph()); + } + catch(Exception e) { + throw new ExceptionConverter(e); + } + } + } + +/** + * Adds the header to the top of the Document + */ + + protected void initFooter() { + if (footer != null) { + try { + // Set the page number. HTML has no notion of a page, so it should always + // add up to 1 + footer.setPageNumber(pageN + 1); + add(footer.paragraph()); + } + catch(Exception e) { + throw new ExceptionConverter(e); + } + } + } + +/** + * Writes a Metatag in the header. + * + * @param meta the element that has to be written + * @throws IOException + */ + + protected void writeHeader(Meta meta) throws IOException { + addTabs(2); + writeStart(HtmlTags.META); + switch(meta.type()) { + case Element.HEADER: + write(HtmlTags.NAME, ((Header) meta).name()); + break; + case Element.SUBJECT: + write(HtmlTags.NAME, HtmlTags.SUBJECT); + break; + case Element.KEYWORDS: + write(HtmlTags.NAME, HtmlTags.KEYWORDS); + break; + case Element.AUTHOR: + write(HtmlTags.NAME, HtmlTags.AUTHOR); + break; + } + write(HtmlTags.CONTENT, HtmlEncoder.encode(meta.content())); + writeEnd(); + } + +/** + * Writes a link in the header. + * + * @param header the element that has to be written + * @throws IOException + */ + + protected void writeLink(Header header) throws IOException { + addTabs(2); + writeStart(HtmlTags.LINK); + write(HtmlTags.REL, header.name()); + write(HtmlTags.TYPE, HtmlTags.TEXT_CSS); + write(HtmlTags.REFERENCE, header.content()); + writeEnd(); + } + +/** + * Writes a JavaScript section or, if the markup attribute HtmlTags.URL is set, a JavaScript reference in the header. + * + * @param header the element that has to be written + * @throws IOException + */ + + protected void writeJavaScript(Header header) throws IOException { + addTabs(2); + writeStart(HtmlTags.SCRIPT); + write(HtmlTags.LANGUAGE, HtmlTags.JAVASCRIPT); + if (header.getMarkupAttribute(HtmlTags.URL) != null) { + /* JavaScript reference example: + * + * + */ + write(HtmlTags.TYPE, MarkupTags.HTML_VALUE_JAVASCRIPT); + os.write(GT); + addTabs(2); + write(new String(BEGINCOMMENT) + "\n"); + write(header.content()); + addTabs(2); + write("//" + new String(ENDCOMMENT)); + addTabs(2); + writeEnd(HtmlTags.SCRIPT); + } + } + +/** + * Writes some comment. + *

+ * This method writes some comment. + * + * @param comment the comment that has to be written + * @throws IOException + */ + + protected void writeComment(String comment) throws IOException { + addTabs(2); + os.write(BEGINCOMMENT); + write(comment); + os.write(ENDCOMMENT); + } + + // public methods + +/** + * Changes the standardfont. + * + * @param standardfont The font + */ + + public void setStandardFont(Font standardfont) { + this.standardfont = standardfont; + } + +/** + * Checks if a given font is the same as the font that was last used. + * + * @param font the font of an object + * @return true if the font differs + */ + + public boolean isOtherFont(Font font) { + try { + Font cFont = (Font) currentfont.peek(); + if (cFont.compareTo(font) == 0) return false; + return true; + } + catch(EmptyStackException ese) { + if (standardfont.compareTo(font) == 0) return false; + return true; + } + } + +/** + * Sets the basepath for images. + *

+ * This is especially useful if you add images using a file, + * rather than an URL. In PDF there is no problem, since + * the images are added inline, but in HTML it is sometimes + * necessary to use a relative path or a special path to some + * images directory. + * + * @param imagepath the new imagepath + */ + + public void setImagepath(String imagepath) { + this.imagepath = imagepath; + } + +/** + * Resets the imagepath. + */ + + public void resetImagepath() { + imagepath = null; + } + +/** + * Changes the header of this document. + * + * @param header the new header + */ + + public void setHeader(HeaderFooter header) { + this.header = header; + } + +/** + * Changes the footer of this document. + * + * @param footer the new footer + */ + + public void setFooter(HeaderFooter footer) { + this.footer = footer; + } + +/** + * Signals that a String was added to the Document. + * + * @param string a String to add to the HTML + * @return true if the string was added, false if not. + * @throws DocumentException when a document isn't open yet, or has been closed + */ + + public boolean add(String string) throws DocumentException{ + if (pause) { + return false; + } + try + { + write(string); + return true; + } + catch(IOException ioe) { + throw new ExceptionConverter(ioe); + } + } + +/** + * Writes the HTML representation of an element. + * + * @param element the element + * @param indent the indentation + * @throws IOException + */ + + protected void write(Element element, int indent) throws IOException { + Properties styleAttributes = null; + switch(element.type()) { + case Element.CHUNK: + { + Chunk chunk = (Chunk) element; + // if the chunk contains an image, return the image representation + Image image = chunk.getImage(); + if (image != null) { + write(image, indent); + return; + } + + if (chunk.isEmpty()) return; + HashMap attributes = chunk.getAttributes(); + if (attributes != null && attributes.get(Chunk.NEWPAGE) != null) { + return; + } + // This doesn't seem to work: + //if (attributes != null && attributes.get(Chunk.SUBSUPSCRIPT) != null) { + // float p = (((Float)attributes.get(Chunk.SUBSUPSCRIPT)).floatValue() * 100f) / chunk.font().size(); + // styleAttributes = new Properties(); + // styleAttributes.setProperty(MarkupTags.CSS_VERTICALALIGN, "" + p + "%"); + //} + boolean tag = isOtherFont(chunk.font()) || hasMarkupAttributes(chunk) || styleAttributes != null; + if (tag) { + // start span tag + addTabs(indent); + writeStart(HtmlTags.SPAN); + if (isOtherFont(chunk.font())) { + write(chunk.font(), styleAttributes); + } + if (hasMarkupAttributes(chunk)) { + writeMarkupAttributes(chunk); + } + os.write(GT); + } + if (attributes != null && attributes.get(Chunk.SUBSUPSCRIPT) != null) { + // start sup or sub tag + if (((Float)attributes.get(Chunk.SUBSUPSCRIPT)).floatValue() > 0) { + writeStart(HtmlTags.SUP); + } + else { + writeStart(HtmlTags.SUB); + } + os.write(GT); + } + // contents + write(HtmlEncoder.encode(chunk.content())); + if (attributes != null && attributes.get(Chunk.SUBSUPSCRIPT) != null) { + // end sup or sub tag + os.write(LT); + os.write(FORWARD); + if (((Float)attributes.get(Chunk.SUBSUPSCRIPT)).floatValue() > 0) { + write(HtmlTags.SUP); + } + else { + write(HtmlTags.SUB); + } + os.write(GT); + } + if (tag) { + // end tag + writeEnd(MarkupTags.HTML_TAG_SPAN); + } + return; + } + case Element.PHRASE: + { + Phrase phrase = (Phrase) element; + styleAttributes = new Properties(); + if (phrase.leadingDefined()) styleAttributes.setProperty(MarkupTags.CSS_KEY_LINEHEIGHT, String.valueOf(phrase.leading()) + "pt"); + + // start tag + addTabs(indent); + writeStart(MarkupTags.HTML_TAG_SPAN); + if (hasMarkupAttributes(phrase)) { + writeMarkupAttributes(phrase); + } + write(phrase.font(), styleAttributes); + os.write(GT); + currentfont.push(phrase.font()); + // contents + for (Iterator i = phrase.iterator(); i.hasNext(); ) { + write((Element) i.next(), indent + 1); + } + // end tag + addTabs(indent); + writeEnd(MarkupTags.HTML_TAG_SPAN); + currentfont.pop(); + return; + } + case Element.ANCHOR: + { + Anchor anchor = (Anchor) element; + styleAttributes = new Properties(); + if (anchor.leadingDefined()) styleAttributes.setProperty(MarkupTags.CSS_KEY_LINEHEIGHT, String.valueOf(anchor.leading()) + "pt"); + + // start tag + addTabs(indent); + writeStart(HtmlTags.ANCHOR); + if (anchor.name() != null) { + write(HtmlTags.NAME, anchor.name()); + } + if (anchor.reference() != null) { + write(HtmlTags.REFERENCE, anchor.reference()); + } + if (hasMarkupAttributes(anchor)) { + writeMarkupAttributes(anchor); + } + write(anchor.font(), styleAttributes); + os.write(GT); + currentfont.push(anchor.font()); + // contents + for (Iterator i = anchor.iterator(); i.hasNext(); ) { + write((Element) i.next(), indent + 1); + } + // end tag + addTabs(indent); + writeEnd(HtmlTags.ANCHOR); + currentfont.pop(); + return; + } + case Element.PARAGRAPH: + { + Paragraph paragraph = (Paragraph) element; + styleAttributes = new Properties(); + if (paragraph.leadingDefined()) styleAttributes.setProperty(MarkupTags.CSS_KEY_LINEHEIGHT, String.valueOf(paragraph.leading()) + "pt"); + // start tag + addTabs(indent); + writeStart(HtmlTags.DIV); + if (hasMarkupAttributes(paragraph)) { + writeMarkupAttributes(paragraph); + } + String alignment = HtmlEncoder.getAlignment(paragraph.alignment()); + if (!"".equals(alignment)) { + write(HtmlTags.ALIGN, alignment); + } + write(paragraph.font(), styleAttributes); + os.write(GT); + currentfont.push(paragraph.font()); + // contents + for (Iterator i = paragraph.iterator(); i.hasNext(); ) { + write((Element) i.next(), indent + 1); + } + // end tag + addTabs(indent); + writeEnd(HtmlTags.DIV); + currentfont.pop(); + return; + } + case Element.SECTION: + case Element.CHAPTER: + { + // part of the start tag + contents + writeSection((Section) element, indent); + return; + } + case Element.LIST: + { + List list = (List) element; + // start tag + addTabs(indent); + if (list.isNumbered()) { + writeStart(HtmlTags.ORDEREDLIST); + } + else { + writeStart(HtmlTags.UNORDEREDLIST); + } + if (hasMarkupAttributes(list)) { + writeMarkupAttributes(list); + } + os.write(GT); + // contents + for (Iterator i = list.getItems().iterator(); i.hasNext(); ) { + write((Element) i.next(), indent + 1); + } + // end tag + addTabs(indent); + if (list.isNumbered()) { + writeEnd(HtmlTags.ORDEREDLIST); + } + else { + writeEnd(HtmlTags.UNORDEREDLIST); + } + return; + } + case Element.LISTITEM: + { + ListItem listItem = (ListItem) element; + styleAttributes = new Properties(); + if (listItem.leadingDefined()) styleAttributes.setProperty(MarkupTags.CSS_KEY_LINEHEIGHT, String.valueOf(listItem.leading()) + "pt"); + + // start tag + addTabs(indent); + writeStart(HtmlTags.LISTITEM); + if (hasMarkupAttributes(listItem)) { + writeMarkupAttributes(listItem); + } + write(listItem.font(), styleAttributes); + os.write(GT); + currentfont.push(listItem.font()); + // contents + for (Iterator i = listItem.iterator(); i.hasNext(); ) { + write((Element) i.next(), indent + 1); + } + // end tag + addTabs(indent); + writeEnd(HtmlTags.LISTITEM); + currentfont.pop(); + return; + } + case Element.CELL: + { + Cell cell = (Cell) element; + + // start tag + addTabs(indent); + if (cell.header()) { + writeStart(HtmlTags.HEADERCELL); + } + else { + writeStart(HtmlTags.CELL); + } + if (hasMarkupAttributes(cell)) { + writeMarkupAttributes(cell); + } + if (cell.borderWidth() != Rectangle.UNDEFINED) { + write(HtmlTags.BORDERWIDTH, String.valueOf(cell.borderWidth())); + } + if (cell.borderColor() != null) { + write(HtmlTags.BORDERCOLOR, HtmlEncoder.encode(cell.borderColor())); + } + if (cell.backgroundColor() != null) { + write(HtmlTags.BACKGROUNDCOLOR, HtmlEncoder.encode(cell.backgroundColor())); + } + String alignment = HtmlEncoder.getAlignment(cell.horizontalAlignment()); + if (!"".equals(alignment)) { + write(HtmlTags.HORIZONTALALIGN, alignment); + } + alignment = HtmlEncoder.getAlignment(cell.verticalAlignment()); + if (!"".equals(alignment)) { + write(HtmlTags.VERTICALALIGN, alignment); + } + if (cell.cellWidth() != null) { + write(HtmlTags.WIDTH, cell.cellWidth()); + } + if (cell.colspan() != 1) { + write(HtmlTags.COLSPAN, String.valueOf(cell.colspan())); + } + if (cell.rowspan() != 1) { + write(HtmlTags.ROWSPAN, String.valueOf(cell.rowspan())); + } + if (cell.noWrap()) { + write(HtmlTags.NOWRAP, String.valueOf(true)); + } + os.write(GT); + // contents + if (cell.isEmpty()) { + write(NBSP); + } else { + for (Iterator i = cell.getElements(); i.hasNext(); ) { + write((Element) i.next(), indent + 1); + } + } + // end tag + addTabs(indent); + if (cell.header()) { + writeEnd(HtmlTags.HEADERCELL); + } + else { + writeEnd(HtmlTags.CELL); + } + return; + } + case Element.ROW: + { + Row row = (Row) element; + + // start tag + addTabs(indent); + writeStart(HtmlTags.ROW); + if (hasMarkupAttributes(row)) { + writeMarkupAttributes(row); + } + os.write(GT); + // contents + Element cell; + for (int i = 0; i < row.columns(); i++) { + if ((cell = (Element)row.getCell(i)) != null) { + write(cell, indent + 1); + } + } + // end tag + addTabs(indent); + writeEnd(HtmlTags.ROW); + return; + } + case Element.TABLE: + { + Table table; + try { + table = (Table) element; + } + catch(ClassCastException cce) { + try { + table = ((SimpleTable)element).createTable(); + } catch (BadElementException e) { + throw new ExceptionConverter(e); + } + } + table.complete(); + // start tag + addTabs(indent); + writeStart(HtmlTags.TABLE); + if (hasMarkupAttributes(table)) { + writeMarkupAttributes(table); + } + os.write(SPACE); + write(HtmlTags.WIDTH); + os.write(EQUALS); + os.write(QUOTE); + if (! "".equals(table.absWidth())){ + write(table.absWidth()); + } + else{ + write(String.valueOf(table.widthPercentage())); + write("%"); + } + os.write(QUOTE); + String alignment = HtmlEncoder.getAlignment(table.alignment()); + if (!"".equals(alignment)) { + write(HtmlTags.ALIGN, alignment); + } + write(HtmlTags.CELLPADDING, String.valueOf(table.cellpadding())); + write(HtmlTags.CELLSPACING, String.valueOf(table.cellspacing())); + if (table.borderWidth() != Rectangle.UNDEFINED) { + write(HtmlTags.BORDERWIDTH, String.valueOf(table.borderWidth())); + } + if (table.borderColor() != null) { + write(HtmlTags.BORDERCOLOR, HtmlEncoder.encode(table.borderColor())); + } + if (table.backgroundColor() != null) { + write(HtmlTags.BACKGROUNDCOLOR, HtmlEncoder.encode(table.backgroundColor())); + } + os.write(GT); + // contents + Row row; + for (Iterator iterator = table.iterator(); iterator.hasNext(); ) { + row = (Row) iterator.next(); + write(row, indent + 1); + } + // end tag + addTabs(indent); + writeEnd(HtmlTags.TABLE); + return; + } + case Element.ANNOTATION: + { + Annotation annotation = (Annotation) element; + writeComment(annotation.title() + ": " + annotation.content()); + if (hasMarkupAttributes(annotation)) { + os.write(BEGINCOMMENT); + writeMarkupAttributes(annotation); + os.write(ENDCOMMENT); + } + return; + } + case Element.IMGRAW: + case Element.JPEG: + case Element.IMGTEMPLATE: + { + Image image = (Image) element; + if (image.url() == null) { + return; + } + + // start tag + addTabs(indent); + writeStart(HtmlTags.IMAGE); + String path = image.url().toString(); + if (imagepath != null) { + if (path.indexOf("/") > 0) { + path = imagepath + path.substring(path.lastIndexOf("/") + 1); + } + else { + path = imagepath + path; + } + } + write(HtmlTags.URL, path); + if ((image.alignment() & Image.LEFT) > 0) { + write(HtmlTags.ALIGN, HtmlTags.ALIGN_LEFT); + } + else if ((image.alignment() & Image.RIGHT) > 0) { + write(HtmlTags.ALIGN, HtmlTags.ALIGN_RIGHT); + } + else if ((image.alignment() & Image.MIDDLE) > 0) { + write(HtmlTags.ALIGN, HtmlTags.ALIGN_MIDDLE); + } + if (image.alt() != null) { + write(HtmlTags.ALT, image.alt()); + } + write(HtmlTags.PLAINWIDTH, String.valueOf(image.scaledWidth())); + write(HtmlTags.PLAINHEIGHT, String.valueOf(image.scaledHeight())); + if (hasMarkupAttributes(image)){ + writeMarkupAttributes(image); + } + writeEnd(); + return; + } + + default: + return; + } + } + +/** + * Writes the HTML representation of a section. + * + * @param section the section to write + * @param indent the indentation + * @throws IOException + */ + + protected void writeSection(Section section, int indent) throws IOException { + if (section.title() != null) { + int depth = section.depth() - 1; + if (depth > 5) { + depth = 5; + } + Properties styleAttributes = new Properties(); + if (section.title().leadingDefined()) styleAttributes.setProperty(MarkupTags.CSS_KEY_LINEHEIGHT, String.valueOf(section.title().leading()) + "pt"); + // start tag + addTabs(indent); + writeStart(HtmlTags.H[depth]); + write(section.title().font(), styleAttributes); + String alignment = HtmlEncoder.getAlignment(section.title().alignment()); + if (!"".equals(alignment)) { + write(HtmlTags.ALIGN, alignment); + } + if (hasMarkupAttributes(section.title())) { + writeMarkupAttributes(section.title()); + } + os.write(GT); + currentfont.push(section.title().font()); + // contents + for (Iterator i = section.title().iterator(); i.hasNext(); ) { + write((Element)i.next(), indent + 1); + } + // end tag + addTabs(indent); + writeEnd(HtmlTags.H[depth]); + currentfont.pop(); + } + for (Iterator i = section.iterator(); i.hasNext(); ) { + write((Element) i.next(), indent); + } + } + + /** + * Writes the representation of a Font. + * + * @param font a Font + * @param styleAttributes the style of the font + * @throws IOException + */ + + protected void write(Font font, Properties styleAttributes) throws IOException { + if (font == null || !isOtherFont(font) /* || styleAttributes == null*/) return; + write(" "); + write(HtmlTags.STYLE); + write("=\""); + if (styleAttributes != null) { + String key; + for (Enumeration e = styleAttributes.propertyNames(); e.hasMoreElements(); ) { + key = (String)e.nextElement(); + writeCssProperty(key, styleAttributes.getProperty(key)); + } + } + if (isOtherFont(font)) { + writeCssProperty(MarkupTags.CSS_KEY_FONTFAMILY, font.getFamilyname()); + + if (font.size() != Font.UNDEFINED) { + writeCssProperty(MarkupTags.CSS_KEY_FONTSIZE, String.valueOf(font.size()) + "pt"); + } + if (font.color() != null) { + writeCssProperty(MarkupTags.CSS_KEY_COLOR, HtmlEncoder.encode(font.color())); + } + + int fontstyle = font.style(); + if (fontstyle != Font.UNDEFINED && fontstyle != Font.NORMAL) { + switch (fontstyle & Font.BOLDITALIC) { + case Font.BOLD: + writeCssProperty(MarkupTags.CSS_KEY_FONTWEIGHT, MarkupTags.CSS_VALUE_BOLD); + break; + case Font.ITALIC: + writeCssProperty(MarkupTags.CSS_KEY_FONTSTYLE, MarkupTags.CSS_VALUE_ITALIC); + break; + case Font.BOLDITALIC: + writeCssProperty(MarkupTags.CSS_KEY_FONTWEIGHT, MarkupTags.CSS_VALUE_BOLD); + writeCssProperty(MarkupTags.CSS_KEY_FONTSTYLE, MarkupTags.CSS_VALUE_ITALIC); + break; + } + + // CSS only supports one decoration tag so if both are specified + // only one of the two will display + if ((fontstyle & Font.UNDERLINE) > 0) { + writeCssProperty(MarkupTags.CSS_KEY_TEXTDECORATION, MarkupTags.CSS_VALUE_UNDERLINE); + } + if ((fontstyle & Font.STRIKETHRU) > 0) { + writeCssProperty(MarkupTags.CSS_KEY_TEXTDECORATION, MarkupTags.CSS_VALUE_LINETHROUGH); + } + } + } + write("\""); + } + + /** + * Writes out a CSS property. + * @param prop a CSS property + * @param value the value of the CSS property + * @throws IOException + */ + protected void writeCssProperty(String prop, String value) throws IOException { + write(new StringBuffer(prop).append(": ").append(value).append("; ").toString()); + } +} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/html/SAXmyHtmlHandler.java b/src/main/java/com/lowagie/text/html/SAXmyHtmlHandler.java new file mode 100644 index 0000000..76c2e6a --- /dev/null +++ b/src/main/java/com/lowagie/text/html/SAXmyHtmlHandler.java @@ -0,0 +1,293 @@ +/* + * $Id: SAXmyHtmlHandler.java,v 1.25 2006/03/23 09:51:50 blowagie Exp $ + * $Name: $ + * + * Copyright 2001, 2002 by Bruno Lowagie. + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Properties; + +import org.xml.sax.Attributes; + +import com.lowagie.text.Cell; +import com.lowagie.text.DocListener; +import com.lowagie.text.DocumentException; +import com.lowagie.text.Element; +import com.lowagie.text.ElementTags; +import com.lowagie.text.ExceptionConverter; +import com.lowagie.text.Paragraph; +import com.lowagie.text.Table; +import com.lowagie.text.html.HtmlTagMap; +import com.lowagie.text.html.HtmlTags; +import com.lowagie.text.pdf.BaseFont; +import com.lowagie.text.xml.SAXiTextHandler; +import com.lowagie.text.xml.XmlPeer; + +/** + * The Tags-class maps several XHTML-tags to iText-objects. + */ + +public class SAXmyHtmlHandler extends SAXiTextHandler // SAXmyHandler +{ + + /** These are the properties of the body section. */ + private Properties bodyAttributes = new Properties(); + + /** This is the status of the table border. */ + private boolean tableBorder = false; + + /** + * Constructs a new SAXiTextHandler that will translate all the events + * triggered by the parser to actions on the Document-object. + * + * @param document + * this is the document on which events must be triggered + * @throws IOException + * @throws DocumentException + */ + + public SAXmyHtmlHandler(DocListener document) + throws DocumentException, IOException { + super(document, new HtmlTagMap()); + } + /** + * Constructs a new SAXiTextHandler that will translate all the events + * triggered by the parser to actions on the Document-object. + * + * @param document + * this is the document on which events must be triggered + * @param bf + * @throws IOException + * @throws DocumentException + */ + + public SAXmyHtmlHandler(DocListener document, BaseFont bf) + throws DocumentException, IOException { + super(document, new HtmlTagMap(), bf); + } + + /** + * Constructs a new SAXiTextHandler that will translate all the events + * triggered by the parser to actions on the Document-object. + * + * @param document + * this is the document on which events must be triggered + * @param htmlTags + * a tagmap translating HTML tags to iText tags + * @throws IOException + * @throws DocumentException + */ + + public SAXmyHtmlHandler(DocListener document, HashMap htmlTags) + throws DocumentException, IOException { + super(document, htmlTags); + } + + /** + * This method gets called when a start tag is encountered. + * + * @param uri + * the Uniform Resource Identifier + * @param lname + * the local name (without prefix), or the empty string if + * Namespace processing is not being performed. + * @param name + * the name of the tag that is encountered + * @param attrs + * the list of attributes + */ + + public void startElement(String uri, String lname, String name, + Attributes attrs) { + // System.err.println("Start: " + name); + + // super.handleStartingTags is replaced with handleStartingTags + // suggestion by Vu Ngoc Tan/Hop + name = name.toLowerCase(); + if (((HtmlTagMap) myTags).isHtml(name)) { + // we do nothing + return; + } + if (((HtmlTagMap) myTags).isHead(name)) { + // we do nothing + return; + } + if (((HtmlTagMap) myTags).isTitle(name)) { + // we do nothing + return; + } + if (((HtmlTagMap) myTags).isMeta(name)) { + // we look if we can change the body attributes + String meta = null; + String content = null; + if (attrs != null) { + for (int i = 0; i < attrs.getLength(); i++) { + String attribute = attrs.getQName(i); + if (attribute.equalsIgnoreCase(HtmlTags.CONTENT)) + content = attrs.getValue(i); + else if (attribute.equalsIgnoreCase(HtmlTags.NAME)) + meta = attrs.getValue(i); + } + } + if (meta != null && content != null) { + bodyAttributes.put(meta, content); + } + return; + } + if (((HtmlTagMap) myTags).isLink(name)) { + // we do nothing for the moment, in a later version we could extract + // the style sheet + return; + } + if (((HtmlTagMap) myTags).isBody(name)) { + // maybe we could extract some info about the document: color, + // margins,... + // but that's for a later version... + XmlPeer peer = new XmlPeer(ElementTags.ITEXT, name); + peer.addAlias(ElementTags.TOP, HtmlTags.TOPMARGIN); + peer.addAlias(ElementTags.BOTTOM, HtmlTags.BOTTOMMARGIN); + peer.addAlias(ElementTags.RIGHT, HtmlTags.RIGHTMARGIN); + peer.addAlias(ElementTags.LEFT, HtmlTags.LEFTMARGIN); + String content = null; + bodyAttributes.putAll(peer.getAttributes(attrs)); + handleStartingTags(peer.getTag(), bodyAttributes); + return; + } + if (myTags.containsKey(name)) { + XmlPeer peer = (XmlPeer) myTags.get(name); + if (Table.isTag(peer.getTag()) || Cell.isTag(peer.getTag())) { + Properties p = peer.getAttributes(attrs); + String value; + if (Table.isTag(peer.getTag()) + && (value = p.getProperty(ElementTags.BORDERWIDTH)) != null) { + if (Float.valueOf(value + "f").floatValue() > 0) { + tableBorder = true; + } + } + if (tableBorder) { + p.put(ElementTags.LEFT, String.valueOf(true)); + p.put(ElementTags.RIGHT, String.valueOf(true)); + p.put(ElementTags.TOP, String.valueOf(true)); + p.put(ElementTags.BOTTOM, String.valueOf(true)); + } + handleStartingTags(peer.getTag(), p); + return; + } + handleStartingTags(peer.getTag(), peer.getAttributes(attrs)); + return; + } + Properties attributes = new Properties(); + if (attrs != null) { + for (int i = 0; i < attrs.getLength(); i++) { + String attribute = attrs.getQName(i).toLowerCase(); + attributes.setProperty(attribute, attrs.getValue(i).toLowerCase()); + } + } + handleStartingTags(name, attributes); + } + + /** + * This method gets called when an end tag is encountered. + * + * @param uri + * the Uniform Resource Identifier + * @param lname + * the local name (without prefix), or the empty string if + * Namespace processing is not being performed. + * @param name + * the name of the tag that ends + */ + + public void endElement(String uri, String lname, String name) { + // System.err.println("End: " + name); + name = name.toLowerCase(); + if (Paragraph.isTag(name)) { + try { + document.add((Element) stack.pop()); + return; + } catch (DocumentException e) { + throw new ExceptionConverter(e); + } + } + if (((HtmlTagMap) myTags).isHead(name)) { + // we do nothing + return; + } + if (((HtmlTagMap) myTags).isTitle(name)) { + if (currentChunk != null) { + bodyAttributes.put(ElementTags.TITLE, currentChunk.content()); + } + return; + } + if (((HtmlTagMap) myTags).isMeta(name)) { + // we do nothing + return; + } + if (((HtmlTagMap) myTags).isLink(name)) { + // we do nothing + return; + } + if (((HtmlTagMap) myTags).isBody(name)) { + // we do nothing + return; + } + if (myTags.containsKey(name)) { + XmlPeer peer = (XmlPeer) myTags.get(name); + if (Table.isTag(peer.getTag())) { + tableBorder = false; + } + super.handleEndingTags(peer.getTag()); + return; + } + // super.handleEndingTags is replaced with handleEndingTags + // suggestion by Ken Auer + handleEndingTags(name); + } +} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/html/simpleparser/ALink.java b/src/main/java/com/lowagie/text/html/simpleparser/ALink.java new file mode 100644 index 0000000..a190e38 --- /dev/null +++ b/src/main/java/com/lowagie/text/html/simpleparser/ALink.java @@ -0,0 +1,57 @@ +/* + * Copyright 2005 Paulo Soares + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html.simpleparser; + +import com.lowagie.text.Paragraph; +/** + * + * @author psoares + */ +public interface ALink { + boolean process(Paragraph current, ChainedProperties cprops); +} diff --git a/src/main/java/com/lowagie/text/html/simpleparser/ChainedProperties.java b/src/main/java/com/lowagie/text/html/simpleparser/ChainedProperties.java new file mode 100644 index 0000000..c3e078a --- /dev/null +++ b/src/main/java/com/lowagie/text/html/simpleparser/ChainedProperties.java @@ -0,0 +1,127 @@ +/* + * Copyright 2004 Paulo Soares + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html.simpleparser; + +import java.util.ArrayList; +import java.util.HashMap; + +public class ChainedProperties { + + public final static int fontSizes[] = {8, 10, 12, 14, 18, 24, 36}; + public ArrayList chain = new ArrayList(); + + /** Creates a new instance of ChainedProperties */ + public ChainedProperties() { + } + + public String getProperty(String key) { + for (int k = chain.size() - 1; k >= 0; --k) { + Object obj[] = (Object[])chain.get(k); + HashMap prop = (HashMap)obj[1]; + String ret = (String)prop.get(key); + if (ret != null) + return ret; + } + return null; + } + + public boolean hasProperty(String key) { + for (int k = chain.size() - 1; k >= 0; --k) { + Object obj[] = (Object[])chain.get(k); + HashMap prop = (HashMap)obj[1]; + if (prop.containsKey(key)) + return true; + } + return false; + } + + public void addToChain(String key, HashMap prop) { + // adjust the font size + String value = (String)prop.get("size"); + if (value != null) { + if (value.endsWith("px")) { + prop.put("size", value.substring(0, value.length() - 2)); + } + else { + int s = 0; + if (value.startsWith("+") || value.startsWith("-")) { + String old = getProperty("basefontsize"); + if (old == null) + old = "12"; + float f = Float.valueOf(old).floatValue(); + int c = (int)f; + for (int k = fontSizes.length - 1; k >= 0; --k) { + if (c >= fontSizes[k]) { + s = k; + break; + } + } + int inc = Integer.parseInt(value.startsWith("+") ? value.substring(1) : value); + s += inc; + } + else + s = Integer.parseInt(value) - 1; + if (s < 0) + s = 0; + else if (s >= fontSizes.length) + s = fontSizes.length - 1; + prop.put("size", Integer.toString(fontSizes[s])); + } + } + chain.add(new Object[]{key, prop}); + } + + public void removeChain(String key) { + for (int k = chain.size() - 1; k >= 0; --k) { + if (key.equals(((Object[])chain.get(k))[0])) { + chain.remove(k); + return; + } + } + } +} diff --git a/src/main/java/com/lowagie/text/html/simpleparser/FactoryProperties.java b/src/main/java/com/lowagie/text/html/simpleparser/FactoryProperties.java new file mode 100644 index 0000000..a017a1a --- /dev/null +++ b/src/main/java/com/lowagie/text/html/simpleparser/FactoryProperties.java @@ -0,0 +1,244 @@ +/* + * Copyright 2004 Paulo Soares + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html.simpleparser; + +import com.lowagie.text.*; +import com.lowagie.text.pdf.*; +import java.util.HashMap; +import java.util.StringTokenizer; +import java.awt.Color; + +/** + * + * @author psoares + */ +public class FactoryProperties { + + private FontFactoryImp fontImp; + + /** Creates a new instance of FactoryProperties */ + public FactoryProperties() { + } + + public Chunk createChunk(String text, ChainedProperties props) { + Chunk ck = new Chunk(text, getFont(props)); + if (props.hasProperty("sub")) + ck.setTextRise(-6); + else if (props.hasProperty("sup")) + ck.setTextRise(6); + return ck; + } + + private static void setParagraphLeading(Paragraph p, String leading) { + if (leading == null) { + p.setLeading(0, 1.5f); + return; + } + try { + StringTokenizer tk = new StringTokenizer(leading, " ,"); + String v = tk.nextToken(); + float v1 = Float.valueOf(v).floatValue(); + if (!tk.hasMoreTokens()) { + p.setLeading(v1, 0); + return; + } + v = tk.nextToken(); + float v2 = Float.valueOf(v).floatValue(); + p.setLeading(v1, v2); + } + catch (Exception e) { + p.setLeading(0, 1.5f); + } + + } + + public static Paragraph createParagraph(HashMap props) { + Paragraph p = new Paragraph(); + String value = (String)props.get("align"); + if (value != null) { + if (value.equalsIgnoreCase("center")) + p.setAlignment(Element.ALIGN_CENTER); + else if (value.equalsIgnoreCase("right")) + p.setAlignment(Element.ALIGN_RIGHT); + else if (value.equalsIgnoreCase("justify")) + p.setAlignment(Element.ALIGN_JUSTIFIED); + } + setParagraphLeading(p, (String)props.get("leading")); + return p; + } + + public static void createParagraph(Paragraph p, ChainedProperties props) { + String value = props.getProperty("align"); + if (value != null) { + if (value.equalsIgnoreCase("center")) + p.setAlignment(Element.ALIGN_CENTER); + else if (value.equalsIgnoreCase("right")) + p.setAlignment(Element.ALIGN_RIGHT); + else if (value.equalsIgnoreCase("justify")) + p.setAlignment(Element.ALIGN_JUSTIFIED); + } + setParagraphLeading(p, props.getProperty("leading")); + value = props.getProperty("before"); + if (value != null) { + try { + p.setSpacingBefore(Float.valueOf(value).floatValue()); + } + catch (Exception e) {} + } + value = props.getProperty("after"); + if (value != null) { + try { + p.setSpacingAfter(Float.valueOf(value).floatValue()); + } + catch (Exception e) {} + } + value = props.getProperty("extraparaspace"); + if (value != null) { + try { + p.setExtraParagraphSpace(Float.valueOf(value).floatValue()); + } + catch (Exception e) {} + } + } + + public static Paragraph createParagraph(ChainedProperties props) { + Paragraph p = new Paragraph(); + createParagraph(p, props); + return p; + } + + public static ListItem createListItem(ChainedProperties props) { + ListItem p = new ListItem(); + createParagraph(p, props); + return p; + } + + public Font getFont(ChainedProperties props) { + String face = props.getProperty("face"); + if (face != null) { + StringTokenizer tok = new StringTokenizer(face, ","); + while (tok.hasMoreTokens()) { + face = tok.nextToken().trim(); + if (FontFactory.isRegistered(face)) + break; + } + } + int style = 0; + if (props.hasProperty("i")) + style |= Font.ITALIC; + if (props.hasProperty("b")) + style |= Font.BOLD; + if (props.hasProperty("u")) + style |= Font.UNDERLINE; + String value = props.getProperty("size"); + float size = 12; + if (value != null) + size = Float.valueOf(value).floatValue(); + Color color = decodeColor(props.getProperty("color")); + String encoding = props.getProperty("encoding"); + if (encoding == null) + encoding = BaseFont.WINANSI; + FontFactoryImp ff = fontImp; + if (ff == null) + ff = FontFactory.getFontImp(); + return ff.getFont(face, encoding, true, size, style, color); + } + + public static Color decodeColor(String s) { + if (s == null) + return null; + s = s.toLowerCase().trim(); + Color c = (Color)colorTable.get(s); + if (c != null) + return c; + try { + if (s.startsWith("#")) + return new Color(Integer.parseInt(s.substring(1), 16)); + } + catch (Exception e) { + } + return null; + } + + public FontFactoryImp getFontImp() { + return fontImp; + } + + public void setFontImp(FontFactoryImp fontImp) { + this.fontImp = fontImp; + } + + public static HashMap colorTable = new HashMap(); + public static HashMap followTags = new HashMap(); + static { + followTags.put("i", "i"); + followTags.put("b", "b"); + followTags.put("u", "u"); + followTags.put("sub", "sub"); + followTags.put("sup", "sup"); + followTags.put("em", "i"); + followTags.put("strong", "b"); + + colorTable.put("black", new Color(0x000000)); + colorTable.put("green", new Color(0x008000)); + colorTable.put("silver", new Color(0xC0C0C0)); + colorTable.put("lime", new Color(0x00FF00)); + colorTable.put("gray", new Color(0x808080)); + colorTable.put("olive", new Color(0x808000)); + colorTable.put("white", new Color(0xFFFFFF)); + colorTable.put("yellow", new Color(0xFFFF00)); + colorTable.put("maroon", new Color(0x800000)); + colorTable.put("navy", new Color(0x000080)); + colorTable.put("red", new Color(0xFF0000)); + colorTable.put("blue", new Color(0x0000FF)); + colorTable.put("purple", new Color(0x800080)); + colorTable.put("teal", new Color(0x008080)); + colorTable.put("fuchsia", new Color(0xFF00FF)); + colorTable.put("aqua", new Color(0x00FFFF)); + } +} diff --git a/src/main/java/com/lowagie/text/html/simpleparser/HTMLWorker.java b/src/main/java/com/lowagie/text/html/simpleparser/HTMLWorker.java new file mode 100644 index 0000000..b28fe04 --- /dev/null +++ b/src/main/java/com/lowagie/text/html/simpleparser/HTMLWorker.java @@ -0,0 +1,623 @@ +/* + * Copyright 2004 Paulo Soares + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html.simpleparser; + +import com.lowagie.text.*; +import com.lowagie.text.pdf.*; +import java.util.Stack; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.StringTokenizer; +import java.io.IOException; +import java.io.Reader; +import java.io.File; + +public class HTMLWorker implements SimpleXMLDocHandler, DocListener { + + protected ArrayList objectList; + protected DocListener document; + private Paragraph currentParagraph; + private ChainedProperties cprops = new ChainedProperties(); + private Stack stack = new Stack(); + private boolean pendingTR = false; + private boolean pendingTD = false; + private boolean pendingLI = false; + private StyleSheet style = new StyleSheet(); + private boolean isPRE = false; + private Stack tableState = new Stack(); + private boolean skipText = false; + private HashMap interfaceProps; + private FactoryProperties factoryProperties = new FactoryProperties(); + + /** Creates a new instance of HTMLWorker */ + public HTMLWorker(DocListener document) { + this.document = document; + } + + public void setStyleSheet(StyleSheet style) { + this.style = style; + } + + public StyleSheet getStyleSheet() { + return style; + } + + public void setInterfaceProps(HashMap interfaceProps) { + this.interfaceProps = interfaceProps; + FontFactoryImp ff = null; + if (interfaceProps != null) + ff = (FontFactoryImp)interfaceProps.get("font_factory"); + factoryProperties.setFontImp(ff); + } + + public HashMap getInterfaceProps() { + return interfaceProps; + } + + public void parse(Reader reader) throws IOException { + SimpleXMLParser.parse(this, null, reader, true); + } + + public static ArrayList parseToList(Reader reader, StyleSheet style) throws IOException { + return parseToList(reader, style, null); + } + + public static ArrayList parseToList(Reader reader, StyleSheet style, HashMap interfaceProps) throws IOException { + HTMLWorker worker = new HTMLWorker(null); + if (style != null) + worker.style = style; + worker.document = worker; + worker.setInterfaceProps(interfaceProps); + worker.objectList = new ArrayList(); + worker.parse(reader); + return worker.objectList; + } + + public void endDocument() { + try { + for (int k = 0; k < stack.size(); ++k) + document.add((Element)stack.elementAt(k)); + if (currentParagraph != null) + document.add(currentParagraph); + currentParagraph = null; + } + catch (Exception e) { + throw new ExceptionConverter(e); + } + } + + public void startDocument() { + HashMap h = new HashMap(); + style.applyStyle("body", h); + cprops.addToChain("body", h); + } + + public void startElement(String tag, HashMap h) { + if (!tagsSupported.containsKey(tag)) + return; + try { + style.applyStyle(tag, h); + String follow = (String)FactoryProperties.followTags.get(tag); + if (follow != null) { + HashMap prop = new HashMap(); + prop.put(follow, null); + cprops.addToChain(follow, prop); + return; + } + if (tag.equals("a")) { + cprops.addToChain(tag, h); + if (currentParagraph == null) + currentParagraph = new Paragraph(); + stack.push(currentParagraph); + currentParagraph = new Paragraph(); + return; + } + if (tag.equals("br")) { + if (currentParagraph == null) + currentParagraph = new Paragraph(); + currentParagraph.add(factoryProperties.createChunk("\n", cprops)); + return; + } + if (tag.equals("font") || tag.equals("span")) { + cprops.addToChain(tag, h); + return; + } + if (tag.equals("img")) { + String src = (String)h.get("src"); + if (src == null) + return; + cprops.addToChain(tag, h); + Image img = null; + if (interfaceProps != null) { + HashMap images = (HashMap)interfaceProps.get("img_static"); + if (images != null) { + Image tim = (Image)images.get(src); + if (tim != null) + img = Image.getInstance(tim); + } else { + if (!src.startsWith("http")) { // relative src references only + String baseurl = (String)interfaceProps.get("img_baseurl"); + if (baseurl != null) { + src = baseurl+src; + img = Image.getInstance(src); + } + } + } + } + if (img == null) { + if (!src.startsWith("http")) { + String path = cprops.getProperty("image_path"); + if (path == null) + path = ""; + src = new File(path, src).getPath(); + } + img = Image.getInstance(src); + } + String align = (String)h.get("align"); + String width = (String)h.get("width"); + String height = (String)h.get("height"); + String before = cprops.getProperty("before"); + String after = cprops.getProperty("after"); + if (before != null) + img.setSpacingBefore(Float.valueOf(before).floatValue()); + if (after != null) + img.setSpacingAfter(Float.valueOf(after).floatValue()); + float wp = lengthParse(width, (int)img.width()); + float lp = lengthParse(height, (int)img.height()); + if (wp > 0 && lp > 0) + img.scalePercent(wp > lp ? lp : wp); + else if (wp > 0) + img.scalePercent(wp); + else if (lp > 0) + img.scalePercent(lp); + img.setWidthPercentage(0); + if (align != null) { + endElement("p"); + int ralign = Image.MIDDLE; + if (align.equalsIgnoreCase("left")) + ralign = Image.LEFT; + else if (align.equalsIgnoreCase("right")) + ralign = Image.RIGHT; + img.setAlignment(ralign); + Img i = null; + boolean skip = false; + if (interfaceProps != null) { + i = (Img)interfaceProps.get("img_interface"); + if (i != null) + skip = i.process(img, h, cprops, document); + } + if (!skip) + document.add(img); + cprops.removeChain(tag); + } + else { + cprops.removeChain(tag); + if (currentParagraph == null) + currentParagraph = FactoryProperties.createParagraph(cprops); + currentParagraph.add(new Chunk(img, 0, 0)); + } + return; + } + endElement("p"); + if (tag.equals("h1") || tag.equals("h2") || tag.equals("h3") || tag.equals("h4") || tag.equals("h5") || tag.equals("h6")) { + if (!h.containsKey("size")) + h.put("size", tag.substring(1)); + cprops.addToChain(tag, h); + return; + } + if (tag.equals("ul")) { + if (pendingLI) + endElement("li"); + skipText = true; + cprops.addToChain(tag, h); + com.lowagie.text.List list = new com.lowagie.text.List(false, 10); + list.setListSymbol("\u2022"); + stack.push(list); + return; + } + if (tag.equals("ol")) { + if (pendingLI) + endElement("li"); + skipText = true; + cprops.addToChain(tag, h); + com.lowagie.text.List list = new com.lowagie.text.List(true, 10); + stack.push(list); + return; + } + if (tag.equals("li")) { + if (pendingLI) + endElement("li"); + skipText = false; + pendingLI = true; + cprops.addToChain(tag, h); + stack.push(FactoryProperties.createListItem(cprops)); + return; + } + if (tag.equals("div") || tag.equals("body")) { + cprops.addToChain(tag, h); + return; + } + if (tag.equals("pre")) { + if (!h.containsKey("face")) { + h.put("face", "Courier"); + } + cprops.addToChain(tag, h); + isPRE = true; + return; + } + if (tag.equals("p")) { + cprops.addToChain(tag, h); + currentParagraph = FactoryProperties.createParagraph(h); + return; + } + if (tag.equals("tr")) { + if (pendingTR) + endElement("tr"); + skipText = true; + pendingTR = true; + cprops.addToChain("tr", h); + return; + } + if (tag.equals("td") || tag.equals("th")) { + if (pendingTD) + endElement(tag); + skipText = false; + pendingTD = true; + cprops.addToChain("td", h); + stack.push(new IncCell(tag, cprops)); + return; + } + if (tag.equals("table")) { + cprops.addToChain("table", h); + IncTable table = new IncTable(h); + stack.push(table); + tableState.push(new boolean[]{pendingTR, pendingTD}); + pendingTR = pendingTD = false; + skipText = true; + return; + } + } + catch (Exception e) { + throw new ExceptionConverter(e); + } + } + + public void endElement(String tag) { + if (!tagsSupported.containsKey(tag)) + return; + try { + String follow = (String)FactoryProperties.followTags.get(tag); + if (follow != null) { + cprops.removeChain(follow); + return; + } + if (tag.equals("font") || tag.equals("span")) { + cprops.removeChain(tag); + return; + } + if (tag.equals("a")) { + if (currentParagraph == null) + currentParagraph = new Paragraph(); + ALink i = null; + boolean skip = false; + if (interfaceProps != null) { + i = (ALink)interfaceProps.get("alink_interface"); + if (i != null) + skip = i.process(currentParagraph, cprops); + } + if (!skip) { + String href = cprops.getProperty("href"); + if (href != null) { + ArrayList chunks = currentParagraph.getChunks(); + for (int k = 0; k < chunks.size(); ++k) { + Chunk ck = (Chunk)chunks.get(k); + ck.setAnchor(href); + } + } + } + Paragraph tmp = (Paragraph)stack.pop(); + Phrase tmp2 = new Phrase(); + tmp2.add(currentParagraph); + tmp.add(tmp2); + currentParagraph = tmp; + cprops.removeChain("a"); + return; + } + if (tag.equals("br")) { + return; + } + if (currentParagraph != null) { + if (stack.empty()) + document.add(currentParagraph); + else { + Object obj = stack.pop(); + if (obj instanceof TextElementArray) { + TextElementArray current = (TextElementArray)obj; + current.add(currentParagraph); + } + stack.push(obj); + } + } + currentParagraph = null; + if (tag.equals("ul") || tag.equals("ol")) { + if (pendingLI) + endElement("li"); + skipText = false; + cprops.removeChain(tag); + if (stack.empty()) + return; + Object obj = stack.pop(); + if (!(obj instanceof com.lowagie.text.List)) { + stack.push(obj); + return; + } + if (stack.empty()) + document.add((Element)obj); + else + ((TextElementArray)stack.peek()).add(obj); + return; + } + if (tag.equals("li")) { + pendingLI = false; + skipText = true; + cprops.removeChain(tag); + if (stack.empty()) + return; + Object obj = stack.pop(); + if (!(obj instanceof ListItem)) { + stack.push(obj); + return; + } + if (stack.empty()) { + document.add((Element)obj); + return; + } + Object list = stack.pop(); + if (!(list instanceof com.lowagie.text.List)) { + stack.push(list); + return; + } + ListItem item = (ListItem)obj; + ((com.lowagie.text.List)list).add(item); + ArrayList cks = item.getChunks(); + if (cks.size() > 0) + item.listSymbol().setFont(((Chunk)cks.get(0)).font()); + stack.push(list); + return; + } + if (tag.equals("div") || tag.equals("body")) { + cprops.removeChain(tag); + return; + } + if (tag.equals("pre")) { + cprops.removeChain(tag); + isPRE = false; + return; + } + if (tag.equals("p")) { + cprops.removeChain(tag); + return; + } + if (tag.equals("h1") || tag.equals("h2") || tag.equals("h3") || tag.equals("h4") || tag.equals("h5") || tag.equals("h6")) { + cprops.removeChain(tag); + return; + } + if (tag.equals("table")) { + if (pendingTR) + endElement("tr"); + cprops.removeChain("table"); + IncTable table = (IncTable) stack.pop(); + PdfPTable tb = table.buildTable(); + tb.setSplitRows(true); + if (stack.empty()) + document.add(tb); + else + ((TextElementArray)stack.peek()).add(tb); + boolean state[] = (boolean[])tableState.pop(); + pendingTR = state[0]; + pendingTD = state[1]; + skipText = false; + return; + } + if (tag.equals("tr")) { + if (pendingTD) + endElement("td"); + pendingTR = false; + cprops.removeChain("tr"); + ArrayList cells = new ArrayList(); + IncTable table = null; + while (true) { + Object obj = stack.pop(); + if (obj instanceof IncCell) { + cells.add(((IncCell)obj).getCell()); + } + if (obj instanceof IncTable) { + table = (IncTable)obj; + break; + } + } + table.addCols(cells); + table.endRow(); + stack.push(table); + skipText = true; + return; + } + if (tag.equals("td") || tag.equals("th")) { + pendingTD = false; + cprops.removeChain("td"); + skipText = true; + return; + } + } + catch (Exception e) { + throw new ExceptionConverter(e); + } + } + + public void text(String str) { + if (skipText) + return; + String content = str; + if (isPRE) { + if (currentParagraph == null) + currentParagraph = new Paragraph(); + currentParagraph.add(factoryProperties.createChunk(content, cprops)); + return; + } + if (content.trim().length() == 0 && content.indexOf(' ') < 0) { + return; + } + + StringBuffer buf = new StringBuffer(); + int len = content.length(); + char character; + boolean newline = false; + for (int i = 0; i < len; i++) { + switch(character = content.charAt(i)) { + case ' ': + if (!newline) { + buf.append(character); + } + break; + case '\n': + if (i > 0) { + newline = true; + buf.append(' '); + } + break; + case '\r': + break; + case '\t': + break; + default: + newline = false; + buf.append(character); + } + } + if (currentParagraph == null) + currentParagraph = FactoryProperties.createParagraph(cprops); + currentParagraph.add(factoryProperties.createChunk(buf.toString(), cprops)); + } + + public boolean add(Element element) throws DocumentException { + objectList.add(element); + return true; + } + + public boolean add(Watermark watermark) { + return true; + } + + public void clearTextWrap() throws DocumentException { + } + + public void close() { + } + + public boolean newPage() throws DocumentException { + return true; + } + + public void open() { + } + + public void removeWatermark() { + } + + public void resetFooter() { + } + + public void resetHeader() { + } + + public void resetPageCount() { + } + + public void setFooter(HeaderFooter footer) { + } + + public void setHeader(HeaderFooter header) { + } + + public boolean setMarginMirroring(boolean marginMirroring) { + return true; + } + + public boolean setMargins(float marginLeft, float marginRight, float marginTop, float marginBottom) { + return true; + } + + public void setPageCount(int pageN) { + } + + public boolean setPageSize(Rectangle pageSize) { + return true; + } + + public static final String tagsSupportedString = "ol ul li a pre font span br p div body table td th tr i b u sub sup em strong" + + " h1 h2 h3 h4 h5 h6 img"; + + public static final HashMap tagsSupported = new HashMap(); + + static { + StringTokenizer tok = new StringTokenizer(tagsSupportedString); + while (tok.hasMoreTokens()) + tagsSupported.put(tok.nextToken(), null); + } + + private static float lengthParse(String txt, int c) { + if (txt == null) + return -1; + if (txt.endsWith("%")) { + float vf = Float.valueOf(txt.substring(0, txt.length() - 1)).floatValue(); + return vf; + } + int v = Integer.parseInt(txt); + return (float)v / c * 100f; + } +} diff --git a/src/main/java/com/lowagie/text/html/simpleparser/Img.java b/src/main/java/com/lowagie/text/html/simpleparser/Img.java new file mode 100644 index 0000000..a7c066c --- /dev/null +++ b/src/main/java/com/lowagie/text/html/simpleparser/Img.java @@ -0,0 +1,60 @@ +/* + * Copyright 2005 Paulo Soares + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html.simpleparser; + +import com.lowagie.text.Image; +import com.lowagie.text.DocListener; +import java.util.HashMap; + +/** + * + * @author psoares + */ +public interface Img { + boolean process(Image img, HashMap h, ChainedProperties cprops, DocListener doc); +} diff --git a/src/main/java/com/lowagie/text/html/simpleparser/IncCell.java b/src/main/java/com/lowagie/text/html/simpleparser/IncCell.java new file mode 100644 index 0000000..3f25e0c --- /dev/null +++ b/src/main/java/com/lowagie/text/html/simpleparser/IncCell.java @@ -0,0 +1,124 @@ +/* + * Copyright 2004 Paulo Soares + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html.simpleparser; + +import com.lowagie.text.*; +import com.lowagie.text.pdf.*; +import java.util.ArrayList; +/** + * + * @author psoares + */ +public class IncCell implements TextElementArray { + + private ArrayList chunks = new ArrayList(); + private PdfPCell cell; + + /** Creates a new instance of IncCell */ + public IncCell(String tag, ChainedProperties props) { + cell = new PdfPCell((Phrase)null); + String value = props.getProperty("colspan"); + if (value != null) + cell.setColspan(Integer.parseInt(value)); + value = props.getProperty("align"); + if (tag.equals("th")) + cell.setHorizontalAlignment(Element.ALIGN_CENTER); + if (value != null) { + if ("center".equalsIgnoreCase(value)) + cell.setHorizontalAlignment(Element.ALIGN_CENTER); + else if ("right".equalsIgnoreCase(value)) + cell.setHorizontalAlignment(Element.ALIGN_RIGHT); + else if ("left".equalsIgnoreCase(value)) + cell.setHorizontalAlignment(Element.ALIGN_LEFT); + else if ("justify".equalsIgnoreCase(value)) + cell.setHorizontalAlignment(Element.ALIGN_JUSTIFIED); + } + value = props.getProperty("valign"); + cell.setVerticalAlignment(Element.ALIGN_MIDDLE); + if (value != null) { + if ("top".equalsIgnoreCase(value)) + cell.setVerticalAlignment(Element.ALIGN_TOP); + else if ("bottom".equalsIgnoreCase(value)) + cell.setVerticalAlignment(Element.ALIGN_BOTTOM); + } + value = props.getProperty("border"); + float border = 0; + if (value != null) + border = Float.valueOf(value).floatValue(); + cell.setBorderWidth(border); + value = props.getProperty("cellpadding"); + if (value != null) + cell.setPadding(Float.valueOf(value).floatValue()); + cell.setUseDescender(true); + value = props.getProperty("bgcolor"); + cell.setBackgroundColor(FactoryProperties.decodeColor(value)); + } + + public boolean add(Object o) { + if (!(o instanceof Element)) + return false; + cell.addElement((Element)o); + return true; + } + + public ArrayList getChunks() { + return chunks; + } + + public boolean process(ElementListener listener) { + return true; + } + + public int type() { + return 0; + } + + public PdfPCell getCell() { + return cell; + } +} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/html/simpleparser/IncTable.java b/src/main/java/com/lowagie/text/html/simpleparser/IncTable.java new file mode 100644 index 0000000..92b569b --- /dev/null +++ b/src/main/java/com/lowagie/text/html/simpleparser/IncTable.java @@ -0,0 +1,121 @@ +/* + * Copyright 2004 Paulo Soares + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html.simpleparser; + +import com.lowagie.text.pdf.*; +import java.util.HashMap; +import java.util.ArrayList; +import java.util.Collections; + +/** + * + * @author psoares + */ +public class IncTable { + private HashMap props = new HashMap(); + private ArrayList rows = new ArrayList(); + private ArrayList cols; + /** Creates a new instance of IncTable */ + public IncTable(HashMap props) { + this.props.putAll(props); + } + + public void addCol(PdfPCell cell) { + if (cols == null) + cols = new ArrayList(); + cols.add(cell); + } + + public void addCols(ArrayList ncols) { + if (cols == null) + cols = new ArrayList(ncols); + else + cols.addAll(ncols); + } + + public void endRow() { + if (cols != null) { + Collections.reverse(cols); + rows.add(cols); + cols = null; + } + } + + public ArrayList getRows() { + return rows; + } + + public PdfPTable buildTable() { + if (rows.size() == 0) + return new PdfPTable(1); + int ncol = 0; + ArrayList c0 = (ArrayList)rows.get(0); + for (int k = 0; k < c0.size(); ++k) { + ncol += ((PdfPCell)c0.get(k)).getColspan(); + } + PdfPTable table = new PdfPTable(ncol); + String width = (String)props.get("width"); + if (width == null) + table.setWidthPercentage(100); + else { + if (width.endsWith("%")) + table.setWidthPercentage(Float.valueOf(width.substring(0, width.length() - 1)).floatValue()); + else { + table.setTotalWidth(Float.valueOf(width).floatValue()); + table.setLockedWidth(true); + } + } + for (int row = 0; row < rows.size(); ++row) { + ArrayList col = (ArrayList)rows.get(row); + for (int k = 0; k < col.size(); ++k) { + table.addCell((PdfPCell)col.get(k)); + } + } + return table; + } +} diff --git a/src/main/java/com/lowagie/text/html/simpleparser/StyleSheet.java b/src/main/java/com/lowagie/text/html/simpleparser/StyleSheet.java new file mode 100644 index 0000000..a659715 --- /dev/null +++ b/src/main/java/com/lowagie/text/html/simpleparser/StyleSheet.java @@ -0,0 +1,112 @@ +/* + * Copyright 2004 Paulo Soares + * + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the License. + * + * The Original Code is 'iText, a free JAVA-PDF library'. + * + * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by + * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. + * All Rights Reserved. + * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer + * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. + * + * Contributor(s): all the names of the contributors are added in the source code + * where applicable. + * + * Alternatively, the contents of this file may be used under the terms of the + * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the + * provisions of LGPL are applicable instead of those above. If you wish to + * allow use of your version of this file only under the terms of the LGPL + * License and not to allow others to use your version of this file under + * the MPL, indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by the LGPL. + * If you do not delete the provisions above, a recipient may use your version + * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MPL as stated above or under the terms of the GNU + * Library General Public License as published by the Free Software Foundation; + * either version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more + * details. + * + * If you didn't download this code from the following link, you should check if + * you aren't using an obsolete version: + * http://www.lowagie.com/iText/ + */ + +package com.lowagie.text.html.simpleparser; + +import java.util.HashMap; + +public class StyleSheet { + + public HashMap classMap = new HashMap(); + public HashMap tagMap = new HashMap(); + + /** Creates a new instance of StyleSheet */ + public StyleSheet() { + } + + public void applyStyle(String tag, HashMap props) { + HashMap map = (HashMap)tagMap.get(tag.toLowerCase()); + if (map != null) { + HashMap temp = new HashMap(map); + temp.putAll(props); + props.putAll(temp); + } + String cm = (String)props.get("class"); + if (cm == null) + return; + map = (HashMap)classMap.get(cm.toLowerCase()); + if (map == null) + return; + props.remove("class"); + HashMap temp = new HashMap(map); + temp.putAll(props); + props.putAll(temp); + } + + private void applyMap(HashMap map, HashMap props) { + + } + + public void loadStyle(String style, HashMap props) { + classMap.put(style.toLowerCase(), props); + } + + public void loadStyle(String style, String key, String value) { + style = style.toLowerCase(); + HashMap props = (HashMap)classMap.get(style); + if (props == null) { + props = new HashMap(); + classMap.put(style, props); + } + props.put(key, value); + } + + public void loadTagStyle(String tag, HashMap props) { + tagMap.put(tag.toLowerCase(), props); + } + + public void loadTagStyle(String tag, String key, String value) { + tag = tag.toLowerCase(); + HashMap props = (HashMap)tagMap.get(tag); + if (props == null) { + props = new HashMap(); + tagMap.put(tag, props); + } + props.put(key, value); + } + +} \ No newline at end of file -- cgit v1.2.3