Mercurial Hosting > luan
comparison src/goodjava/bbcode/BBCode.java @ 1711:05d14db623b6
add bbcodes
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 13 Jul 2022 21:50:41 -0600 |
parents | a6e27c8e7ef4 |
children | 36c28be6d432 |
comparison
equal
deleted
inserted
replaced
1710:fc224a1bb6ea | 1711:05d14db623b6 |
---|---|
47 | 47 |
48 private Object parse() { | 48 private Object parse() { |
49 List list = new ArrayList(); | 49 List list = new ArrayList(); |
50 StringBuilder text = new StringBuilder(); | 50 StringBuilder text = new StringBuilder(); |
51 while( !parser.endOfInput() ) { | 51 while( !parser.endOfInput() ) { |
52 Element block = parseBlock(); | 52 Element block = parseBlock(false); |
53 if( block != null ) { | 53 if( block != null ) { |
54 add(list,text); | 54 add(list,text); |
55 list.add( block ); | 55 list.add( block ); |
56 } else { | 56 } else { |
57 text.append( parser.currentChar() ); | 57 text.append( parser.currentChar() ); |
60 } | 60 } |
61 add(list,text); | 61 add(list,text); |
62 return list.size()==1 ? list.get(0) : list; | 62 return list.size()==1 ? list.get(0) : list; |
63 } | 63 } |
64 | 64 |
65 private Object parseWellFormed() { | 65 private Object parseUntil(String end) { |
66 return parseUntil(end,false); | |
67 } | |
68 | |
69 private Object parseUntil(String end,boolean inList) { | |
66 List list = new ArrayList(); | 70 List list = new ArrayList(); |
67 StringBuilder text = new StringBuilder(); | 71 StringBuilder text = new StringBuilder(); |
68 while( !parser.endOfInput() ) { | 72 while( !parser.matchIgnoreCase(end) ) { |
69 Element block = parseBlock(); | 73 if( parser.endOfInput() ) |
74 return null; | |
75 Element block = parseBlock(inList); | |
70 if( block != null ) { | 76 if( block != null ) { |
71 add(list,text); | 77 add(list,text); |
72 list.add( block ); | 78 list.add( block ); |
73 continue; | 79 } else { |
80 text.append( parser.currentChar() ); | |
81 parser.anyChar(); | |
74 } | 82 } |
75 if( couldBeTag() ) | |
76 break; | |
77 text.append( parser.currentChar() ); | |
78 parser.anyChar(); | |
79 } | 83 } |
80 add(list,text); | 84 add(list,text); |
81 return list.size()==1 ? list.get(0) : list; | 85 return list.size()==1 ? list.get(0) : list; |
82 } | 86 } |
83 | 87 |
86 list.add( text.toString() ); | 90 list.add( text.toString() ); |
87 text.setLength(0); | 91 text.setLength(0); |
88 } | 92 } |
89 } | 93 } |
90 | 94 |
91 private boolean couldBeTag() { | 95 private Element parseBlock(boolean inList) { |
92 if( parser.currentChar() != '[' ) | |
93 return false; | |
94 return parser.testIgnoreCase("[b]") | |
95 || parser.testIgnoreCase("[/b]") | |
96 || parser.testIgnoreCase("[i]") | |
97 || parser.testIgnoreCase("[/i]") | |
98 || parser.testIgnoreCase("[u]") | |
99 || parser.testIgnoreCase("[/u]") | |
100 || parser.testIgnoreCase("[url]") | |
101 || parser.testIgnoreCase("[url=") | |
102 || parser.testIgnoreCase("[/url]") | |
103 || parser.testIgnoreCase("[code]") | |
104 || parser.testIgnoreCase("[/code]") | |
105 || parser.testIgnoreCase("[img]") | |
106 || parser.testIgnoreCase("[/img]") | |
107 || parser.testIgnoreCase("[color=") | |
108 || parser.testIgnoreCase("[/color]") | |
109 || parser.testIgnoreCase("[size=") | |
110 || parser.testIgnoreCase("[/size]") | |
111 || parser.testIgnoreCase("[video]") | |
112 || parser.testIgnoreCase("[/video]") | |
113 || parser.testIgnoreCase("[quote]") | |
114 || parser.testIgnoreCase("[quote=") | |
115 || parser.testIgnoreCase("[/quote]") | |
116 ; | |
117 } | |
118 | |
119 private Element parseBlock() { | |
120 if( parser.currentChar() != '[' ) | 96 if( parser.currentChar() != '[' ) |
121 return null; | 97 return null; |
122 Element s; | 98 Element s; |
123 s = parseB(); if(s!=null) return s; | 99 s = parseB(); if(s!=null) return s; |
124 s = parseI(); if(s!=null) return s; | 100 s = parseI(); if(s!=null) return s; |
125 s = parseU(); if(s!=null) return s; | 101 s = parseU(); if(s!=null) return s; |
126 s = parseUrl1(); if(s!=null) return s; | 102 s = parseS(); if(s!=null) return s; |
127 s = parseUrl2(); if(s!=null) return s; | 103 s = parseSup(); if(s!=null) return s; |
104 s = parseBrackets(); if(s!=null) return s; | |
105 s = parseUrl(); if(s!=null) return s; | |
128 s = parseCode(); if(s!=null) return s; | 106 s = parseCode(); if(s!=null) return s; |
129 s = parseImg(); if(s!=null) return s; | 107 s = parseImg(); if(s!=null) return s; |
130 s = parseColor(); if(s!=null) return s; | 108 s = parseColor(); if(s!=null) return s; |
131 s = parseSize(); if(s!=null) return s; | 109 s = parseSize(); if(s!=null) return s; |
132 s = parseVideo(); if(s!=null) return s; | 110 s = parseVideo(); if(s!=null) return s; |
133 s = parseQuote1(); if(s!=null) return s; | 111 s = parseQuote(); if(s!=null) return s; |
134 s = parseQuote2(); if(s!=null) return s; | 112 s = parseUl(); if(s!=null) return s; |
113 s = parseOl(); if(s!=null) return s; | |
114 if( inList ) { | |
115 s = parseLi(); if(s!=null) return s; | |
116 } | |
135 return null; | 117 return null; |
136 } | 118 } |
137 | 119 |
138 private Element parseB() { | 120 private Element parseB() { |
139 parser.begin(); | 121 parser.begin(); |
140 if( !parser.matchIgnoreCase("[b]") ) | 122 if( !parser.matchIgnoreCase("[b]") ) |
141 return parser.failure(null); | 123 return parser.failure(null); |
142 Object content = parseWellFormed(); | 124 Object content = parseUntil("[/b]"); |
143 if( !parser.matchIgnoreCase("[/b]") ) | 125 if( content==null ) |
144 return parser.failure(null); | 126 return parser.failure(null); |
145 Element rtn = new Element("b",content); | 127 Element rtn = new Element("b",content); |
146 return parser.success(rtn); | 128 return parser.success(rtn); |
147 } | 129 } |
148 | 130 |
149 private Element parseI() { | 131 private Element parseI() { |
150 parser.begin(); | 132 parser.begin(); |
151 if( !parser.matchIgnoreCase("[i]") ) | 133 if( !parser.matchIgnoreCase("[i]") ) |
152 return parser.failure(null); | 134 return parser.failure(null); |
153 Object content = parseWellFormed(); | 135 Object content = parseUntil("[/i]"); |
154 if( !parser.matchIgnoreCase("[/i]") ) | 136 if( content==null ) |
155 return parser.failure(null); | 137 return parser.failure(null); |
156 Element rtn = new Element("i",content); | 138 Element rtn = new Element("i",content); |
157 return parser.success(rtn); | 139 return parser.success(rtn); |
158 } | 140 } |
159 | 141 |
160 private Element parseU() { | 142 private Element parseU() { |
161 parser.begin(); | 143 parser.begin(); |
162 if( !parser.matchIgnoreCase("[u]") ) | 144 if( !parser.matchIgnoreCase("[u]") ) |
163 return parser.failure(null); | 145 return parser.failure(null); |
164 Object content = parseWellFormed(); | 146 Object content = parseUntil("[/u]"); |
165 if( !parser.matchIgnoreCase("[/u]") ) | 147 if( content==null ) |
166 return parser.failure(null); | 148 return parser.failure(null); |
167 Element rtn = new Element("u",content); | 149 Element rtn = new Element("u",content); |
168 return parser.success(rtn); | 150 return parser.success(rtn); |
169 } | 151 } |
170 | 152 |
171 private Element parseUrl1() { | 153 private Element parseS() { |
172 parser.begin(); | 154 parser.begin(); |
173 if( !parser.matchIgnoreCase("[url]") ) | 155 if( !parser.matchIgnoreCase("[s]") ) |
174 return parser.failure(null); | 156 return parser.failure(null); |
175 String url = parseRealUrl(); | 157 Object content = parseUntil("[/s]"); |
176 if( !parser.matchIgnoreCase("[/url]") ) | 158 if( content==null ) |
177 return parser.failure(null); | 159 return parser.failure(null); |
178 Element rtn = new Element("url",url); | 160 Element rtn = new Element("s",content); |
179 return parser.success(rtn); | 161 return parser.success(rtn); |
180 } | 162 } |
181 | 163 |
182 private Element parseUrl2() { | 164 private Element parseSup() { |
183 parser.begin(); | 165 parser.begin(); |
184 if( !parser.matchIgnoreCase("[url=") ) | 166 if( !parser.matchIgnoreCase("[sup]") ) |
185 return parser.failure(null); | 167 return parser.failure(null); |
186 String url = parseRealUrl(); | 168 Object content = parseUntil("[/sup]"); |
187 if( !parser.match(']') ) | 169 if( content==null ) |
188 return parser.failure(null); | 170 return parser.failure(null); |
189 Object content = parseWellFormed(); | 171 Element rtn = new Element("sup",content); |
190 if( !parser.matchIgnoreCase("[/url]") ) | 172 return parser.success(rtn); |
173 } | |
174 | |
175 private Element parseBrackets() { | |
176 parser.begin(); | |
177 if( !parser.matchIgnoreCase("[brackets]") ) | |
178 return parser.failure(null); | |
179 Object content = parseUntil("[/brackets]"); | |
180 if( content==null ) | |
181 return parser.failure(null); | |
182 Element rtn = new Element("brackets",content); | |
183 return parser.success(rtn); | |
184 } | |
185 | |
186 private Element parseUrl() { | |
187 parser.begin(); | |
188 if( !parser.matchIgnoreCase("[url") ) | |
189 return parser.failure(null); | |
190 String url; | |
191 Object content; | |
192 if( parser.match(']') ) { | |
193 url = parseRealUrl(); | |
194 content = null; | |
195 if( !parser.matchIgnoreCase("[/url]") ) | |
196 return parser.failure(null); | |
197 } else if( parser.match('=') ) { | |
198 url = parseRealUrl(); | |
199 if( !parser.match(']') ) | |
200 return parser.failure(null); | |
201 content = parseUntil("[/url]"); | |
202 if( content==null ) | |
203 return parser.failure(null); | |
204 } else | |
191 return parser.failure(null); | 205 return parser.failure(null); |
192 Element rtn = new Element("url",url,content); | 206 Element rtn = new Element("url",url,content); |
193 return parser.success(rtn); | 207 return parser.success(rtn); |
194 } | 208 } |
195 | 209 |
208 return parser.success(url); | 222 return parser.success(url); |
209 } | 223 } |
210 | 224 |
211 private Element parseCode() { | 225 private Element parseCode() { |
212 parser.begin(); | 226 parser.begin(); |
213 if( !parser.matchIgnoreCase("[code]") ) | 227 String param; |
228 String end; | |
229 if( !parser.matchIgnoreCase("[code") ) | |
230 return parser.failure(null); | |
231 if( parser.match(']') ) { | |
232 param = null; | |
233 end = "[/code]"; | |
234 } else if( parser.match('=') ) { | |
235 int start = parser.currentIndex(); | |
236 while( parser.noneOf("[]") ); | |
237 param = parser.textFrom(start); | |
238 if( !parser.match(']') ) | |
239 return parser.failure(null); | |
240 end = "[/code=" + param + "]"; | |
241 } else | |
214 return parser.failure(null); | 242 return parser.failure(null); |
215 int start = parser.currentIndex(); | 243 int start = parser.currentIndex(); |
216 while( !parser.testIgnoreCase("[/code]") ) { | 244 while( !parser.testIgnoreCase(end) ) { |
217 if( !parser.anyChar() ) | 245 if( !parser.anyChar() ) |
218 return parser.failure(null); | 246 return parser.failure(null); |
219 } | 247 } |
220 String content = parser.textFrom(start); | 248 String content = parser.textFrom(start); |
221 if( !parser.matchIgnoreCase("[/code]") ) throw new RuntimeException(); | 249 if( !parser.matchIgnoreCase(end) ) throw new RuntimeException(); |
222 Element rtn = new Element("code",content); | 250 Element rtn = new Element("code",param,content); |
223 return parser.success(rtn); | 251 return parser.success(rtn); |
224 } | 252 } |
225 | 253 |
226 private Element parseImg() { | 254 private Element parseImg() { |
227 parser.begin(); | 255 parser.begin(); |
245 || parser.inCharRange('A','Z') | 273 || parser.inCharRange('A','Z') |
246 ); | 274 ); |
247 String color = parser.textFrom(start); | 275 String color = parser.textFrom(start); |
248 if( !parser.match(']') ) | 276 if( !parser.match(']') ) |
249 return parser.failure(null); | 277 return parser.failure(null); |
250 Object content = parseWellFormed(); | 278 Object content = parseUntil("[/color]"); |
251 if( !parser.matchIgnoreCase("[/color]") ) | 279 if( content==null ) |
252 return parser.failure(null); | 280 return parser.failure(null); |
253 Element rtn = new Element("color",color,content); | 281 Element rtn = new Element("color",color,content); |
254 return parser.success(rtn); | 282 return parser.success(rtn); |
255 } | 283 } |
256 | 284 |
261 int start = parser.currentIndex(); | 289 int start = parser.currentIndex(); |
262 while( parser.match('.') || parser.inCharRange('0','9') ); | 290 while( parser.match('.') || parser.inCharRange('0','9') ); |
263 String size = parser.textFrom(start); | 291 String size = parser.textFrom(start); |
264 if( !parser.match(']') ) | 292 if( !parser.match(']') ) |
265 return parser.failure(null); | 293 return parser.failure(null); |
266 Object content = parseWellFormed(); | 294 Object content = parseUntil("[/size]"); |
267 if( !parser.matchIgnoreCase("[/size]") ) | 295 if( content==null ) |
268 return parser.failure(null); | 296 return parser.failure(null); |
269 Element rtn = new Element("size",size,content); | 297 Element rtn = new Element("size",size,content); |
270 return parser.success(rtn); | 298 return parser.success(rtn); |
271 } | 299 } |
272 | 300 |
308 } | 336 } |
309 return parser.success(rtn); | 337 return parser.success(rtn); |
310 } | 338 } |
311 | 339 |
312 | 340 |
313 private Element parseQuote1() { | 341 private Element parseQuote() { |
314 parser.begin(); | 342 parser.begin(); |
315 if( !parser.matchIgnoreCase("[quote]") ) | 343 if( !parser.matchIgnoreCase("[quote") ) |
316 return parser.failure(null); | 344 return parser.failure(null); |
317 Object content = parseWellFormed(); | 345 String name; |
318 if( !parser.matchIgnoreCase("[/quote]") ) | 346 if( parser.match(']') ) { |
319 return parser.failure(null); | 347 name = null; |
320 Element rtn = new Element("quote",content); | 348 } else if( parser.match('=') ) { |
321 return parser.success(rtn); | 349 int start = parser.currentIndex(); |
322 } | 350 while( parser.noneOf("[]") ); |
323 | 351 name = parser.textFrom(start).trim(); |
324 private Element parseQuote2() { | 352 if( !parser.match(']') ) |
325 parser.begin(); | 353 return parser.failure(null); |
326 if( !parser.matchIgnoreCase("[quote=") ) | 354 } else |
327 return parser.failure(null); | 355 return parser.failure(null); |
328 List args = new ArrayList(); | 356 Object content = parseUntil("[/quote]"); |
329 int start = parser.currentIndex(); | 357 if( content==null ) |
330 while( parser.noneOf("[]") ); | |
331 String name = parser.textFrom(start).trim(); | |
332 if( !parser.match(']') ) | |
333 return parser.failure(null); | |
334 Object content = parseWellFormed(); | |
335 if( !parser.matchIgnoreCase("[/quote]") ) | |
336 return parser.failure(null); | 358 return parser.failure(null); |
337 Element rtn = new Element("quote",name,content); | 359 Element rtn = new Element("quote",name,content); |
338 return parser.success(rtn); | 360 return parser.success(rtn); |
339 } | 361 } |
340 | 362 |
363 | |
364 private Element parseUl() { | |
365 parser.begin(); | |
366 if( !parser.matchIgnoreCase("[ul]") ) | |
367 return parser.failure(null); | |
368 Object content = parseUntil("[/ul]",true); | |
369 if( content==null ) | |
370 return parser.failure(null); | |
371 Element rtn = new Element("ul",content); | |
372 return parser.success(rtn); | |
373 } | |
374 | |
375 private Element parseOl() { | |
376 parser.begin(); | |
377 if( !parser.matchIgnoreCase("[ol]") ) | |
378 return parser.failure(null); | |
379 Object content = parseUntil("[/ol]",true); | |
380 if( content==null ) | |
381 return parser.failure(null); | |
382 Element rtn = new Element("ol",content); | |
383 return parser.success(rtn); | |
384 } | |
385 | |
386 private Element parseLi() { | |
387 parser.begin(); | |
388 if( !parser.matchIgnoreCase("[li]") ) | |
389 return parser.failure(null); | |
390 Object content = parseUntil("[/li]"); | |
391 if( content==null ) | |
392 return parser.failure(null); | |
393 Element rtn = new Element("li",content); | |
394 return parser.success(rtn); | |
395 } | |
396 | |
341 } | 397 } |