Mercurial Hosting > luan
annotate src/goodjava/bbcode/BBCode.java @ 2021:b8e5d53c4fc9
admin monitors scheduler
| author | Franklin Schmidt <fschmidt@gmail.com> | 
|---|---|
| date | Mon, 20 Oct 2025 14:45:27 -0600 | 
| parents | 6c9aea554691 | 
| children | 
| rev | line source | 
|---|---|
| 1702 | 1 package goodjava.bbcode; | 
| 585 | 2 | 
| 637 
6ea90dc10375
bbcode parser now takes a quoter function
 Franklin Schmidt <fschmidt@gmail.com> parents: 
588diff
changeset | 3 import java.util.List; | 
| 
6ea90dc10375
bbcode parser now takes a quoter function
 Franklin Schmidt <fschmidt@gmail.com> parents: 
588diff
changeset | 4 import java.util.ArrayList; | 
| 1705 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 5 import java.util.Map; | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 6 import java.util.LinkedHashMap; | 
| 1703 | 7 import java.util.regex.Pattern; | 
| 1402 
27efb1fcbcb5
move luan.lib to goodjava
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1335diff
changeset | 8 import goodjava.parser.Parser; | 
| 637 
6ea90dc10375
bbcode parser now takes a quoter function
 Franklin Schmidt <fschmidt@gmail.com> parents: 
588diff
changeset | 9 | 
| 585 | 10 | 
| 11 public final class BBCode { | |
| 12 | |
| 1712 
36c28be6d432
improve html and bbcode
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1711diff
changeset | 13 private static final Pattern tagPtn = Pattern.compile( | 
| 1737 | 14 "\\[(/?[a-zA-Z_]+(=[^ \\n\\t\\[\\]]*)?)\\]" | 
| 1712 
36c28be6d432
improve html and bbcode
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1711diff
changeset | 15 ); | 
| 
36c28be6d432
improve html and bbcode
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1711diff
changeset | 16 | 
| 
36c28be6d432
improve html and bbcode
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1711diff
changeset | 17 public static String encode(String s) { | 
| 
36c28be6d432
improve html and bbcode
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1711diff
changeset | 18 return tagPtn.matcher(s).replaceAll("[brackets]$1[/brackets]"); | 
| 
36c28be6d432
improve html and bbcode
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1711diff
changeset | 19 } | 
| 
36c28be6d432
improve html and bbcode
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1711diff
changeset | 20 | 
| 
36c28be6d432
improve html and bbcode
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1711diff
changeset | 21 | 
| 1705 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 22 public final class Element { | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 23 public final String name; | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 24 public final String param; | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 25 public final Object contents; // String, Element, or List | 
| 585 | 26 | 
| 1705 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 27 private Element(String name,String param,Object contents) { | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 28 this.name = name.toLowerCase(); | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 29 this.param = param; | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 30 this.contents = contents; | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 31 } | 
| 585 | 32 } | 
| 33 | |
| 1705 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 34 public static Object parse(String text) { | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 35 if( text.indexOf('[') == -1 ) | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 36 return text; | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 37 return new BBCode(text).parse(); | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 38 } | 
| 585 | 39 | 
| 1702 | 40 private final Parser parser; | 
| 41 | |
| 1705 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 42 private BBCode(String text) { | 
| 585 | 43 this.parser = new Parser(text); | 
| 44 } | |
| 45 | |
| 1705 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 46 private Object parse() { | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 47 List list = new ArrayList(); | 
| 1247 | 48 StringBuilder text = new StringBuilder(); | 
| 585 | 49 while( !parser.endOfInput() ) { | 
| 1737 | 50 Element block = parseBlock(); | 
| 1247 | 51 if( block != null ) { | 
| 1705 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 52 add(list,text); | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 53 list.add( block ); | 
| 1247 | 54 } else { | 
| 55 text.append( parser.currentChar() ); | |
| 585 | 56 parser.anyChar(); | 
| 57 } | |
| 58 } | |
| 1705 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 59 add(list,text); | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 60 return list.size()==1 ? list.get(0) : list; | 
| 585 | 61 } | 
| 62 | |
| 1711 | 63 private Object parseUntil(String end) { | 
| 1705 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 64 List list = new ArrayList(); | 
| 1247 | 65 StringBuilder text = new StringBuilder(); | 
| 1711 | 66 while( !parser.matchIgnoreCase(end) ) { | 
| 67 if( parser.endOfInput() ) | |
| 68 return null; | |
| 1737 | 69 Element block = parseBlock(); | 
| 585 | 70 if( block != null ) { | 
| 1705 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 71 add(list,text); | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 72 list.add( block ); | 
| 1711 | 73 } else { | 
| 74 text.append( parser.currentChar() ); | |
| 75 parser.anyChar(); | |
| 585 | 76 } | 
| 77 } | |
| 1705 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 78 add(list,text); | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 79 return list.size()==1 ? list.get(0) : list; | 
| 585 | 80 } | 
| 81 | |
| 1705 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 82 private void add(List list,StringBuilder text) { | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 83 if( text.length() > 0 ) { | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 84 list.add( text.toString() ); | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 85 text.setLength(0); | 
| 
a6e27c8e7ef4
bbcode now returns data
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1703diff
changeset | 86 } | 
| 1247 | 87 } | 
| 88 | |
| 1737 | 89 private Element parseBlock() { | 
| 585 | 90 if( parser.currentChar() != '[' ) | 
| 91 return null; | |
| 1737 | 92 parser.begin(); | 
| 93 parser.anyChar(); // [ | |
| 94 int start = parser.currentIndex(); | |
| 95 if( !matchTagChar() ) | |
| 96 return parser.failure(null); | |
| 97 while(matchTagChar()); | |
| 98 String name = parser.textFrom(start).toLowerCase(); | |
| 99 String param = null; | |
| 100 if( parser.match('=') ) { | |
| 101 start = parser.currentIndex(); | |
| 102 while( parser.noneOf("[]\n") ); | |
| 103 param = parser.textFrom(start); | |
| 1711 | 104 } | 
| 1737 | 105 if( !parser.match(']') ) | 
| 585 | 106 return parser.failure(null); | 
| 1737 | 107 Object content = parseUntil("[/"+name+"]"); | 
| 1711 | 108 if( content==null ) | 
| 585 | 109 return parser.failure(null); | 
| 1737 | 110 Element rtn = new Element(name,param,content); | 
| 585 | 111 return parser.success(rtn); | 
| 112 } | |
| 113 | |
| 1737 | 114 private boolean matchTagChar() { | 
| 115 return parser.inCharRange('a','z') | |
| 585 | 116 || parser.inCharRange('A','Z') | 
| 1737 | 117 || parser.inCharRange('0','9') | 
| 118 || parser.match('_') | |
| 119 ; | |
| 1711 | 120 } | 
| 121 | |
| 585 | 122 } | 
