Mercurial Hosting > luan
diff src/goodjava/bbcode/BBCode.java @ 1705:a6e27c8e7ef4
bbcode now returns data
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 03 Jul 2022 21:59:38 -0600 |
parents | 3a61451f8130 |
children | 05d14db623b6 |
line wrap: on
line diff
--- a/src/goodjava/bbcode/BBCode.java Fri Jul 01 15:53:03 2022 -0600 +++ b/src/goodjava/bbcode/BBCode.java Sun Jul 03 21:59:38 2022 -0600 @@ -2,6 +2,8 @@ import java.util.List; import java.util.ArrayList; +import java.util.Map; +import java.util.LinkedHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import goodjava.parser.Parser; @@ -9,59 +11,65 @@ public final class BBCode { - public enum Target { HTML, TEXT } + public final class Element { + public final String name; + public final String param; + public final Object contents; // String, Element, or List + public final Map<String,String> extra; + + private Element(String name,Object contents) { + this(name,null,contents); + } - public interface Quoter { - public String quote(Target target,String text,String param); + private Element(String name,String param,Object contents) { + this(name,param,contents,null); + } + + private Element(String name,String param,Object contents,Map<String,String> extra) { + this.name = name.toLowerCase(); + this.param = param; + this.contents = contents; + this.extra = extra; + } } - public static final Quoter defaultQuoter = new Quoter() { - public String quote(Target target,String text,String param) { - StringBuilder sb = new StringBuilder(); - sb.append( "<blockquote>" ); - if( param != null ) { - sb.append( htmlEncode(param) ); - sb.append( " wrote:\n" ); - } - sb.append( text ); - sb.append( "</blockquote>" ); - return sb.toString(); - } - }; + public static Object parse(String text) { + if( text.indexOf('[') == -1 ) + return text; + return new BBCode(text).parse(); + } - public Target target = Target.HTML; - public Quoter quoter = defaultQuoter; private final Parser parser; - public BBCode(String text) { + private BBCode(String text) { this.parser = new Parser(text); } - public String parse() { - StringBuilder sb = new StringBuilder(); + private Object parse() { + List list = new ArrayList(); StringBuilder text = new StringBuilder(); while( !parser.endOfInput() ) { - String block = parseBlock(); + Element block = parseBlock(); if( block != null ) { - sb.append( textToString(text) ); - sb.append(block); + add(list,text); + list.add( block ); } else { text.append( parser.currentChar() ); parser.anyChar(); } } - sb.append( textToString(text) ); - return sb.toString(); + add(list,text); + return list.size()==1 ? list.get(0) : list; } - private String parseWellFormed() { - StringBuilder sb = new StringBuilder(); + private Object parseWellFormed() { + List list = new ArrayList(); StringBuilder text = new StringBuilder(); while( !parser.endOfInput() ) { - String block = parseBlock(); + Element block = parseBlock(); if( block != null ) { - sb.append( textToString(text) ); - sb.append(block); + add(list,text); + list.add( block ); continue; } if( couldBeTag() ) @@ -69,16 +77,15 @@ text.append( parser.currentChar() ); parser.anyChar(); } - sb.append( textToString(text) ); - return sb.toString(); + add(list,text); + return list.size()==1 ? list.get(0) : list; } - private String textToString(StringBuilder text) { - String s = text.toString(); - text.setLength(0); - if( target == Target.HTML ) - s = htmlEncode(s); - return s; + private void add(List list,StringBuilder text) { + if( text.length() > 0 ) { + list.add( text.toString() ); + text.setLength(0); + } } private boolean couldBeTag() { @@ -109,10 +116,10 @@ ; } - private String parseBlock() { + private Element parseBlock() { if( parser.currentChar() != '[' ) return null; - String s; + Element s; s = parseB(); if(s!=null) return s; s = parseI(); if(s!=null) return s; s = parseU(); if(s!=null) return s; @@ -128,61 +135,61 @@ return null; } - private String parseB() { + private Element parseB() { parser.begin(); if( !parser.matchIgnoreCase("[b]") ) return parser.failure(null); - String content = parseWellFormed(); + Object content = parseWellFormed(); if( !parser.matchIgnoreCase("[/b]") ) return parser.failure(null); - String rtn = target==Target.HTML ? "<b>"+content+"</b>" : content; + Element rtn = new Element("b",content); return parser.success(rtn); } - private String parseI() { + private Element parseI() { parser.begin(); if( !parser.matchIgnoreCase("[i]") ) return parser.failure(null); - String content = parseWellFormed(); + Object content = parseWellFormed(); if( !parser.matchIgnoreCase("[/i]") ) return parser.failure(null); - String rtn = target==Target.HTML ? "<i>"+content+"</i>" : content; + Element rtn = new Element("i",content); return parser.success(rtn); } - private String parseU() { + private Element parseU() { parser.begin(); if( !parser.matchIgnoreCase("[u]") ) return parser.failure(null); - String content = parseWellFormed(); + Object content = parseWellFormed(); if( !parser.matchIgnoreCase("[/u]") ) return parser.failure(null); - String rtn = target==Target.HTML ? "<u>"+content+"</u>" : content; + Element rtn = new Element("u",content); return parser.success(rtn); } - private String parseUrl1() { + private Element parseUrl1() { parser.begin(); if( !parser.matchIgnoreCase("[url]") ) return parser.failure(null); String url = parseRealUrl(); if( !parser.matchIgnoreCase("[/url]") ) return parser.failure(null); - String rtn = target==Target.HTML ? "<a href='" + url + "'>" + url + "</a>" : url; + Element rtn = new Element("url",url); return parser.success(rtn); } - private String parseUrl2() { + private Element parseUrl2() { parser.begin(); if( !parser.matchIgnoreCase("[url=") ) return parser.failure(null); String url = parseRealUrl(); if( !parser.match(']') ) return parser.failure(null); - String content = parseWellFormed(); + Object content = parseWellFormed(); if( !parser.matchIgnoreCase("[/url]") ) return parser.failure(null); - String rtn = target==Target.HTML ? "<a href='" + url + "'>" + content + "</a>" : content; + Element rtn = new Element("url",url,content); return parser.success(rtn); } @@ -201,7 +208,7 @@ return parser.success(url); } - private String parseCode() { + private Element parseCode() { parser.begin(); if( !parser.matchIgnoreCase("[code]") ) return parser.failure(null); @@ -212,22 +219,22 @@ } String content = parser.textFrom(start); if( !parser.matchIgnoreCase("[/code]") ) throw new RuntimeException(); - String rtn = target==Target.HTML ? "<code>"+content+"</code>" : content; + Element rtn = new Element("code",content); return parser.success(rtn); } - private String parseImg() { + private Element parseImg() { parser.begin(); if( !parser.matchIgnoreCase("[img]") ) return parser.failure(null); String url = parseRealUrl(); if( !parser.matchIgnoreCase("[/img]") ) return parser.failure(null); - String rtn = target==Target.HTML ? "<img src='" + url + "'>" : ""; + Element rtn = new Element("img",url); return parser.success(rtn); } - private String parseColor() { + private Element parseColor() { parser.begin(); if( !parser.matchIgnoreCase("[color=") ) return parser.failure(null); @@ -240,14 +247,14 @@ String color = parser.textFrom(start); if( !parser.match(']') ) return parser.failure(null); - String content = parseWellFormed(); + Object content = parseWellFormed(); if( !parser.matchIgnoreCase("[/color]") ) return parser.failure(null); - String rtn = target==Target.HTML ? "<span style='color: "+color+"'>"+content+"</span>" : content; + Element rtn = new Element("color",color,content); return parser.success(rtn); } - private String parseSize() { + private Element parseSize() { parser.begin(); if( !parser.matchIgnoreCase("[size=") ) return parser.failure(null); @@ -256,10 +263,10 @@ String size = parser.textFrom(start); if( !parser.match(']') ) return parser.failure(null); - String content = parseWellFormed(); + Object content = parseWellFormed(); if( !parser.matchIgnoreCase("[/size]") ) return parser.failure(null); - String rtn = target==Target.HTML ? "<span style='font-size: "+size+"em'>"+content+"</span>" : content; + Element rtn = new Element("size",size,content); return parser.success(rtn); } @@ -272,55 +279,49 @@ return m.find() ? m : null; } - private String parseVideo() { + private Element parseVideo() { parser.begin(); if( !parser.matchIgnoreCase("[video]") ) return parser.failure(null); String url = parseRealUrl(); if( !parser.matchIgnoreCase("[/video]") ) return parser.failure(null); - if( target==Target.TEXT ) - return parser.success( "" ); + Map<String,String> extra = new LinkedHashMap<String,String>(); + Element rtn = new Element("video",null,url,extra); Matcher m; m = find(youtubePtn1,url); if( m == null ) m = find(youtubePtn2,url); if( m != null ) { - StringBuilder sb = new StringBuilder(); - sb.append( "<iframe width='420' height='315' src='https://www.youtube.com/embed/" ); - sb.append( m.group(1) ); + extra.put( "site", "youtube" ); + extra.put( "id", m.group(1) ); String t = m.group(2); - if( t != null ) { - sb.append( "?start=" ); - sb.append( t ); - } - sb.append( "' frameborder='0' allowfullscreen></iframe>" ); - return parser.success( sb.toString() ); + if( t != null ) + extra.put( "start", t ); + return parser.success(rtn); } m = find(bitchutePtn,url); if( m != null ) { - StringBuilder sb = new StringBuilder(); - sb.append( "<iframe width='420' height='315' scrolling='no' frameborder='0' style='border: none;' src='https://www.bitchute.com/embed/" ); - sb.append( m.group(1) ); - sb.append( "/'></iframe>" ); - return parser.success( sb.toString() ); + extra.put( "site", "bitchute" ); + extra.put( "id", m.group(1) ); + return parser.success(rtn); } - return parser.success( "<a href='" + url + "'>" + url + "</a>" ); + return parser.success(rtn); } - private String parseQuote1() { + private Element parseQuote1() { parser.begin(); if( !parser.matchIgnoreCase("[quote]") ) return parser.failure(null); - String content = parseWellFormed(); + Object content = parseWellFormed(); if( !parser.matchIgnoreCase("[/quote]") ) return parser.failure(null); - String rtn = quoter.quote(target,content,null); + Element rtn = new Element("quote",content); return parser.success(rtn); } - private String parseQuote2() { + private Element parseQuote2() { parser.begin(); if( !parser.matchIgnoreCase("[quote=") ) return parser.failure(null); @@ -330,35 +331,11 @@ String name = parser.textFrom(start).trim(); if( !parser.match(']') ) return parser.failure(null); - String content = parseWellFormed(); + Object content = parseWellFormed(); if( !parser.matchIgnoreCase("[/quote]") ) return parser.failure(null); - String rtn = quoter.quote(target,content,name); + Element rtn = new Element("quote",name,content); return parser.success(rtn); } - public static String htmlEncode(String s) { - final char[] a = s.toCharArray(); - StringBuilder buf = new StringBuilder(); - for( char c : a ) { - switch(c) { - case '&': - buf.append("&"); - break; - case '<': - buf.append("<"); - break; - case '>': - buf.append(">"); - break; - case '"': - buf.append("""); - break; - default: - buf.append(c); - } - } - return buf.toString(); - } - }