changeset 1711:05d14db623b6

add bbcodes
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 13 Jul 2022 21:50:41 -0600
parents fc224a1bb6ea
children 36c28be6d432
files src/goodjava/bbcode/BBCode.java
diffstat 1 files changed, 144 insertions(+), 88 deletions(-) [+]
line wrap: on
line diff
--- a/src/goodjava/bbcode/BBCode.java	Sun Jul 10 17:52:19 2022 -0600
+++ b/src/goodjava/bbcode/BBCode.java	Wed Jul 13 21:50:41 2022 -0600
@@ -49,7 +49,7 @@
 		List list = new ArrayList();
 		StringBuilder text = new StringBuilder();
 		while( !parser.endOfInput() ) {
-			Element block = parseBlock();
+			Element block = parseBlock(false);
 			if( block != null ) {
 				add(list,text);
 				list.add( block );
@@ -62,20 +62,24 @@
 		return list.size()==1 ? list.get(0) : list;
 	}
 
-	private Object parseWellFormed() {
+	private Object parseUntil(String end) {
+		return parseUntil(end,false);
+	}
+
+	private Object parseUntil(String end,boolean inList) {
 		List list = new ArrayList();
 		StringBuilder text = new StringBuilder();
-		while( !parser.endOfInput() ) {
-			Element block = parseBlock();
+		while( !parser.matchIgnoreCase(end) ) {
+			if( parser.endOfInput() )
+				return null;
+			Element block = parseBlock(inList);
 			if( block != null ) {
 				add(list,text);
 				list.add( block );
-				continue;
+			} else {
+				text.append( parser.currentChar() );
+				parser.anyChar();
 			}
-			if( couldBeTag() )
-				break;
-			text.append( parser.currentChar() );
-			parser.anyChar();
 		}
 		add(list,text);
 		return list.size()==1 ? list.get(0) : list;
@@ -88,50 +92,28 @@
 		}
 	}
 
-	private boolean couldBeTag() {
-		if( parser.currentChar() != '[' )
-			return false;
-		return parser.testIgnoreCase("[b]")
-			|| parser.testIgnoreCase("[/b]")
-			|| parser.testIgnoreCase("[i]")
-			|| parser.testIgnoreCase("[/i]")
-			|| parser.testIgnoreCase("[u]")
-			|| parser.testIgnoreCase("[/u]")
-			|| parser.testIgnoreCase("[url]")
-			|| parser.testIgnoreCase("[url=")
-			|| parser.testIgnoreCase("[/url]")
-			|| parser.testIgnoreCase("[code]")
-			|| parser.testIgnoreCase("[/code]")
-			|| parser.testIgnoreCase("[img]")
-			|| parser.testIgnoreCase("[/img]")
-			|| parser.testIgnoreCase("[color=")
-			|| parser.testIgnoreCase("[/color]")
-			|| parser.testIgnoreCase("[size=")
-			|| parser.testIgnoreCase("[/size]")
-			|| parser.testIgnoreCase("[video]")
-			|| parser.testIgnoreCase("[/video]")
-			|| parser.testIgnoreCase("[quote]")
-			|| parser.testIgnoreCase("[quote=")
-			|| parser.testIgnoreCase("[/quote]")
-		;
-	}
-
-	private Element parseBlock() {
+	private Element parseBlock(boolean inList) {
 		if( parser.currentChar() != '[' )
 			return null;
 		Element s;
 		s = parseB();  if(s!=null) return s;
 		s = parseI();  if(s!=null) return s;
 		s = parseU();  if(s!=null) return s;
-		s = parseUrl1();  if(s!=null) return s;
-		s = parseUrl2();  if(s!=null) return s;
+		s = parseS();  if(s!=null) return s;
+		s = parseSup();  if(s!=null) return s;
+		s = parseBrackets();  if(s!=null) return s;
+		s = parseUrl();  if(s!=null) return s;
 		s = parseCode();  if(s!=null) return s;
 		s = parseImg();  if(s!=null) return s;
 		s = parseColor();  if(s!=null) return s;
 		s = parseSize();  if(s!=null) return s;
 		s = parseVideo();  if(s!=null) return s;
-		s = parseQuote1();  if(s!=null) return s;
-		s = parseQuote2();  if(s!=null) return s;
+		s = parseQuote();  if(s!=null) return s;
+		s = parseUl();  if(s!=null) return s;
+		s = parseOl();  if(s!=null) return s;
+		if( inList ) {
+			s = parseLi();  if(s!=null) return s;
+		}
 		return null;
 	}
 
@@ -139,8 +121,8 @@
 		parser.begin();
 		if( !parser.matchIgnoreCase("[b]") )
 			return parser.failure(null);
-		Object content = parseWellFormed();
-		if( !parser.matchIgnoreCase("[/b]") )
+		Object content = parseUntil("[/b]");
+		if( content==null )
 			return parser.failure(null);
 		Element rtn = new Element("b",content);
 		return parser.success(rtn);
@@ -150,8 +132,8 @@
 		parser.begin();
 		if( !parser.matchIgnoreCase("[i]") )
 			return parser.failure(null);
-		Object content = parseWellFormed();
-		if( !parser.matchIgnoreCase("[/i]") )
+		Object content = parseUntil("[/i]");
+		if( content==null )
 			return parser.failure(null);
 		Element rtn = new Element("i",content);
 		return parser.success(rtn);
@@ -161,33 +143,65 @@
 		parser.begin();
 		if( !parser.matchIgnoreCase("[u]") )
 			return parser.failure(null);
-		Object content = parseWellFormed();
-		if( !parser.matchIgnoreCase("[/u]") )
+		Object content = parseUntil("[/u]");
+		if( content==null )
 			return parser.failure(null);
 		Element rtn = new Element("u",content);
 		return parser.success(rtn);
 	}
 
-	private Element parseUrl1() {
+	private Element parseS() {
 		parser.begin();
-		if( !parser.matchIgnoreCase("[url]") )
+		if( !parser.matchIgnoreCase("[s]") )
+			return parser.failure(null);
+		Object content = parseUntil("[/s]");
+		if( content==null )
 			return parser.failure(null);
-		String url = parseRealUrl();
-		if( !parser.matchIgnoreCase("[/url]") )
+		Element rtn = new Element("s",content);
+		return parser.success(rtn);
+	}
+
+	private Element parseSup() {
+		parser.begin();
+		if( !parser.matchIgnoreCase("[sup]") )
 			return parser.failure(null);
-		Element rtn = new Element("url",url);
+		Object content = parseUntil("[/sup]");
+		if( content==null )
+			return parser.failure(null);
+		Element rtn = new Element("sup",content);
 		return parser.success(rtn);
 	}
 
-	private Element parseUrl2() {
+	private Element parseBrackets() {
 		parser.begin();
-		if( !parser.matchIgnoreCase("[url=") )
+		if( !parser.matchIgnoreCase("[brackets]") )
+			return parser.failure(null);
+		Object content = parseUntil("[/brackets]");
+		if( content==null )
+			return parser.failure(null);
+		Element rtn = new Element("brackets",content);
+		return parser.success(rtn);
+	}
+
+	private Element parseUrl() {
+		parser.begin();
+		if( !parser.matchIgnoreCase("[url") )
 			return parser.failure(null);
-		String url = parseRealUrl();
-		if( !parser.match(']') )
-			return parser.failure(null);
-		Object content = parseWellFormed();
-		if( !parser.matchIgnoreCase("[/url]") )
+		String url;
+		Object content;
+		if( parser.match(']') ) {
+			url = parseRealUrl();
+			content = null;
+			if( !parser.matchIgnoreCase("[/url]") )
+				return parser.failure(null);
+		} else if( parser.match('=') ) {
+			url = parseRealUrl();
+			if( !parser.match(']') )
+				return parser.failure(null);
+			content = parseUntil("[/url]");
+			if( content==null )
+				return parser.failure(null);
+		} else
 			return parser.failure(null);
 		Element rtn = new Element("url",url,content);
 		return parser.success(rtn);
@@ -210,16 +224,30 @@
 
 	private Element parseCode() {
 		parser.begin();
-		if( !parser.matchIgnoreCase("[code]") )
+		String param;
+		String end;
+		if( !parser.matchIgnoreCase("[code") )
+			return parser.failure(null);
+		if( parser.match(']') ) {
+			param = null;
+			end = "[/code]";
+		} else if( parser.match('=') ) {
+			int start = parser.currentIndex();
+			while( parser.noneOf("[]") );
+			param = parser.textFrom(start);
+			if( !parser.match(']') )
+				return parser.failure(null);
+			end = "[/code=" + param + "]";
+		} else
 			return parser.failure(null);
 		int start = parser.currentIndex();
-		while( !parser.testIgnoreCase("[/code]") ) {
+		while( !parser.testIgnoreCase(end) ) {
 			if( !parser.anyChar() )
 				return parser.failure(null);
 		}
 		String content = parser.textFrom(start);
-		if( !parser.matchIgnoreCase("[/code]") ) throw new RuntimeException();
-		Element rtn = new Element("code",content);
+		if( !parser.matchIgnoreCase(end) ) throw new RuntimeException();
+		Element rtn = new Element("code",param,content);
 		return parser.success(rtn);
 	}
 
@@ -247,8 +275,8 @@
 		String color = parser.textFrom(start);
 		if( !parser.match(']') )
 			return parser.failure(null);
-		Object content = parseWellFormed();
-		if( !parser.matchIgnoreCase("[/color]") )
+		Object content = parseUntil("[/color]");
+		if( content==null )
 			return parser.failure(null);
 		Element rtn = new Element("color",color,content);
 		return parser.success(rtn);
@@ -263,8 +291,8 @@
 		String size = parser.textFrom(start);
 		if( !parser.match(']') )
 			return parser.failure(null);
-		Object content = parseWellFormed();
-		if( !parser.matchIgnoreCase("[/size]") )
+		Object content = parseUntil("[/size]");
+		if( content==null )
 			return parser.failure(null);
 		Element rtn = new Element("size",size,content);
 		return parser.success(rtn);
@@ -310,32 +338,60 @@
 	}
 
 
-	private Element parseQuote1() {
+	private Element parseQuote() {
 		parser.begin();
-		if( !parser.matchIgnoreCase("[quote]") )
-			return parser.failure(null);
-		Object content = parseWellFormed();
-		if( !parser.matchIgnoreCase("[/quote]") )
+		if( !parser.matchIgnoreCase("[quote") )
 			return parser.failure(null);
-		Element rtn = new Element("quote",content);
-		return parser.success(rtn);
-	}
-
-	private Element parseQuote2() {
-		parser.begin();
-		if( !parser.matchIgnoreCase("[quote=") )
+		String name;
+		if( parser.match(']') ) {
+			name = null;
+		} else if( parser.match('=') ) {
+			int start = parser.currentIndex();
+			while( parser.noneOf("[]") );
+			name = parser.textFrom(start).trim();
+			if( !parser.match(']') )
+				return parser.failure(null);
+		} else
 			return parser.failure(null);
-		List args = new ArrayList();
-		int start = parser.currentIndex();
-		while( parser.noneOf("[]") );
-		String name = parser.textFrom(start).trim();
-		if( !parser.match(']') )
-			return parser.failure(null);
-		Object content = parseWellFormed();
-		if( !parser.matchIgnoreCase("[/quote]") )
+		Object content = parseUntil("[/quote]");
+		if( content==null )
 			return parser.failure(null);
 		Element rtn = new Element("quote",name,content);
 		return parser.success(rtn);
 	}
 
+
+	private Element parseUl() {
+		parser.begin();
+		if( !parser.matchIgnoreCase("[ul]") )
+			return parser.failure(null);
+		Object content = parseUntil("[/ul]",true);
+		if( content==null )
+			return parser.failure(null);
+		Element rtn = new Element("ul",content);
+		return parser.success(rtn);
+	}
+
+	private Element parseOl() {
+		parser.begin();
+		if( !parser.matchIgnoreCase("[ol]") )
+			return parser.failure(null);
+		Object content = parseUntil("[/ol]",true);
+		if( content==null )
+			return parser.failure(null);
+		Element rtn = new Element("ol",content);
+		return parser.success(rtn);
+	}
+
+	private Element parseLi() {
+		parser.begin();
+		if( !parser.matchIgnoreCase("[li]") )
+			return parser.failure(null);
+		Object content = parseUntil("[/li]");
+		if( content==null )
+			return parser.failure(null);
+		Element rtn = new Element("li",content);
+		return parser.success(rtn);
+	}
+
 }