changeset 1737:6c9aea554691

generalize bbcode
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 18 Oct 2022 22:08:29 -0600
parents a02a75e3daa8
children 9713f7fd50b3
files src/goodjava/bbcode/BBCode.java src/luan/modules/parsers/BBCodeLuan.java
diffstat 2 files changed, 24 insertions(+), 287 deletions(-) [+]
line wrap: on
line diff
--- a/src/goodjava/bbcode/BBCode.java	Sun Oct 16 11:44:23 2022 -0600
+++ b/src/goodjava/bbcode/BBCode.java	Tue Oct 18 22:08:29 2022 -0600
@@ -11,7 +11,7 @@
 public final class BBCode {
 
 	private static final Pattern tagPtn = Pattern.compile(
-		"\\[(/?[a-zA-Z]+(=[^ \\n\\t\\[\\]]*)?)\\]"
+		"\\[(/?[a-zA-Z_]+(=[^ \\n\\t\\[\\]]*)?)\\]"
 	);
 
 	public static String encode(String s) {
@@ -23,21 +23,11 @@
 		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);
-		}
 
 		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;
 		}
 	}
 
@@ -57,7 +47,7 @@
 		List list = new ArrayList();
 		StringBuilder text = new StringBuilder();
 		while( !parser.endOfInput() ) {
-			Element block = parseBlock(false);
+			Element block = parseBlock();
 			if( block != null ) {
 				add(list,text);
 				list.add( block );
@@ -71,16 +61,12 @@
 	}
 
 	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.matchIgnoreCase(end) ) {
 			if( parser.endOfInput() )
 				return null;
-			Element block = parseBlock(inList);
+			Element block = parseBlock();
 			if( block != null ) {
 				add(list,text);
 				list.add( block );
@@ -100,280 +86,37 @@
 		}
 	}
 
-	private Element parseBlock(boolean inList) {
+	private Element parseBlock() {
 		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 = 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 = 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;
+		parser.begin();
+		parser.anyChar();  // [
+		int start = parser.currentIndex();
+		if( !matchTagChar() )
+			return parser.failure(null);
+		while(matchTagChar());
+		String name = parser.textFrom(start).toLowerCase();
+		String param = null;
+		if( parser.match('=') ) {
+			start = parser.currentIndex();
+			while( parser.noneOf("[]\n") );
+			param = parser.textFrom(start);
 		}
-		return null;
-	}
-
-	private Element parseB() {
-		parser.begin();
-		if( !parser.matchIgnoreCase("[b]") )
-			return parser.failure(null);
-		Object content = parseUntil("[/b]");
-		if( content==null )
+		if( !parser.match(']') )
 			return parser.failure(null);
-		Element rtn = new Element("b",content);
-		return parser.success(rtn);
-	}
-
-	private Element parseI() {
-		parser.begin();
-		if( !parser.matchIgnoreCase("[i]") )
-			return parser.failure(null);
-		Object content = parseUntil("[/i]");
-		if( content==null )
-			return parser.failure(null);
-		Element rtn = new Element("i",content);
-		return parser.success(rtn);
-	}
-
-	private Element parseU() {
-		parser.begin();
-		if( !parser.matchIgnoreCase("[u]") )
-			return parser.failure(null);
-		Object content = parseUntil("[/u]");
+		Object content = parseUntil("[/"+name+"]");
 		if( content==null )
 			return parser.failure(null);
-		Element rtn = new Element("u",content);
-		return parser.success(rtn);
-	}
-
-	private Element parseS() {
-		parser.begin();
-		if( !parser.matchIgnoreCase("[s]") )
-			return parser.failure(null);
-		Object content = parseUntil("[/s]");
-		if( content==null )
-			return parser.failure(null);
-		Element rtn = new Element("s",content);
-		return parser.success(rtn);
-	}
-
-	private Element parseSup() {
-		parser.begin();
-		if( !parser.matchIgnoreCase("[sup]") )
-			return parser.failure(null);
-		Object content = parseUntil("[/sup]");
-		if( content==null )
-			return parser.failure(null);
-		Element rtn = new Element("sup",content);
-		return parser.success(rtn);
-	}
-
-	private Element parseBrackets() {
-		parser.begin();
-		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;
-		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);
+		Element rtn = new Element(name,param,content);
 		return parser.success(rtn);
 	}
 
-	private String parseRealUrl() {
-		parser.begin();
-		while( parser.match(' ') );
-		int start = parser.currentIndex();
-		if( !parser.matchIgnoreCase("http") )
-			return parser.failure(null);
-		parser.matchIgnoreCase("s");
-		if( !parser.matchIgnoreCase("://") )
-			return parser.failure(null);
-		while( parser.noneOf(" \n\t[]") );
-		String url = parser.textFrom(start);
-		while( parser.match(' ') );
-		return parser.success(url);
-	}
-
-	private Element parseCode() {
-		parser.begin();
-		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("[]\n") );
-			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(end) ) {
-			if( !parser.anyChar() )
-				return parser.failure(null);
-		}
-		String content = parser.textFrom(start);
-		if( !parser.matchIgnoreCase(end) ) throw new RuntimeException();
-		Element rtn = new Element("code",param,content);
-		return parser.success(rtn);
-	}
-
-	private Element parseImg() {
-		parser.begin();
-		if( !parser.matchIgnoreCase("[img]") )
-			return parser.failure(null);
-		String url = parseRealUrl();
-		if( !parser.matchIgnoreCase("[/img]") )
-			return parser.failure(null);
-		Element rtn = new Element("img",url);
-		return parser.success(rtn);
-	}
-
-	private Element parseColor() {
-		parser.begin();
-		if( !parser.matchIgnoreCase("[color=") )
-			return parser.failure(null);
-		int start = parser.currentIndex();
-		while( parser.inCharRange('0','9')
-			|| parser.inCharRange('a','z')
+	private boolean matchTagChar() {
+		return parser.inCharRange('a','z')
 			|| parser.inCharRange('A','Z')
-			|| parser.anyOf("#(, )")
-		);
-		String color = parser.textFrom(start);
-		if( !parser.match(']') )
-			return parser.failure(null);
-		Object content = parseUntil("[/color]");
-		if( content==null )
-			return parser.failure(null);
-		Element rtn = new Element("color",color,content);
-		return parser.success(rtn);
-	}
-
-	private Element parseSize() {
-		parser.begin();
-		if( !parser.matchIgnoreCase("[size=") )
-			return parser.failure(null);
-		int start = parser.currentIndex();
-		while( parser.match('.') || parser.inCharRange('0','9') );
-		if( parser.matchIgnoreCase("pt") || parser.match('%') )
-			; // ok
-		String size = parser.textFrom(start);
-		if( !parser.match(']') )
-			return parser.failure(null);
-		Object content = parseUntil("[/size]");
-		if( content==null )
-			return parser.failure(null);
-		Element rtn = new Element("size",size,content);
-		return parser.success(rtn);
-	}
-
-	private Element parseVideo() {
-		parser.begin();
-		if( !parser.matchIgnoreCase("[video]") )
-			return parser.failure(null);
-		String url = parseRealUrl();
-		if( !parser.matchIgnoreCase("[/video]") )
-			return parser.failure(null);
-		Element rtn = new Element("video",null,url);
-		return parser.success(rtn);
-	}
-
-
-	private Element parseQuote() {
-		parser.begin();
-		if( !parser.matchIgnoreCase("[quote") )
-			return parser.failure(null);
-		String name;
-		if( parser.match(']') ) {
-			name = null;
-		} else if( parser.match('=') ) {
-			int start = parser.currentIndex();
-			while( parser.noneOf("[]\n") );
-			name = parser.textFrom(start);
-			if( !parser.match(']') )
-				return parser.failure(null);
-		} else
-			return parser.failure(null);
-		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);
+			|| parser.inCharRange('0','9')
+			|| parser.match('_')
+		;
 	}
 
 }
--- a/src/luan/modules/parsers/BBCodeLuan.java	Sun Oct 16 11:44:23 2022 -0600
+++ b/src/luan/modules/parsers/BBCodeLuan.java	Tue Oct 18 22:08:29 2022 -0600
@@ -41,15 +41,9 @@
 		t.rawPut( "name", el.name );
 		Object param = el.param;
 		Object contents = el.contents;
-		Map<String,String> extra = el.extra;
 		if( param != null )
 			t.rawPut( "param", param );
 		t.rawPut( "contents", convert(contents) );
-		if( extra != null ) {
-			for( Map.Entry<String,String> entry : extra.entrySet() ) {
-				t.rawPut( entry.getKey(), entry.getValue() );
-			}
-		}
 		return t;
 	}