📄 htmlwriter.java
字号:
String name = map.getName(); incrIndent(); indentSmart(); write("<map"); if (name != null) { write(" name=\""); write(name); write("\">"); } else { write('>'); } writeLineSeparator(); incrIndent(); // Output the areas AttributeSet[] areas = map.getAreas(); if (areas != null) { for (int counter = 0, maxCounter = areas.length; counter < maxCounter; counter++) { indentSmart(); write("<area"); writeAttributes(areas[counter]); write("></area>"); writeLineSeparator(); } } decrIndent(); indentSmart(); write("</map>"); writeLineSeparator(); decrIndent(); } } } /** * Outputs the styles as a single element. Styles are not stored as * elements, but part of the document. For the time being styles are * written out as a comment, inside a style tag. */ void writeStyles(StyleSheet sheet) throws IOException { if (sheet != null) { Enumeration styles = sheet.getStyleNames(); if (styles != null) { boolean outputStyle = false; while (styles.hasMoreElements()) { String name = (String)styles.nextElement(); // Don't write out the default style. if (!StyleContext.DEFAULT_STYLE.equals(name) && writeStyle(name, sheet.getStyle(name), outputStyle)) { outputStyle = true; } } if (outputStyle) { writeStyleEndTag(); } } } } /** * Outputs the named style. <code>outputStyle</code> indicates * whether or not a style has been output yet. This will return * true if a style is written. */ boolean writeStyle(String name, Style style, boolean outputStyle) throws IOException{ boolean didOutputStyle = false; Enumeration attributes = style.getAttributeNames(); if (attributes != null) { while (attributes.hasMoreElements()) { Object attribute = attributes.nextElement(); if (attribute instanceof CSS.Attribute) { String value = style.getAttribute(attribute).toString(); if (value != null) { if (!outputStyle) { writeStyleStartTag(); outputStyle = true; } if (!didOutputStyle) { didOutputStyle = true; indentSmart(); write(name); write(" {"); } else { write(";"); } write(' '); write(attribute.toString()); write(": "); write(value); } } } } if (didOutputStyle) { write(" }"); writeLineSeparator(); } return didOutputStyle; } void writeStyleStartTag() throws IOException { indentSmart(); write("<style type=\"text/css\">"); incrIndent(); writeLineSeparator(); indentSmart(); write("<!--"); incrIndent(); writeLineSeparator(); } void writeStyleEndTag() throws IOException { decrIndent(); indentSmart(); write("-->"); writeLineSeparator(); decrIndent(); indentSmart(); write("</style>"); writeLineSeparator(); indentSmart(); } // --- conversion support --------------------------- /** * Convert the give set of attributes to be html for * the purpose of writing them out. Any keys that * have been converted will not appear in the resultant * set. Any keys not converted will appear in the * resultant set the same as the received set.<p> * This will put the converted values into <code>to</code>, unless * it is null in which case a temporary AttributeSet will be returned. */ AttributeSet convertToHTML(AttributeSet from, MutableAttributeSet to) { if (to == null) { to = convAttr; } to.removeAttributes(to); if (writeCSS) { convertToHTML40(from, to); } else { convertToHTML32(from, to); } return to; } /** * If true, the writer will emit CSS attributes in preference * to HTML tags/attributes (i.e. It will emit an HTML 4.0 * style). */ private boolean writeCSS = false; /** * Buffer for the purpose of attribute conversion */ private MutableAttributeSet convAttr = new SimpleAttributeSet(); /** * Buffer for the purpose of attribute conversion. This can be * used if convAttr is being used. */ private MutableAttributeSet oConvAttr = new SimpleAttributeSet(); /** * Create an older style of HTML attributes. This will * convert character level attributes that have a StyleConstants * mapping over to an HTML tag/attribute. Other CSS attributes * will be placed in an HTML style attribute. */ private static void convertToHTML32(AttributeSet from, MutableAttributeSet to) { if (from == null) { return; } Enumeration keys = from.getAttributeNames(); String value = ""; while (keys.hasMoreElements()) { Object key = keys.nextElement(); if (key instanceof CSS.Attribute) { if ((key == CSS.Attribute.FONT_FAMILY) || (key == CSS.Attribute.FONT_SIZE) || (key == CSS.Attribute.COLOR)) { createFontAttribute((CSS.Attribute)key, from, to); } else if (key == CSS.Attribute.FONT_WEIGHT) { // add a bold tag is weight is bold CSS.FontWeight weightValue = (CSS.FontWeight) from.getAttribute(CSS.Attribute.FONT_WEIGHT); if ((weightValue != null) && (weightValue.getValue() > 400)) { addAttribute(to, HTML.Tag.B, SimpleAttributeSet.EMPTY); } } else if (key == CSS.Attribute.FONT_STYLE) { String s = from.getAttribute(key).toString(); if (s.indexOf("italic") >= 0) { addAttribute(to, HTML.Tag.I, SimpleAttributeSet.EMPTY); } } else if (key == CSS.Attribute.TEXT_DECORATION) { String decor = from.getAttribute(key).toString(); if (decor.indexOf("underline") >= 0) { addAttribute(to, HTML.Tag.U, SimpleAttributeSet.EMPTY); } if (decor.indexOf("line-through") >= 0) { addAttribute(to, HTML.Tag.STRIKE, SimpleAttributeSet.EMPTY); } } else if (key == CSS.Attribute.VERTICAL_ALIGN) { String vAlign = from.getAttribute(key).toString(); if (vAlign.indexOf("sup") >= 0) { addAttribute(to, HTML.Tag.SUP, SimpleAttributeSet.EMPTY); } if (vAlign.indexOf("sub") >= 0) { addAttribute(to, HTML.Tag.SUB, SimpleAttributeSet.EMPTY); } } else if (key == CSS.Attribute.TEXT_ALIGN) { addAttribute(to, HTML.Attribute.ALIGN, from.getAttribute(key).toString()); } else { // default is to store in a HTML style attribute if (value.length() > 0) { value = value + "; "; } value = value + key + ": " + from.getAttribute(key); } } else { Object attr = from.getAttribute(key); if (attr instanceof AttributeSet) { attr = ((AttributeSet)attr).copyAttributes(); } addAttribute(to, key, attr); } } if (value.length() > 0) { to.addAttribute(HTML.Attribute.STYLE, value); } } /** * Add an attribute only if it doesn't exist so that we don't * loose information replacing it with SimpleAttributeSet.EMPTY */ private static void addAttribute(MutableAttributeSet to, Object key, Object value) { Object attr = to.getAttribute(key); if (attr == null || attr == SimpleAttributeSet.EMPTY) { to.addAttribute(key, value); } else { if (attr instanceof MutableAttributeSet && value instanceof AttributeSet) { ((MutableAttributeSet)attr).addAttributes((AttributeSet)value); } } } /** * Create/update an HTML <font> tag attribute. The * value of the attribute should be a MutableAttributeSet so * that the attributes can be updated as they are discovered. */ private static void createFontAttribute(CSS.Attribute a, AttributeSet from, MutableAttributeSet to) { MutableAttributeSet fontAttr = (MutableAttributeSet) to.getAttribute(HTML.Tag.FONT); if (fontAttr == null) { fontAttr = new SimpleAttributeSet(); to.addAttribute(HTML.Tag.FONT, fontAttr); } // edit the parameters to the font tag String htmlValue = from.getAttribute(a).toString(); if (a == CSS.Attribute.FONT_FAMILY) { fontAttr.addAttribute(HTML.Attribute.FACE, htmlValue); } else if (a == CSS.Attribute.FONT_SIZE) { fontAttr.addAttribute(HTML.Attribute.SIZE, htmlValue); } else if (a == CSS.Attribute.COLOR) { fontAttr.addAttribute(HTML.Attribute.COLOR, htmlValue); } } /** * Copies the given AttributeSet to a new set, converting * any CSS attributes found to arguments of an HTML style * attribute. */ private static void convertToHTML40(AttributeSet from, MutableAttributeSet to) { Enumeration keys = from.getAttributeNames(); String value = ""; while (keys.hasMoreElements()) { Object key = keys.nextElement(); if (key instanceof CSS.Attribute) { value = value + " " + key + "=" + from.getAttribute(key) + ";"; } else { to.addAttribute(key, from.getAttribute(key)); } } if (value.length() > 0) { to.addAttribute(HTML.Attribute.STYLE, value); } } // // Overrides the writing methods to only break a string when // canBreakString is true. // In a future release it is likely AbstractWriter will get this // functionality. // /** * Writes the line separator. This is overriden to make sure we don't * replace the newline content in case it is outside normal ascii. * @since 1.3 */ protected void writeLineSeparator() throws IOException { boolean oldReplace = replaceEntities; replaceEntities = false; super.writeLineSeparator(); replaceEntities = oldReplace; indented = false; } /** * This method is overriden to map any character entities, such as * < to &lt;. <code>super.output</code> will be invoked to * write the content. * @since 1.3 */ protected void output(char[] chars, int start, int length) throws IOException { if (!replaceEntities) { super.output(chars, start, length); return; } int last = start; length += start; for (int counter = start; counter < length; counter++) { // This will change, we need better support character level // entities. switch(chars[counter]) { // Character level entities. case '<': if (counter > last) { super.output(chars, last, counter - last); } last = counter + 1; output("<"); break; case '>': if (counter > last) { super.output(chars, last, counter - last); } last = counter + 1; output(">"); break; case '&': if (counter > last) { super.output(chars, last, counter - last); } last = counter + 1; output("&"); break; case '"': if (counter > last) { super.output(chars, last, counter - last); } last = counter + 1; output("""); break; // Special characters case '\n': case '\t': case '\r': break; default: if (chars[counter] < ' ' || chars[counter] > 127) { if (counter > last) { super.output(chars, last, counter - last); } last = counter + 1; // If the character is outside of ascii, write the // numeric value. output("&#"); output(String.valueOf((int)chars[counter])); output(";"); } break; } } if (last < length) { super.output(chars, last, length - last); } } /** * This directly invokes super's <code>output</code> after converting * <code>string</code> to a char[]. */ private void output(String string) throws IOException { int length = string.length(); if (tempChars == null || tempChars.length < length) { tempChars = new char[length]; } string.getChars(0, length, tempChars, 0); super.output(tempChars, 0, length); } private boolean indented = false; /** * Writes indent only once per line. */ private void indentSmart() throws IOException { if (!indented) { indent(); indented = true; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -