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 --- .../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 ++++ 8 files changed, 1468 insertions(+) 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/simpleparser') 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