1 /*******************************************************************************
2  * Copyright (c) 2007, 2017 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 
15 package org.eclipse.help.ui.internal.util;
16 
17 /**
18  * Utility class for preparing strings for display in a FormText widget by
19  * escaping the necessary characters
20  */
21 
22 public class EscapeUtils {
23 
24 	/**
25 	 * Replace every occurrence of {@code &, <, >, ', "} by an escape character
26 	 * Replace tabs with spaces
27 	 * @param value the original string, may not be null
28 	 * @return the escaped string
29 	 */
escapeSpecialChars(String value)30 	public static String escapeSpecialChars(String value) {
31 		return escapeSpecialChars(value, false);
32 	}
33 
34 	/**
35 	 * Replace every occurrence of {@code &, <, >, ', "} by an escape character
36 	 * but allow <b> and </b> through
37 	 * Replace tabs with spaces
38 	 * @param value the original string, may not be null
39 	 * @return the escaped string
40 	 */
escapeSpecialCharsLeavinggBold(String value)41 	public static String escapeSpecialCharsLeavinggBold(String value) {
42 		return escapeSpecialChars(value, true);
43 	}
44 
escapeAmpersand(String value)45 	public static String escapeAmpersand(String value) {
46 		return value.replaceAll("&", "&amp;"); //$NON-NLS-1$ //$NON-NLS-2$
47 	}
48 
49 	/**
50 	 * Escape any ampersands used in a label
51 	 */
escapeForLabel(String message)52 	public static String escapeForLabel(String message) {
53 		// Make the most common case - i.e. no ampersand the
54 		// most efficient
55 		if (message.indexOf('&') < 0) {
56 			return message;
57 		}
58 
59 		int next = 0;
60 		StringBuilder result = new StringBuilder();
61 		int index = message.indexOf('&');
62 		while (index >= 0) {
63 			result.append(message.substring(next, index + 1));
64 			result.append('&');
65 			next = index + 1;
66 			index = message.indexOf('&', next);
67 		}
68 		result.append(message.substring(next));
69 		return result.toString();
70 	}
71 
escapeSpecialChars(String value, boolean leaveBold)72 	private static String escapeSpecialChars(String value, boolean leaveBold) {
73 		if (value == null) {
74 			return null;
75 		}
76 		StringBuilder buf = new StringBuilder();
77 		for (int i = 0; i < value.length(); i++) {
78 			char c = value.charAt(i);
79 
80 			switch (c) {
81 			case '&':
82 				buf.append("&amp;"); //$NON-NLS-1$
83 				break;
84 			case '<':
85 				if (leaveBold) {
86 					int length = value.length();
87 					if (i +  6 < length) {
88 						String tag = value.substring(i, i+7);
89 						if (tag.equalsIgnoreCase("</code>")) { //$NON-NLS-1$
90 							buf.append("</span>"); //$NON-NLS-1$
91 							i+= 6;
92 							continue;
93 						}
94 					}
95 					if (i +  5 < length) {
96 						String tag = value.substring(i, i+6);
97 						if (tag.equalsIgnoreCase("<code>")) { //$NON-NLS-1$
98 							buf.append("<span font=\"code\">"); //$NON-NLS-1$
99 							i+= 5;
100 							continue;
101 						}
102 					}
103 					if (i + 3 < length) {
104 						String tag = value.substring(i, i + 4);
105 						if (tag.equalsIgnoreCase("</b>")) { //$NON-NLS-1$
106 							buf.append(tag);
107 							i += 3;
108 							continue;
109 						}
110 						if (tag.equalsIgnoreCase("<br>")) { //$NON-NLS-1$
111 							buf.append("<br/>"); //$NON-NLS-1$
112 							i+= 3;
113 							continue;
114 						}
115 					}
116 					if (i + 2 < length) {
117 						String tag = value.substring(i, i + 3);
118 						if (tag.equalsIgnoreCase("<b>")) { //$NON-NLS-1$
119 							buf.append(tag);
120 							i += 2;
121 							continue;
122 						}
123 					}
124 				}
125 				buf.append("&lt;"); //$NON-NLS-1$
126 				break;
127 			case '>':
128 				buf.append("&gt;"); //$NON-NLS-1$
129 				break;
130 			case '\'':
131 				buf.append("&apos;"); //$NON-NLS-1$
132 				break;
133 			case '\"':
134 				buf.append("&quot;"); //$NON-NLS-1$
135 				break;
136 			case 160:
137 				buf.append(" "); //$NON-NLS-1$
138 				break;
139 			case '\t':
140 				buf.append(' ');
141 				break;
142 			default:
143 				buf.append(c);
144 				break;
145 			}
146 		}
147 		return buf.toString();
148 	}
149 
150 }
151