Mercurial Hosting > luan
comparison core/src/luan/modules/parsers/BBCode.java @ 637:6ea90dc10375
bbcode parser now takes a quoter function
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 03 Mar 2016 12:38:24 -0700 |
parents | 5fdbefa80146 |
children | 3ab4f282f0bd |
comparison
equal
deleted
inserted
replaced
636:13b390bfed32 | 637:6ea90dc10375 |
---|---|
1 package luan.modules.parsers; | 1 package luan.modules.parsers; |
2 | 2 |
3 import java.util.List; | |
4 import java.util.ArrayList; | |
5 import luan.Luan; | |
6 import luan.LuanState; | |
7 import luan.LuanFunction; | |
8 import luan.LuanException; | |
9 import luan.modules.Utils; | |
10 | |
3 | 11 |
4 public final class BBCode { | 12 public final class BBCode { |
5 | 13 |
6 public static String toHtml(String bbcode) { | 14 public static String toHtml(LuanState luan,String bbcode,LuanFunction quoter) throws LuanException { |
7 return new BBCode(bbcode,true).parse(); | 15 return new BBCode(luan,bbcode,true,quoter).parse(); |
8 } | 16 } |
9 | 17 |
10 public static String toText(String bbcode) { | 18 public static String toText(LuanState luan,String bbcode,LuanFunction quoter) throws LuanException { |
11 return new BBCode(bbcode,false).parse(); | 19 return new BBCode(luan,bbcode,false,quoter).parse(); |
12 } | 20 } |
13 | 21 |
22 private final LuanState luan; | |
14 private final Parser parser; | 23 private final Parser parser; |
15 private final boolean toHtml; | 24 private final boolean toHtml; |
16 | 25 private final LuanFunction quoter; |
17 private BBCode(String text,boolean toHtml) { | 26 |
27 private BBCode(LuanState luan,String text,boolean toHtml,LuanFunction quoter) throws LuanException { | |
28 Utils.checkNotNull(luan,text,1); | |
29 Utils.checkNotNull(luan,quoter,3); | |
30 this.luan = luan; | |
18 this.parser = new Parser(text); | 31 this.parser = new Parser(text); |
19 this.toHtml = toHtml; | 32 this.toHtml = toHtml; |
20 } | 33 this.quoter = quoter; |
21 | 34 } |
22 private String parse() { | 35 |
36 private String parse() throws LuanException { | |
23 StringBuilder sb = new StringBuilder(); | 37 StringBuilder sb = new StringBuilder(); |
24 while( !parser.endOfInput() ) { | 38 while( !parser.endOfInput() ) { |
25 String block = parseBlock(); | 39 String block = parseBlock(); |
26 if( block != null ) | 40 if( block != null ) |
27 sb.append(block); | 41 sb.append(block); |
31 } | 45 } |
32 } | 46 } |
33 return sb.toString(); | 47 return sb.toString(); |
34 } | 48 } |
35 | 49 |
36 private String parseWellFormed() { | 50 private String parseWellFormed() throws LuanException { |
37 StringBuilder sb = new StringBuilder(); | 51 StringBuilder sb = new StringBuilder(); |
38 while( !parser.endOfInput() ) { | 52 while( !parser.endOfInput() ) { |
39 String block = parseBlock(); | 53 String block = parseBlock(); |
40 if( block != null ) { | 54 if( block != null ) { |
41 sb.append(block); | 55 sb.append(block); |
75 || parser.testIgnoreCase("[quote=") | 89 || parser.testIgnoreCase("[quote=") |
76 || parser.testIgnoreCase("[/quote]") | 90 || parser.testIgnoreCase("[/quote]") |
77 ; | 91 ; |
78 } | 92 } |
79 | 93 |
80 private String parseBlock() { | 94 private String parseBlock() throws LuanException { |
81 if( parser.currentChar() != '[' ) | 95 if( parser.currentChar() != '[' ) |
82 return null; | 96 return null; |
83 String s; | 97 String s; |
84 s = parseB(); if(s!=null) return s; | 98 s = parseB(); if(s!=null) return s; |
85 s = parseI(); if(s!=null) return s; | 99 s = parseI(); if(s!=null) return s; |
94 s = parseQuote1(); if(s!=null) return s; | 108 s = parseQuote1(); if(s!=null) return s; |
95 s = parseQuote2(); if(s!=null) return s; | 109 s = parseQuote2(); if(s!=null) return s; |
96 return null; | 110 return null; |
97 } | 111 } |
98 | 112 |
99 private String parseB() { | 113 private String parseB() throws LuanException { |
100 parser.begin(); | 114 parser.begin(); |
101 if( !parser.matchIgnoreCase("[b]") ) | 115 if( !parser.matchIgnoreCase("[b]") ) |
102 return parser.failure(null); | 116 return parser.failure(null); |
103 String content = parseWellFormed(); | 117 String content = parseWellFormed(); |
104 if( !parser.matchIgnoreCase("[/b]") ) | 118 if( !parser.matchIgnoreCase("[/b]") ) |
105 return parser.failure(null); | 119 return parser.failure(null); |
106 String rtn = toHtml ? "<b>"+content+"</b>" : content; | 120 String rtn = toHtml ? "<b>"+content+"</b>" : content; |
107 return parser.success(rtn); | 121 return parser.success(rtn); |
108 } | 122 } |
109 | 123 |
110 private String parseI() { | 124 private String parseI() throws LuanException { |
111 parser.begin(); | 125 parser.begin(); |
112 if( !parser.matchIgnoreCase("[i]") ) | 126 if( !parser.matchIgnoreCase("[i]") ) |
113 return parser.failure(null); | 127 return parser.failure(null); |
114 String content = parseWellFormed(); | 128 String content = parseWellFormed(); |
115 if( !parser.matchIgnoreCase("[/i]") ) | 129 if( !parser.matchIgnoreCase("[/i]") ) |
116 return parser.failure(null); | 130 return parser.failure(null); |
117 String rtn = toHtml ? "<i>"+content+"</i>" : content; | 131 String rtn = toHtml ? "<i>"+content+"</i>" : content; |
118 return parser.success(rtn); | 132 return parser.success(rtn); |
119 } | 133 } |
120 | 134 |
121 private String parseU() { | 135 private String parseU() throws LuanException { |
122 parser.begin(); | 136 parser.begin(); |
123 if( !parser.matchIgnoreCase("[u]") ) | 137 if( !parser.matchIgnoreCase("[u]") ) |
124 return parser.failure(null); | 138 return parser.failure(null); |
125 String content = parseWellFormed(); | 139 String content = parseWellFormed(); |
126 if( !parser.matchIgnoreCase("[/u]") ) | 140 if( !parser.matchIgnoreCase("[/u]") ) |
138 return parser.failure(null); | 152 return parser.failure(null); |
139 String rtn = toHtml ? "<a href='"+url+"'>"+url+"</u>" : url; | 153 String rtn = toHtml ? "<a href='"+url+"'>"+url+"</u>" : url; |
140 return parser.success(rtn); | 154 return parser.success(rtn); |
141 } | 155 } |
142 | 156 |
143 private String parseUrl2() { | 157 private String parseUrl2() throws LuanException { |
144 parser.begin(); | 158 parser.begin(); |
145 if( !parser.matchIgnoreCase("[url=") ) | 159 if( !parser.matchIgnoreCase("[url=") ) |
146 return parser.failure(null); | 160 return parser.failure(null); |
147 String url = parseRealUrl(); | 161 String url = parseRealUrl(); |
148 if( !parser.match(']') ) | 162 if( !parser.match(']') ) |
193 return parser.failure(null); | 207 return parser.failure(null); |
194 String rtn = toHtml ? "<img src='"+url+"'>" : ""; | 208 String rtn = toHtml ? "<img src='"+url+"'>" : ""; |
195 return parser.success(rtn); | 209 return parser.success(rtn); |
196 } | 210 } |
197 | 211 |
198 private String parseColor() { | 212 private String parseColor() throws LuanException { |
199 parser.begin(); | 213 parser.begin(); |
200 if( !parser.matchIgnoreCase("[color=") ) | 214 if( !parser.matchIgnoreCase("[color=") ) |
201 return parser.failure(null); | 215 return parser.failure(null); |
202 int start = parser.currentIndex(); | 216 int start = parser.currentIndex(); |
203 parser.match('#'); | 217 parser.match('#'); |
213 return parser.failure(null); | 227 return parser.failure(null); |
214 String rtn = toHtml ? "<span style='color: "+color+"'>"+content+"</span>" : content; | 228 String rtn = toHtml ? "<span style='color: "+color+"'>"+content+"</span>" : content; |
215 return parser.success(rtn); | 229 return parser.success(rtn); |
216 } | 230 } |
217 | 231 |
218 private String parseSize() { | 232 private String parseSize() throws LuanException { |
219 parser.begin(); | 233 parser.begin(); |
220 if( !parser.matchIgnoreCase("[size=") ) | 234 if( !parser.matchIgnoreCase("[size=") ) |
221 return parser.failure(null); | 235 return parser.failure(null); |
222 int start = parser.currentIndex(); | 236 int start = parser.currentIndex(); |
223 while( parser.match('.') || parser.inCharRange('0','9') ); | 237 while( parser.match('.') || parser.inCharRange('0','9') ); |
247 return parser.failure(null); | 261 return parser.failure(null); |
248 String rtn = toHtml ? "<iframe width='420' height='315' src='https://www.youtube.com/embed/"+id+"' frameborder='0' allowfullscreen></iframe>" : ""; | 262 String rtn = toHtml ? "<iframe width='420' height='315' src='https://www.youtube.com/embed/"+id+"' frameborder='0' allowfullscreen></iframe>" : ""; |
249 return parser.success(rtn); | 263 return parser.success(rtn); |
250 } | 264 } |
251 | 265 |
252 private String parseQuote1() { | 266 private String quote(Object... args) throws LuanException { |
267 Object obj = quoter.call(luan,args); | |
268 if( !(obj instanceof String) ) | |
269 throw new LuanException(luan,"BBCode quoter function returned "+Luan.type(obj)+" but string required"); | |
270 return (String)obj; | |
271 } | |
272 | |
273 private String parseQuote1() throws LuanException { | |
253 parser.begin(); | 274 parser.begin(); |
254 if( !parser.matchIgnoreCase("[quote]") ) | 275 if( !parser.matchIgnoreCase("[quote]") ) |
255 return parser.failure(null); | 276 return parser.failure(null); |
256 String content = parseWellFormed(); | 277 String content = parseWellFormed(); |
257 if( !parser.matchIgnoreCase("[/quote]") ) | 278 if( !parser.matchIgnoreCase("[/quote]") ) |
258 return parser.failure(null); | 279 return parser.failure(null); |
259 String rtn = toHtml ? "<blockquote>"+content+"</blockquote>" : ""; | 280 String rtn = quote(content); |
260 return parser.success(rtn); | 281 return parser.success(rtn); |
261 } | 282 } |
262 | 283 |
263 private String parseQuote2() { | 284 private String parseQuote2() throws LuanException { |
264 parser.begin(); | 285 parser.begin(); |
265 if( !parser.matchIgnoreCase("[quote=") ) | 286 if( !parser.matchIgnoreCase("[quote=") ) |
266 return parser.failure(null); | 287 return parser.failure(null); |
288 List args = new ArrayList(); | |
267 int start = parser.currentIndex(); | 289 int start = parser.currentIndex(); |
268 while( parser.noneOf("[];") ); | 290 while( parser.noneOf("[];") ); |
269 String name = parser.textFrom(start).trim(); | 291 String name = parser.textFrom(start).trim(); |
270 if( name.length() == 0 ) | 292 if( name.length() == 0 ) |
271 return parser.failure(null); | 293 return parser.failure(null); |
272 String src = null; | 294 args.add(name); |
273 if( parser.match(';') ) { | 295 while( parser.match(';') ) { |
274 start = parser.currentIndex(); | 296 start = parser.currentIndex(); |
275 while( parser.noneOf("[]'") ); | 297 while( parser.noneOf("[];'") ); |
276 src = parser.textFrom(start).trim(); | 298 String src = parser.textFrom(start).trim(); |
277 if( src.length() == 0 ) | 299 args.add(src); |
278 return parser.failure(null); | |
279 } | 300 } |
280 if( !parser.match(']') ) | 301 if( !parser.match(']') ) |
281 return parser.failure(null); | 302 return parser.failure(null); |
282 String content = parseWellFormed(); | 303 String content = parseWellFormed(); |
304 args.add(0,content); | |
283 if( !parser.matchIgnoreCase("[/quote]") ) | 305 if( !parser.matchIgnoreCase("[/quote]") ) |
284 return parser.failure(null); | 306 return parser.failure(null); |
285 if( !toHtml ) | 307 String rtn = quote(args.toArray()); |
286 return parser.success(""); | 308 return parser.success(rtn); |
287 StringBuilder sb = new StringBuilder(); | |
288 sb.append( "<blockquote><div quoted>" ); | |
289 if( src != null ) | |
290 sb.append( "<a href='/thread?id=" ).append( src ).append( "'>" ); | |
291 sb.append( "<span quoted>" ).append( name ).append( "</span>" ); | |
292 if( src != null ) | |
293 sb.append( "</a>" ); | |
294 sb.append( "</div>" ).append( content ).append( "</blockquote>" ); | |
295 return parser.success(sb.toString()); | |
296 } | 309 } |
297 | 310 |
298 } | 311 } |