911 if (sheet != null) {
912 Enumeration<?> styles = sheet.getStyleNames();
913 if (styles != null) {
914 boolean outputStyle = false;
915 while (styles.hasMoreElements()) {
916 String name = (String)styles.nextElement();
917 // Don't write out the default style.
918 if (!StyleContext.DEFAULT_STYLE.equals(name) &&
919 writeStyle(name, sheet.getStyle(name), outputStyle)) {
920 outputStyle = true;
921 }
922 }
923 if (outputStyle) {
924 writeStyleEndTag();
925 }
926 }
927 }
928 }
929
930 /**
931 * Outputs the named style. <code>outputStyle</code> indicates
932 * whether or not a style has been output yet. This will return
933 * true if a style is written.
934 */
935 boolean writeStyle(String name, Style style, boolean outputStyle)
936 throws IOException{
937 boolean didOutputStyle = false;
938 Enumeration<?> attributes = style.getAttributeNames();
939 if (attributes != null) {
940 while (attributes.hasMoreElements()) {
941 Object attribute = attributes.nextElement();
942 if (attribute instanceof CSS.Attribute) {
943 String value = style.getAttribute(attribute).toString();
944 if (value != null) {
945 if (!outputStyle) {
946 writeStyleStartTag();
947 outputStyle = true;
948 }
949 if (!didOutputStyle) {
950 didOutputStyle = true;
951 indentSmart();
984 void writeStyleEndTag() throws IOException {
985 decrIndent();
986 indentSmart();
987 write("-->");
988 writeLineSeparator();
989 decrIndent();
990 indentSmart();
991 write("</style>");
992 writeLineSeparator();
993 indentSmart();
994 }
995
996 // --- conversion support ---------------------------
997
998 /**
999 * Convert the give set of attributes to be html for
1000 * the purpose of writing them out. Any keys that
1001 * have been converted will not appear in the resultant
1002 * set. Any keys not converted will appear in the
1003 * resultant set the same as the received set.<p>
1004 * This will put the converted values into <code>to</code>, unless
1005 * it is null in which case a temporary AttributeSet will be returned.
1006 */
1007 AttributeSet convertToHTML(AttributeSet from, MutableAttributeSet to) {
1008 if (to == null) {
1009 to = convAttr;
1010 }
1011 to.removeAttributes(to);
1012 if (writeCSS) {
1013 convertToHTML40(from, to);
1014 } else {
1015 convertToHTML32(from, to);
1016 }
1017 return to;
1018 }
1019
1020 /**
1021 * If true, the writer will emit CSS attributes in preference
1022 * to HTML tags/attributes (i.e. It will emit an HTML 4.0
1023 * style).
1024 */
1172 // canBreakString is true.
1173 // In a future release it is likely AbstractWriter will get this
1174 // functionality.
1175 //
1176
1177 /**
1178 * Writes the line separator. This is overriden to make sure we don't
1179 * replace the newline content in case it is outside normal ascii.
1180 * @since 1.3
1181 */
1182 protected void writeLineSeparator() throws IOException {
1183 boolean oldReplace = replaceEntities;
1184 replaceEntities = false;
1185 super.writeLineSeparator();
1186 replaceEntities = oldReplace;
1187 indented = false;
1188 }
1189
1190 /**
1191 * This method is overriden to map any character entities, such as
1192 * < to &lt;. <code>super.output</code> will be invoked to
1193 * write the content.
1194 * @since 1.3
1195 */
1196 protected void output(char[] chars, int start, int length)
1197 throws IOException {
1198 if (!replaceEntities) {
1199 super.output(chars, start, length);
1200 return;
1201 }
1202 int last = start;
1203 length += start;
1204 for (int counter = start; counter < length; counter++) {
1205 // This will change, we need better support character level
1206 // entities.
1207 switch(chars[counter]) {
1208 // Character level entities.
1209 case '<':
1210 if (counter > last) {
1211 super.output(chars, last, counter - last);
1212 }
1243 if (chars[counter] < ' ' || chars[counter] > 127) {
1244 if (counter > last) {
1245 super.output(chars, last, counter - last);
1246 }
1247 last = counter + 1;
1248 // If the character is outside of ascii, write the
1249 // numeric value.
1250 output("&#");
1251 output(String.valueOf((int)chars[counter]));
1252 output(";");
1253 }
1254 break;
1255 }
1256 }
1257 if (last < length) {
1258 super.output(chars, last, length - last);
1259 }
1260 }
1261
1262 /**
1263 * This directly invokes super's <code>output</code> after converting
1264 * <code>string</code> to a char[].
1265 */
1266 private void output(String string) throws IOException {
1267 int length = string.length();
1268 if (tempChars == null || tempChars.length < length) {
1269 tempChars = new char[length];
1270 }
1271 string.getChars(0, length, tempChars, 0);
1272 super.output(tempChars, 0, length);
1273 }
1274
1275 private boolean indented = false;
1276
1277 /**
1278 * Writes indent only once per line.
1279 */
1280 private void indentSmart() throws IOException {
1281 if (!indented) {
1282 indent();
1283 indented = true;
1284 }
|
911 if (sheet != null) {
912 Enumeration<?> styles = sheet.getStyleNames();
913 if (styles != null) {
914 boolean outputStyle = false;
915 while (styles.hasMoreElements()) {
916 String name = (String)styles.nextElement();
917 // Don't write out the default style.
918 if (!StyleContext.DEFAULT_STYLE.equals(name) &&
919 writeStyle(name, sheet.getStyle(name), outputStyle)) {
920 outputStyle = true;
921 }
922 }
923 if (outputStyle) {
924 writeStyleEndTag();
925 }
926 }
927 }
928 }
929
930 /**
931 * Outputs the named style. {@code outputStyle} indicates
932 * whether or not a style has been output yet. This will return
933 * true if a style is written.
934 */
935 boolean writeStyle(String name, Style style, boolean outputStyle)
936 throws IOException{
937 boolean didOutputStyle = false;
938 Enumeration<?> attributes = style.getAttributeNames();
939 if (attributes != null) {
940 while (attributes.hasMoreElements()) {
941 Object attribute = attributes.nextElement();
942 if (attribute instanceof CSS.Attribute) {
943 String value = style.getAttribute(attribute).toString();
944 if (value != null) {
945 if (!outputStyle) {
946 writeStyleStartTag();
947 outputStyle = true;
948 }
949 if (!didOutputStyle) {
950 didOutputStyle = true;
951 indentSmart();
984 void writeStyleEndTag() throws IOException {
985 decrIndent();
986 indentSmart();
987 write("-->");
988 writeLineSeparator();
989 decrIndent();
990 indentSmart();
991 write("</style>");
992 writeLineSeparator();
993 indentSmart();
994 }
995
996 // --- conversion support ---------------------------
997
998 /**
999 * Convert the give set of attributes to be html for
1000 * the purpose of writing them out. Any keys that
1001 * have been converted will not appear in the resultant
1002 * set. Any keys not converted will appear in the
1003 * resultant set the same as the received set.<p>
1004 * This will put the converted values into {@code to}, unless
1005 * it is null in which case a temporary AttributeSet will be returned.
1006 */
1007 AttributeSet convertToHTML(AttributeSet from, MutableAttributeSet to) {
1008 if (to == null) {
1009 to = convAttr;
1010 }
1011 to.removeAttributes(to);
1012 if (writeCSS) {
1013 convertToHTML40(from, to);
1014 } else {
1015 convertToHTML32(from, to);
1016 }
1017 return to;
1018 }
1019
1020 /**
1021 * If true, the writer will emit CSS attributes in preference
1022 * to HTML tags/attributes (i.e. It will emit an HTML 4.0
1023 * style).
1024 */
1172 // canBreakString is true.
1173 // In a future release it is likely AbstractWriter will get this
1174 // functionality.
1175 //
1176
1177 /**
1178 * Writes the line separator. This is overriden to make sure we don't
1179 * replace the newline content in case it is outside normal ascii.
1180 * @since 1.3
1181 */
1182 protected void writeLineSeparator() throws IOException {
1183 boolean oldReplace = replaceEntities;
1184 replaceEntities = false;
1185 super.writeLineSeparator();
1186 replaceEntities = oldReplace;
1187 indented = false;
1188 }
1189
1190 /**
1191 * This method is overriden to map any character entities, such as
1192 * < to &lt;. {@code super.output} will be invoked to
1193 * write the content.
1194 * @since 1.3
1195 */
1196 protected void output(char[] chars, int start, int length)
1197 throws IOException {
1198 if (!replaceEntities) {
1199 super.output(chars, start, length);
1200 return;
1201 }
1202 int last = start;
1203 length += start;
1204 for (int counter = start; counter < length; counter++) {
1205 // This will change, we need better support character level
1206 // entities.
1207 switch(chars[counter]) {
1208 // Character level entities.
1209 case '<':
1210 if (counter > last) {
1211 super.output(chars, last, counter - last);
1212 }
1243 if (chars[counter] < ' ' || chars[counter] > 127) {
1244 if (counter > last) {
1245 super.output(chars, last, counter - last);
1246 }
1247 last = counter + 1;
1248 // If the character is outside of ascii, write the
1249 // numeric value.
1250 output("&#");
1251 output(String.valueOf((int)chars[counter]));
1252 output(";");
1253 }
1254 break;
1255 }
1256 }
1257 if (last < length) {
1258 super.output(chars, last, length - last);
1259 }
1260 }
1261
1262 /**
1263 * This directly invokes super's {@code output} after converting
1264 * {@code string} to a char[].
1265 */
1266 private void output(String string) throws IOException {
1267 int length = string.length();
1268 if (tempChars == null || tempChars.length < length) {
1269 tempChars = new char[length];
1270 }
1271 string.getChars(0, length, tempChars, 0);
1272 super.output(tempChars, 0, length);
1273 }
1274
1275 private boolean indented = false;
1276
1277 /**
1278 * Writes indent only once per line.
1279 */
1280 private void indentSmart() throws IOException {
1281 if (!indented) {
1282 indent();
1283 indented = true;
1284 }
|