📄 minimalhtmlwriter.java
字号:
/* * @(#)MinimalHTMLWriter.java 1.15 05/11/17 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package javax.swing.text.html;import java.io.Writer;import java.io.IOException;import java.util.*;import java.awt.Color;import javax.swing.text.*;/** * MinimalHTMLWriter is a fallback writer used by the * HTMLEditorKit to write out HTML for a document that * is a not produced by the EditorKit. * * The format for the document is: * <pre> * <html> * <head> * <style> * <!-- list of named styles * p.normal { * font-family: SansSerif; * margin-height: 0; * font-size: 14 * } * --> * </style> * </head> * <body> * <p style=normal> * <b>Bold, italic, and underline attributes * of the run are emitted as HTML tags. * The remaining attributes are emitted as * part of the style attribute of a <span> tag. * The syntax is similar to inline styles.</b> * </p> * </body> * </html> * </pre> * * @author Sunita Mani * @version 1.15, 11/17/05 */public class MinimalHTMLWriter extends AbstractWriter { /** * These static finals are used to * tweak and query the fontMask about which * of these tags need to be generated or * terminated. */ private static final int BOLD = 0x01; private static final int ITALIC = 0x02; private static final int UNDERLINE = 0x04; // Used to map StyleConstants to CSS. private static final CSS css = new CSS(); private int fontMask = 0; int startOffset = 0; int endOffset = 0; /** * Stores the attributes of the previous run. * Used to compare with the current run's * attributeset. If identical, then a * <span> tag is not emitted. */ private AttributeSet fontAttributes; /** * Maps from style name as held by the Document, to the archived * style name (style name written out). These may differ. */ private Hashtable styleNameMapping; /** * Creates a new MinimalHTMLWriter. * * @param w Writer * @param doc StyledDocument * */ public MinimalHTMLWriter(Writer w, StyledDocument doc) { super(w, doc); } /** * Creates a new MinimalHTMLWriter. * * @param w Writer * @param doc StyledDocument * @param pos The location in the document to fetch the * content. * @param len The amount to write out. * */ public MinimalHTMLWriter(Writer w, StyledDocument doc, int pos, int len) { super(w, doc, pos, len); } /** * Generates HTML output * from a StyledDocument. * * @exception IOException on any I/O error * @exception BadLocationException if pos represents an invalid * location within the document. * */ public void write() throws IOException, BadLocationException { styleNameMapping = new Hashtable(); writeStartTag("<html>"); writeHeader(); writeBody(); writeEndTag("</html>"); } /** * Writes out all the attributes for the * following types: * StyleConstants.ParagraphConstants, * StyleConstants.CharacterConstants, * StyleConstants.FontConstants, * StyleConstants.ColorConstants. * The attribute name and value are separated by a colon. * Each pair is separated by a semicolon. * * @exception IOException on any I/O error */ protected void writeAttributes(AttributeSet attr) throws IOException { Enumeration attributeNames = attr.getAttributeNames(); while (attributeNames.hasMoreElements()) { Object name = attributeNames.nextElement(); if ((name instanceof StyleConstants.ParagraphConstants) || (name instanceof StyleConstants.CharacterConstants) || (name instanceof StyleConstants.FontConstants) || (name instanceof StyleConstants.ColorConstants)) { indent(); write(name.toString()); write(':'); write(css.styleConstantsValueToCSSValue ((StyleConstants)name, attr.getAttribute(name)). toString()); write(';'); write(NEWLINE); } } } /** * Writes out text. * * @exception IOException on any I/O error */ protected void text(Element elem) throws IOException, BadLocationException { String contentStr = getText(elem); if ((contentStr.length() > 0) && (contentStr.charAt(contentStr.length()-1) == NEWLINE)) { contentStr = contentStr.substring(0, contentStr.length()-1); } if (contentStr.length() > 0) { write(contentStr); } } /** * Writes out a start tag appropriately * indented. Also increments the indent level. * * @exception IOException on any I/O error */ protected void writeStartTag(String tag) throws IOException { indent(); write(tag); write(NEWLINE); incrIndent(); } /** * Writes out an end tag appropriately * indented. Also decrements the indent level. * * @exception IOException on any I/O error */ protected void writeEndTag(String endTag) throws IOException { decrIndent(); indent(); write(endTag); write(NEWLINE); } /** * Writes out the <head> and <style> * tags, and then invokes writeStyles() to write * out all the named styles as the content of the * <style> tag. The content is surrounded by * valid HTML comment markers to ensure that the * document is viewable in applications/browsers * that do not support the tag. * * @exception IOException on any I/O error */ protected void writeHeader() throws IOException { writeStartTag("<head>"); writeStartTag("<style>"); writeStartTag("<!--"); writeStyles(); writeEndTag("-->"); writeEndTag("</style>"); writeEndTag("</head>"); } /** * Writes out all the named styles as the * content of the <style> tag. * * @exception IOException on any I/O error */ protected void writeStyles() throws IOException { /* * Access to DefaultStyledDocument done to workaround * a missing API in styled document to access the * stylenames. */ DefaultStyledDocument styledDoc = ((DefaultStyledDocument)getDocument()); Enumeration styleNames = styledDoc.getStyleNames(); while (styleNames.hasMoreElements()) { Style s = styledDoc.getStyle((String)styleNames.nextElement()); /** PENDING: Once the name attribute is removed from the list we check check for 0. **/ if (s.getAttributeCount() == 1 && s.isDefined(StyleConstants.NameAttribute)) { continue; } indent(); write("p." + addStyleName(s.getName())); write(" {\n"); incrIndent(); writeAttributes(s); decrIndent(); indent(); write("}\n"); } } /** * Iterates over the elements in the document * and processes elements based on whether they are * branch elements or leaf elements. This method specially handles * leaf elements that are text. * * @exception IOException on any I/O error */ protected void writeBody() throws IOException, BadLocationException { ElementIterator it = getElementIterator(); /* This will be a section element for a styled document. We represent this element in HTML as the body tags. Therefore we ignore it. */ it.current(); Element next = null; writeStartTag("<body>"); boolean inContent = false; while((next = it.next()) != null) { if (!inRange(next)) { continue; } if (next instanceof AbstractDocument.BranchElement) { if (inContent) { writeEndParagraph(); inContent = false; fontMask = 0; } writeStartParagraph(next); } else if (isText(next)) { writeContent(next, !inContent); inContent = true; } else { writeLeaf(next); inContent = true; } } if (inContent) { writeEndParagraph(); } writeEndTag("</body>"); } /** * Emits an end tag for a <p> * tag. Before writing out the tag, this method ensures * that all other tags that have been opened are * appropriately closed off. * * @exception IOException on any I/O error */ protected void writeEndParagraph() throws IOException { writeEndMask(fontMask); if (inFontTag()) { endSpanTag(); } else { write(NEWLINE); } writeEndTag("</p>"); } /** * Emits the start tag for a paragraph. If * the paragraph has a named style associated with it, * then this method also generates a class attribute for the * <p> tag and sets its value to be the name of the * style. * * @exception IOException on any I/O error */ protected void writeStartParagraph(Element elem) throws IOException { AttributeSet attr = elem.getAttributes(); Object resolveAttr = attr.getAttribute(StyleConstants.ResolveAttribute); if (resolveAttr instanceof StyleContext.NamedStyle) { writeStartTag("<p class=" + mapStyleName(((StyleContext.NamedStyle)resolveAttr).getName()) + ">"); } else { writeStartTag("<p>"); } } /** * Responsible for writing out other non-text leaf * elements.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -