28 import java.io.IOException;
29 import java.io.Writer;
30
31 import jdk.javadoc.internal.doclets.toolkit.Content;
32 import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants;
33
34 /**
35 * Class for generating raw HTML content to be added to HTML pages of javadoc output.
36 *
37 * <p><b>This is NOT part of any supported API.
38 * If you write code that depends on this, you do so at your own risk.
39 * This code and its internal interfaces are subject to change or
40 * deletion without notice.</b>
41 *
42 * @author Bhavesh Patel
43 */
44 public class RawHtml extends Content {
45
46 private final String rawHtmlContent;
47
48 public static final Content nbsp = new RawHtml(" ");
49
50 public static final Content zws = new RawHtml("");
51
52 /**
53 * Constructor to construct a RawHtml object.
54 *
55 * @param rawHtml raw HTML text to be added
56 */
57 public RawHtml(CharSequence rawHtml) {
58 rawHtmlContent = rawHtml.toString();
59 }
60
61 /**
62 * This method is not supported by the class.
63 *
64 * @param content content that needs to be added
65 * @throws UnsupportedOperationException always
66 */
67 public void add(Content content) {
68 throw new UnsupportedOperationException();
69 }
70
87 }
88
89 /**
90 * {@inheritDoc}
91 */
92 @Override
93 public String toString() {
94 return rawHtmlContent;
95 }
96
97 private enum State { TEXT, ENTITY, TAG, STRING }
98
99 @Override
100 public int charCount() {
101 return charCount(rawHtmlContent);
102 }
103
104 static int charCount(CharSequence htmlText) {
105 State state = State.TEXT;
106 int count = 0;
107 for (int i = 0; i < htmlText.length(); i++) {
108 char c = htmlText.charAt(i);
109 switch (state) {
110 case TEXT:
111 switch (c) {
112 case '<':
113 state = State.TAG;
114 break;
115 case '&':
116 state = State.ENTITY;
117 count++;
118 break;
119 default:
120 count++;
121 }
122 break;
123
124 case ENTITY:
125 if (!Character.isLetterOrDigit(c))
126 state = State.TEXT;
127 break;
128
129 case TAG:
130 switch (c) {
131 case '"':
132 state = State.STRING;
133 break;
134 case '>':
135 state = State.TEXT;
136 break;
137 }
138 break;
139
140 case STRING:
141 switch (c) {
142 case '"':
143 state = State.TAG;
144 break;
145 }
146 }
147 }
148 return count;
149 }
150
151 /**
152 * {@inheritDoc}
153 */
154 @Override
155 public boolean write(Writer out, boolean atNewline) throws IOException {
156 out.write(rawHtmlContent);
157 return rawHtmlContent.endsWith(DocletConstants.NL);
158 }
159 }
|
28 import java.io.IOException;
29 import java.io.Writer;
30
31 import jdk.javadoc.internal.doclets.toolkit.Content;
32 import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants;
33
34 /**
35 * Class for generating raw HTML content to be added to HTML pages of javadoc output.
36 *
37 * <p><b>This is NOT part of any supported API.
38 * If you write code that depends on this, you do so at your own risk.
39 * This code and its internal interfaces are subject to change or
40 * deletion without notice.</b>
41 *
42 * @author Bhavesh Patel
43 */
44 public class RawHtml extends Content {
45
46 private final String rawHtmlContent;
47
48 private final static String ZERO_WIDTH_SPACE = "";
49
50 public static final Content nbsp = new RawHtml(" ");
51
52 public static final Content zws = new RawHtml(ZERO_WIDTH_SPACE);
53
54 /**
55 * Constructor to construct a RawHtml object.
56 *
57 * @param rawHtml raw HTML text to be added
58 */
59 public RawHtml(CharSequence rawHtml) {
60 rawHtmlContent = rawHtml.toString();
61 }
62
63 /**
64 * This method is not supported by the class.
65 *
66 * @param content content that needs to be added
67 * @throws UnsupportedOperationException always
68 */
69 public void add(Content content) {
70 throw new UnsupportedOperationException();
71 }
72
89 }
90
91 /**
92 * {@inheritDoc}
93 */
94 @Override
95 public String toString() {
96 return rawHtmlContent;
97 }
98
99 private enum State { TEXT, ENTITY, TAG, STRING }
100
101 @Override
102 public int charCount() {
103 return charCount(rawHtmlContent);
104 }
105
106 static int charCount(CharSequence htmlText) {
107 State state = State.TEXT;
108 int count = 0;
109 int entityStart = 0;
110 for (int i = 0; i < htmlText.length(); i++) {
111 char c = htmlText.charAt(i);
112 switch (state) {
113 case TEXT:
114 switch (c) {
115 case '<':
116 state = State.TAG;
117 break;
118 case '&':
119 state = State.ENTITY;
120 entityStart = i;
121 break;
122 default:
123 count++;
124 }
125 break;
126
127 case ENTITY:
128 if (c == ';') {
129 state = State.TEXT;
130 if (!isZeroWidthSpace(htmlText, entityStart, i+1))
131 count++;
132 }
133 break;
134
135 case TAG:
136 switch (c) {
137 case '"':
138 state = State.STRING;
139 break;
140 case '>':
141 state = State.TEXT;
142 break;
143 }
144 break;
145
146 case STRING:
147 if (c == '"') {
148 state = State.TAG;
149 }
150 break;
151 }
152 }
153 return count;
154 }
155
156 /**
157 * {@inheritDoc}
158 */
159 @Override
160 public boolean write(Writer out, boolean atNewline) throws IOException {
161 out.write(rawHtmlContent);
162 return rawHtmlContent.endsWith(DocletConstants.NL);
163 }
164
165 private static boolean isZeroWidthSpace(CharSequence cs, int start, int end) {
166 if (end - start != ZERO_WIDTH_SPACE.length())
167 return false;
168 for (int i = 0; i < ZERO_WIDTH_SPACE.length(); i++) {
169 if (ZERO_WIDTH_SPACE.charAt(i) != cs.charAt(i + start))
170 return false;
171 }
172 return true;
173 }
174 }
|