KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > HtmlFormatter


1 /*
2  * HtmlFormatter.java
3  *
4  * Copyright (C) 1998-2002 Peter Graves
5  * $Id: HtmlFormatter.java,v 1.1.1.1 2002/09/24 16:08:29 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j;
23
24 public final class HtmlFormatter extends Formatter implements Constants
25 {
26     // HTML formats must not overlap with Java formats!
27
private static final int HTML_FORMAT_FIRST = JavaFormatter.JAVA_FORMAT_LAST + 1;
28
29     private static final int HTML_FORMAT_TEXT = HTML_FORMAT_FIRST;
30     private static final int HTML_FORMAT_COMMENT = HTML_FORMAT_FIRST + 1;
31     private static final int HTML_FORMAT_TAG = HTML_FORMAT_FIRST + 2;
32     private static final int HTML_FORMAT_TAG_IMAGE = HTML_FORMAT_FIRST + 3;
33     private static final int HTML_FORMAT_TAG_ANCHOR = HTML_FORMAT_FIRST + 4;
34     private static final int HTML_FORMAT_TAG_TABLE = HTML_FORMAT_FIRST + 5;
35     private static final int HTML_FORMAT_TAG_TABLE_ROW = HTML_FORMAT_FIRST + 6;
36     private static final int HTML_FORMAT_TAG_TABLE_DATA = HTML_FORMAT_FIRST + 7;
37     private static final int HTML_FORMAT_SCRIPT = HTML_FORMAT_FIRST + 8;
38
39     private StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
40
41     private JavaFormatter javaFormatter;
42
43     public HtmlFormatter(Buffer buffer)
44     {
45         this.buffer = buffer;
46         javaFormatter = new JavaFormatter(buffer, LANGUAGE_JAVASCRIPT);
47     }
48
49     private void endToken(int state)
50     {
51         if (sb.length() > 0) {
52             int format = HTML_FORMAT_TEXT;
53             switch (state) {
54                 case STATE_NEUTRAL:
55                     break;
56                 case STATE_TAG:
57                     format = HTML_FORMAT_TAG;
58                     break;
59                 case STATE_HTML_COMMENT:
60                     format = HTML_FORMAT_COMMENT;
61                     break;
62                 case STATE_SCRIPT:
63                     format = HTML_FORMAT_SCRIPT;
64                     break;
65                 default:
66                     break;
67             }
68             addSegment(sb.toString(), format);
69             sb.setLength(0);
70         }
71     }
72
73     public LineSegmentList formatLine(Line line)
74     {
75         if (line == null) {
76             clearSegmentList();
77             addSegment("", HTML_FORMAT_TEXT);
78             return segmentList;
79         }
80         final int flags = line.flags();
81         if (flags == STATE_SCRIPT || flags == STATE_COMMENT) {
82             final String JavaDoc trim = line.trim();
83             if (trim.startsWith("<!--")) {
84                 clearSegmentList();
85                 addSegment(line.getText(), HTML_FORMAT_COMMENT);
86                 return segmentList;
87             }
88             if (!trim.regionMatches(true, 0, "</script>", 0, 9))
89                 return javaFormatter.formatLine(line);
90         }
91         parseLine(line.getText(), flags);
92         for (int i = 0; i < segmentList.size(); i++) {
93             LineSegment segment = segmentList.getSegment(i);
94             if (segment.getFormat() != HTML_FORMAT_TAG)
95                 continue;
96             String JavaDoc token = segment.getText().toLowerCase();
97             if (token.startsWith("<a ") || token.equals("<a>")|| token.equals("</a>"))
98                 segment.setFormat(HTML_FORMAT_TAG_ANCHOR);
99             else if (token.startsWith("<img ") || token.equals("<img>"))
100                 segment.setFormat(HTML_FORMAT_TAG_IMAGE);
101             else if (token.startsWith("<table ") || token.equals("<table>") || token.equals("</table>"))
102                 segment.setFormat(HTML_FORMAT_TAG_TABLE);
103             else if (token.startsWith("<tr ") || token.equals("<tr>") || token.equals("</tr>"))
104                 segment.setFormat(HTML_FORMAT_TAG_TABLE_ROW);
105             else if (token.startsWith("<td ") || token.equals("<td>") || token.equals("</td>"))
106                 segment.setFormat(HTML_FORMAT_TAG_TABLE_DATA);
107         }
108         return segmentList;
109     }
110
111     private void parseLine(String JavaDoc text, int state)
112     {
113         if (Editor.tabsAreVisible())
114             text = Utilities.makeTabsVisible(text, buffer.getTabWidth());
115         else
116             text = Utilities.detab(text, buffer.getTabWidth());
117         clearSegmentList();
118         sb.setLength(0);
119         int i = 0;
120         final int limit = text.length();
121         while (i < limit) {
122             char c = text.charAt(i);
123             if (state == STATE_HTML_COMMENT) {
124                 if (i < limit-2 && text.substring(i, i+3).equals("-->")) {
125                     sb.append("-->");
126                     endToken(state);
127                     state = STATE_NEUTRAL;
128                     i += 3;
129                 } else {
130                     sb.append(c);
131                     ++i;
132                 }
133                 continue;
134             }
135             if (state == STATE_TAG) {
136                 if (c == '>') {
137                     sb.append(c);
138                     endToken(state);
139                     state = STATE_NEUTRAL;
140                 } else
141                     sb.append(c);
142                 ++i;
143                 continue;
144             }
145             if (state == STATE_SCRIPT) {
146                 if (c == '<') {
147                     if (text.regionMatches(true, i, "</script>", 0, 4)) {
148                         endToken(state);
149                         state = STATE_TAG;
150                         sb.append(text.substring(i, i+9));
151                         endToken(state);
152                         state = STATE_NEUTRAL;
153                         i += 9;
154                         continue;
155                     }
156                 }
157                 sb.append(c);
158                 ++i;
159                 continue;
160             }
161             if (state == STATE_SCRIPT_TAG) {
162                 if (c == '>') {
163                     sb.append(c);
164                     endToken(state);
165                     state = STATE_SCRIPT;
166                 } else
167                     sb.append(c);
168                 ++i;
169                 continue;
170             }
171             // Not in comment or tag.
172
if (c == '<') {
173                 endToken(state);
174                 if (text.regionMatches(i, "<!--", 0, 4)) {
175                     state = STATE_HTML_COMMENT;
176                     sb.append("<!--");
177                     i += 4;
178                     continue;
179                 }
180                 sb.append(c);
181                 state = STATE_TAG;
182             } else
183                 sb.append(c);
184             ++i;
185         }
186         endToken(state);
187     }
188
189     public boolean parseBuffer()
190     {
191         Line line = buffer.getFirstLine();
192         if (line == null)
193             return false;
194         Position pos = new Position(line, 0);
195         boolean changed = false;
196         int state = STATE_NEUTRAL;
197         while (line != null) {
198             int oldflags = line.flags();
199             if (state != oldflags) {
200                 line.setFlags(state);
201                 changed = true;
202             }
203             final int limit = line.length();
204             for (int i = 0; i < limit; i++) {
205                 char c = line.charAt(i);
206                 if (state == STATE_HTML_COMMENT) {
207                     if (c == '-') {
208                         pos.moveTo(line, i);
209                         if (pos.lookingAt("-->")) {
210                             state = STATE_NEUTRAL;
211                             i += 2;
212                             continue;
213                         }
214                     }
215                     continue;
216                 }
217                 if (state == STATE_SCRIPT_TAG) {
218                     if (c == '>') {
219                         state = STATE_SCRIPT;
220                         continue;
221                     }
222                 }
223                 if (state == STATE_TAG) {
224                     if (c == '>') {
225                         state = STATE_NEUTRAL;
226                         continue;
227                     }
228                 }
229                 if (state == STATE_SCRIPT) {
230                     if (c == '<') {
231                         pos.moveTo(line, i);
232                         if (pos.lookingAtIgnoreCase("</script>")) {
233                             state = STATE_NEUTRAL;
234                             i += 8;
235                         }
236                     } else if (c == '/' && i < limit-1) {
237                         c = line.charAt(i+1);
238                         if (c == '*') {
239                             pos.moveTo(line, i);
240                             state = STATE_COMMENT;
241                             ++i;
242                         }
243                     }
244                     continue;
245                 }
246                 if (state == STATE_COMMENT) {
247                     if (c == '*' && i < limit-1) {
248                         c = line.charAt(i+1);
249                         if (c == '/') {
250                             pos.moveTo(line, i);
251                             state = STATE_SCRIPT;
252                             ++i;
253                         }
254                     }
255                     continue;
256                 }
257                 // Neutral state.
258
if (c == '<') {
259                     pos.moveTo(line, i);
260                     if (pos.lookingAt("<!--")) {
261                         state = STATE_HTML_COMMENT;
262                         i += 3;
263                         continue;
264                     }
265                     if (pos.lookingAtIgnoreCase("<script>")) {
266                         state = STATE_SCRIPT;
267                         i += 7;
268                         continue;
269                     }
270                     if (pos.lookingAtIgnoreCase("<script ")) {
271                         state = STATE_SCRIPT_TAG;
272                         i += 7;
273                         continue;
274                     }
275                     state = STATE_TAG;
276                     continue;
277                 }
278             }
279             line = line.next();
280         }
281         buffer.setNeedsParsing(false);
282         return changed;
283     }
284
285     public FormatTable getFormatTable()
286     {
287         if (formatTable == null) {
288             formatTable = javaFormatter.getFormatTable();
289             formatTable.setModeName("HtmlMode");
290             formatTable.addEntryFromPrefs(HTML_FORMAT_TEXT, "text");
291             formatTable.addEntryFromPrefs(HTML_FORMAT_COMMENT, "comment");
292             formatTable.addEntryFromPrefs(HTML_FORMAT_TAG, "tag");
293             formatTable.addEntryFromPrefs(HTML_FORMAT_TAG_IMAGE, "image");
294             formatTable.addEntryFromPrefs(HTML_FORMAT_TAG_ANCHOR, "anchor");
295             formatTable.addEntryFromPrefs(HTML_FORMAT_TAG_TABLE, "table");
296             formatTable.addEntryFromPrefs(HTML_FORMAT_TAG_TABLE_ROW, "tableRow");
297             formatTable.addEntryFromPrefs(HTML_FORMAT_TAG_TABLE_DATA, "tableData");
298             formatTable.addEntryFromPrefs(HTML_FORMAT_SCRIPT, "script");
299         }
300         return formatTable;
301     }
302
303     public void reset()
304     {
305         javaFormatter.reset();
306         super.reset();
307     }
308 }
309
Popular Tags