001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.editor.text;
011:
012: import java.io.IOException;
013: import java.io.Reader;
014: import java.net.URL;
015:
016: import org.eclipse.swt.SWT;
017: import org.eclipse.swt.SWTError;
018: import org.eclipse.swt.graphics.FontData;
019: import org.eclipse.swt.graphics.RGB;
020: import org.eclipse.swt.widgets.Display;
021:
022: /**
023: * Provides a set of convenience methods for creating HTML pages.
024: * <p>
025: * Moved into this package from <code>org.eclipse.jface.internal.text.revisions</code>.</p>
026: */
027: public class HTMLPrinter {
028:
029: private static RGB BG_COLOR_RGB = null;
030:
031: static {
032: final Display display = Display.getDefault();
033: if (display != null && !display.isDisposed()) {
034: try {
035: display.asyncExec(new Runnable() {
036: /*
037: * @see java.lang.Runnable#run()
038: */
039: public void run() {
040: BG_COLOR_RGB = display.getSystemColor(
041: SWT.COLOR_INFO_BACKGROUND).getRGB();
042: }
043: });
044: } catch (SWTError err) {
045: // see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=45294
046: if (err.code != SWT.ERROR_DEVICE_DISPOSED)
047: throw err;
048: }
049: }
050: }
051:
052: private HTMLPrinter() {
053: }
054:
055: private static String replace(String text, char c, String s) {
056:
057: int previous = 0;
058: int current = text.indexOf(c, previous);
059:
060: if (current == -1)
061: return text;
062:
063: StringBuffer buffer = new StringBuffer();
064: while (current > -1) {
065: buffer.append(text.substring(previous, current));
066: buffer.append(s);
067: previous = current + 1;
068: current = text.indexOf(c, previous);
069: }
070: buffer.append(text.substring(previous));
071:
072: return buffer.toString();
073: }
074:
075: public static String convertToHTMLContent(String content) {
076: content = replace(content, '&', "&"); //$NON-NLS-1$
077: content = replace(content, '"', """); //$NON-NLS-1$
078: content = replace(content, '<', "<"); //$NON-NLS-1$
079: return replace(content, '>', ">"); //$NON-NLS-1$
080: }
081:
082: public static String read(Reader rd) {
083:
084: StringBuffer buffer = new StringBuffer();
085: char[] readBuffer = new char[2048];
086:
087: try {
088: int n = rd.read(readBuffer);
089: while (n > 0) {
090: buffer.append(readBuffer, 0, n);
091: n = rd.read(readBuffer);
092: }
093: return buffer.toString();
094: } catch (IOException x) {
095: }
096:
097: return null;
098: }
099:
100: public static void insertPageProlog(StringBuffer buffer,
101: int position, RGB bgRGB, URL styleSheetURL) {
102:
103: if (bgRGB == null)
104: insertPageProlog(buffer, position, styleSheetURL);
105: else {
106: StringBuffer pageProlog = new StringBuffer(300);
107:
108: pageProlog.append("<html>"); //$NON-NLS-1$
109:
110: appendStyleSheetURL(pageProlog, styleSheetURL);
111:
112: pageProlog.append("<body text=\"#000000\" bgcolor=\""); //$NON-NLS-1$
113: appendColor(pageProlog, bgRGB);
114: pageProlog.append("\">"); //$NON-NLS-1$
115:
116: buffer.insert(position, pageProlog.toString());
117: }
118: }
119:
120: public static void insertPageProlog(StringBuffer buffer,
121: int position, RGB bgRGB, String styleSheet) {
122:
123: if (bgRGB == null)
124: insertPageProlog(buffer, position, styleSheet);
125: else {
126: StringBuffer pageProlog = new StringBuffer(300);
127:
128: pageProlog.append("<html>"); //$NON-NLS-1$
129:
130: appendStyleSheetURL(pageProlog, styleSheet);
131:
132: pageProlog.append("<body text=\"#000000\" bgcolor=\""); //$NON-NLS-1$
133: appendColor(pageProlog, bgRGB);
134: pageProlog.append("\">"); //$NON-NLS-1$
135:
136: buffer.insert(position, pageProlog.toString());
137: }
138: }
139:
140: public static void insertStyles(StringBuffer buffer, String[] styles) {
141: if (styles == null || styles.length == 0)
142: return;
143:
144: StringBuffer styleBuf = new StringBuffer(10 * styles.length);
145: for (int i = 0; styles != null && i < styles.length; i++) {
146: styleBuf.append(" style=\""); //$NON-NLS-1$
147: styleBuf.append(styles[i]);
148: styleBuf.append('"');
149: }
150:
151: // Find insertion index
152: // a) within existing body tag with trailing space
153: int index = buffer.indexOf("<body "); //$NON-NLS-1$
154: if (index != -1) {
155: buffer.insert(index + 5, styleBuf);
156: return;
157: }
158:
159: // b) within existing body tag without attributes
160: index = buffer.indexOf("<body>"); //$NON-NLS-1$
161: if (index != -1) {
162: buffer.insert(index + 5, ' ');
163: buffer.insert(index + 6, styleBuf);
164: return;
165: }
166: }
167:
168: public static void insertPageProlog(StringBuffer buffer,
169: int position, RGB bgRGB) {
170: if (bgRGB == null)
171: insertPageProlog(buffer, position);
172: else {
173: StringBuffer pageProlog = new StringBuffer(60);
174: pageProlog
175: .append("<html><body text=\"#000000\" bgcolor=\""); //$NON-NLS-1$
176: appendColor(pageProlog, bgRGB);
177: pageProlog.append("\">"); //$NON-NLS-1$
178: buffer.insert(position, pageProlog.toString());
179: }
180: }
181:
182: private static void appendStyleSheetURL(StringBuffer buffer,
183: String styleSheet) {
184: if (styleSheet == null)
185: return;
186:
187: buffer
188: .append("<head><style CHARSET=\"ISO-8859-1\" TYPE=\"text/css\">"); //$NON-NLS-1$
189: buffer.append(styleSheet);
190: buffer.append("</style></head>"); //$NON-NLS-1$
191: }
192:
193: private static void appendStyleSheetURL(StringBuffer buffer,
194: URL styleSheetURL) {
195: if (styleSheetURL == null)
196: return;
197:
198: buffer.append("<head>"); //$NON-NLS-1$
199:
200: buffer.append("<LINK REL=\"stylesheet\" HREF= \""); //$NON-NLS-1$
201: buffer.append(styleSheetURL);
202: buffer.append("\" CHARSET=\"ISO-8859-1\" TYPE=\"text/css\">"); //$NON-NLS-1$
203:
204: buffer.append("</head>"); //$NON-NLS-1$
205: }
206:
207: private static void appendColor(StringBuffer buffer, RGB rgb) {
208: buffer.append('#');
209: buffer.append(Integer.toHexString(rgb.red));
210: buffer.append(Integer.toHexString(rgb.green));
211: buffer.append(Integer.toHexString(rgb.blue));
212: }
213:
214: public static void insertPageProlog(StringBuffer buffer,
215: int position) {
216: insertPageProlog(buffer, position, getBgColor());
217: }
218:
219: public static void insertPageProlog(StringBuffer buffer,
220: int position, URL styleSheetURL) {
221: insertPageProlog(buffer, position, getBgColor(), styleSheetURL);
222: }
223:
224: public static void insertPageProlog(StringBuffer buffer,
225: int position, String styleSheet) {
226: insertPageProlog(buffer, position, getBgColor(), styleSheet);
227: }
228:
229: private static RGB getBgColor() {
230: if (BG_COLOR_RGB != null)
231: return BG_COLOR_RGB;
232: return new RGB(255, 255, 225); // RGB value of info bg color on WindowsXP
233:
234: }
235:
236: public static void addPageProlog(StringBuffer buffer) {
237: insertPageProlog(buffer, buffer.length());
238: }
239:
240: public static void addPageEpilog(StringBuffer buffer) {
241: buffer.append("</font></body></html>"); //$NON-NLS-1$
242: }
243:
244: public static void startBulletList(StringBuffer buffer) {
245: buffer.append("<ul>"); //$NON-NLS-1$
246: }
247:
248: public static void endBulletList(StringBuffer buffer) {
249: buffer.append("</ul>"); //$NON-NLS-1$
250: }
251:
252: public static void addBullet(StringBuffer buffer, String bullet) {
253: if (bullet != null) {
254: buffer.append("<li>"); //$NON-NLS-1$
255: buffer.append(bullet);
256: buffer.append("</li>"); //$NON-NLS-1$
257: }
258: }
259:
260: public static void addSmallHeader(StringBuffer buffer, String header) {
261: if (header != null) {
262: buffer.append("<h5>"); //$NON-NLS-1$
263: buffer.append(header);
264: buffer.append("</h5>"); //$NON-NLS-1$
265: }
266: }
267:
268: public static void addParagraph(StringBuffer buffer,
269: String paragraph) {
270: if (paragraph != null) {
271: buffer.append("<p>"); //$NON-NLS-1$
272: buffer.append(paragraph);
273: }
274: }
275:
276: public static void addParagraph(StringBuffer buffer,
277: Reader paragraphReader) {
278: if (paragraphReader != null)
279: addParagraph(buffer, read(paragraphReader));
280: }
281:
282: /**
283: * Replaces the following style attributes of the font definition of the <code>html</code>
284: * element:
285: * <ul>
286: * <li>font-size</li>
287: * <li>font-weight</li>
288: * <li>font-style</li>
289: * <li>font-family</li>
290: * </ul>
291: * The font's name is used as font family, a <code>sans-serif</code> default font family is
292: * appended for the case that the given font name is not available.
293: * <p>
294: * If the listed font attributes are not contained in the passed style list, nothing happens.
295: * </p>
296: *
297: * @param styles CSS style definitions
298: * @param fontData the font information to use
299: * @return the modified style definitions
300: * @since 3.3
301: */
302: public static String convertTopLevelFont(String styles,
303: FontData fontData) {
304: boolean bold = (fontData.getStyle() & SWT.BOLD) != 0;
305: boolean italic = (fontData.getStyle() & SWT.ITALIC) != 0;
306:
307: // See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=155993
308: String size = Integer.toString(fontData.getHeight())
309: + ("carbon".equals(SWT.getPlatform()) ? "px" : "pt"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
310:
311: String family = "'" + fontData.getName() + "',sans-serif"; //$NON-NLS-1$ //$NON-NLS-2$
312: styles = styles
313: .replaceFirst(
314: "(html\\s*\\{.*(?:\\s|;)font-size:\\s*)\\d+pt(\\;?.*\\})", "$1" + size + "$2"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
315: styles = styles
316: .replaceFirst(
317: "(html\\s*\\{.*(?:\\s|;)font-weight:\\s*)\\w+(\\;?.*\\})", "$1" + (bold ? "bold" : "normal") + "$2"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
318: styles = styles
319: .replaceFirst(
320: "(html\\s*\\{.*(?:\\s|;)font-style:\\s*)\\w+(\\;?.*\\})", "$1" + (italic ? "italic" : "normal") + "$2"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
321: styles = styles
322: .replaceFirst(
323: "(html\\s*\\{.*(?:\\s|;)font-family:\\s*).+?(;.*\\})", "$1" + family + "$2"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
324: return styles;
325: }
326: }
|