"+NEWLINE); // FIXME: Class value = ? incrIndent(); } /** * Write a paragraph end tag, closes any other open tags. */ protected void writeEndParagraph() throws IOException { endOpenTags(); writeEndTag("
"); } /** * Writes the body of the HTML document. */ protected void writeBody() throws IOException, BadLocationException { writeStartTag(""); ElementIterator ei = getElementIterator(); Element e = ei.first(); boolean inParagraph = false; do { if( e.isLeaf() ) { boolean hasNL = (getText(e).indexOf(NEWLINE) != -1); if( !inParagraph && hasText( e ) ) { writeStartParagraph(e); inParagraph = true; } if( hasText( e ) ) writeContent(e, true); if( hasNL && inParagraph ) { writeEndParagraph(); inParagraph = false; } else endOpenTags(); } } while((e = ei.next()) != null); writeEndTag(""); } protected void text(Element elem) throws IOException, BadLocationException { write( getText(elem).trim() ); } /** * Write bold, indent and underline tags. */ protected void writeHTMLTags(AttributeSet attr) throws IOException { if(attr.getAttribute(StyleConstants.Bold) != null) if(((Boolean)attr.getAttribute(StyleConstants.Bold)).booleanValue()) { write(""); tagStack.push(""); } if(attr.getAttribute(StyleConstants.Italic) != null) if(((Boolean)attr.getAttribute(StyleConstants.Italic)).booleanValue()) { write(""); tagStack.push(""); } if(attr.getAttribute(StyleConstants.Underline) != null) if(((Boolean)attr.getAttribute(StyleConstants.Underline)).booleanValue()) { write(""); tagStack.push(""); } } /** * Returns whether the element contains text or not. */ protected boolean isText(Element elem) { return (elem.getEndOffset() != elem.getStartOffset()); } /** * Writes the content of an element. */ protected void writeContent(Element elem, boolean needsIndenting) throws IOException, BadLocationException { writeNonHTMLAttributes(elem.getAttributes()); if(needsIndenting) indent(); writeHTMLTags(elem.getAttributes()); if( isText(elem) ) text(elem); else writeLeaf(elem); endOpenTags(); } /** * Writes a non-text leaf element. */ protected void writeLeaf(Element e) throws IOException { // NOTE: Haven't tested if this is correct. if(e.getName().equals(StyleConstants.IconElementName)) writeImage(e); else writeComponent(e); } /** * Write the HTML attributes which do not have tag equivalents, * e.g. attributes other than bold/italic/underlined. */ protected void writeNonHTMLAttributes(AttributeSet attr) throws IOException { String style = ""; // Alignment? Background? if( StyleConstants.getForeground(attr) != null ) style = style + "color: " + getColor(StyleConstants.getForeground(attr)) + "; "; style = style + "font-size: "+StyleConstants.getFontSize(attr)+"pt; "; style = style + "font-family: "+StyleConstants.getFontFamily(attr); startFontTag(style); } /** * Write the styles used. */ protected void writeStyles() throws IOException { if(doc instanceof DefaultStyledDocument) { Enumeration> styles = ((DefaultStyledDocument)doc).getStyleNames(); while(styles.hasMoreElements()) writeStyle(doc.getStyle((String)styles.nextElement())); } else { // What else to do here? Style s = doc.getStyle("default"); if(s != null) writeStyle( s ); } } /** * Write a set of attributes. */ protected void writeAttributes(AttributeSet attr) throws IOException { Enumeration> attribs = attr.getAttributeNames(); while(attribs.hasMoreElements()) { Object attribName = attribs.nextElement(); String name = attribName.toString(); String output = getAttribute(name, attr.getAttribute(attribName)); if( output != null ) { indent(); write( output + NEWLINE ); } } } /** * Deliberately unimplemented, handles component elements. */ protected void writeComponent(Element elem) throws IOException { } /** * Deliberately unimplemented. * Writes StyleConstants.IconElementName elements. */ protected void writeImage(Element elem) throws IOException { } // -------------------- Private methods. -------------------------------- /** * Write a single style attribute */ private String getAttribute(String name, Object a) throws IOException { if(name.equals("foreground")) return "foreground:"+getColor((Color)a)+";"; if(name.equals("background")) return "background:"+getColor((Color)a)+";"; if(name.equals("italic")) return "italic:"+(((Boolean)a).booleanValue() ? "italic;" : ";"); if(name.equals("bold")) return "bold:"+(((Boolean)a).booleanValue() ? "bold;" : "normal;"); if(name.equals("family")) return "family:" + a + ";"; if(name.equals("size")) { int size = ((Integer)a).intValue(); int htmlSize; if( size > 24 ) htmlSize = 7; else if( size > 18 ) htmlSize = 6; else if( size > 14 ) htmlSize = 5; else if( size > 12 ) htmlSize = 4; else if( size > 10 ) htmlSize = 3; else if( size > 8 ) htmlSize = 2; else htmlSize = 1; return "size:" + htmlSize + ";"; } return null; } /** * Stupid that Color doesn't have a method for this. */ private String getColor(Color c) { String r = "00" + Integer.toHexString(c.getRed()); r = r.substring(r.length() - 2); String g = "00" + Integer.toHexString(c.getGreen()); g = g.substring(g.length() - 2); String b = "00" + Integer.toHexString(c.getBlue()); b = b.substring(b.length() - 2); return "#" + r + g + b; } /** * Empty the stack of open tags */ private void endOpenTags() throws IOException { while(tagStack.size() > 0) write(tagStack.pop()); if( inFontTag() ) { write(""+NEWLINE); endFontTag(); } } /** * Output a single style */ private void writeStyle(Style s) throws IOException { if( s == null ) return; writeStartTag("p."+s.getName()+" {"); writeAttributes(s); writeEndTag("}"); } private boolean hasText(Element e) throws BadLocationException { return (getText(e).trim().length() > 0); } }