Mercurial Hosting > luan
view src/goodjava/bbcode/BBCode.java @ 1809:90187946d1a4
minor
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 12 May 2024 17:15:33 -0600 |
parents | 6c9aea554691 |
children |
line wrap: on
line source
package goodjava.bbcode; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.LinkedHashMap; import java.util.regex.Pattern; import goodjava.parser.Parser; public final class BBCode { private static final Pattern tagPtn = Pattern.compile( "\\[(/?[a-zA-Z_]+(=[^ \\n\\t\\[\\]]*)?)\\]" ); public static String encode(String s) { return tagPtn.matcher(s).replaceAll("[brackets]$1[/brackets]"); } public final class Element { public final String name; public final String param; public final Object contents; // String, Element, or List private Element(String name,String param,Object contents) { this.name = name.toLowerCase(); this.param = param; this.contents = contents; } } public static Object parse(String text) { if( text.indexOf('[') == -1 ) return text; return new BBCode(text).parse(); } private final Parser parser; private BBCode(String text) { this.parser = new Parser(text); } private Object parse() { List list = new ArrayList(); StringBuilder text = new StringBuilder(); while( !parser.endOfInput() ) { Element block = parseBlock(); if( block != null ) { add(list,text); list.add( block ); } else { text.append( parser.currentChar() ); parser.anyChar(); } } add(list,text); return list.size()==1 ? list.get(0) : list; } private Object parseUntil(String end) { List list = new ArrayList(); StringBuilder text = new StringBuilder(); while( !parser.matchIgnoreCase(end) ) { if( parser.endOfInput() ) return null; Element block = parseBlock(); if( block != null ) { add(list,text); list.add( block ); } else { text.append( parser.currentChar() ); parser.anyChar(); } } add(list,text); return list.size()==1 ? list.get(0) : list; } private void add(List list,StringBuilder text) { if( text.length() > 0 ) { list.add( text.toString() ); text.setLength(0); } } private Element parseBlock() { if( parser.currentChar() != '[' ) return null; 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); } if( !parser.match(']') ) return parser.failure(null); Object content = parseUntil("[/"+name+"]"); if( content==null ) return parser.failure(null); Element rtn = new Element(name,param,content); return parser.success(rtn); } private boolean matchTagChar() { return parser.inCharRange('a','z') || parser.inCharRange('A','Z') || parser.inCharRange('0','9') || parser.match('_') ; } }