1 5 package com.teamkonzept.publishing.markups; 6 7 import java.util.*; 8 9 import com.teamkonzept.lib.*; 10 11 public class TKMarkupParser { 12 13 private static final String IDENTIFIERFIRSTCODES = "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 14 private static final String DIGITCODES = "0123456789"; 15 private static final String IDENTIFIERCODES = IDENTIFIERFIRSTCODES+DIGITCODES; 16 private static final String ESCAPECODES = "<>"; 17 18 private TKMarkupItemList itemList; 19 private TKHashtable markups; 20 21 public TKMarkup currentMarkup; 22 23 protected TKVector diagnostics; 24 25 public TKMarkupParser (TKVector diagnostics, TKMarkupItemList itemList) { 26 27 if (itemList == null) this.itemList = new TKMarkupItemList (); 28 else this.itemList = itemList; 29 30 this.markups = new TKHashtable(); 31 this.diagnostics = diagnostics; 32 this.currentMarkup = null; 33 } 34 35 public TKMarkupParser (TKVector diagnostics) { 36 37 this (diagnostics,null); 38 } 39 40 public void initMarkupParsing () { } 41 42 public void addDiagnostic (String diagnostic) { 43 44 if (diagnostics == null) diagnostics = new TKVector(); 45 diagnostics.addElement(diagnostic); 46 } 47 48 public TKMarkupParam createParam (String name, String value) { 49 50 return new TKMarkupParam (name,value); 51 } 52 53 public TKMarkup createMarkup (String name, TKHashtable params, int pos) { 54 55 return new TKMarkup (name,params,pos); 56 } 57 58 public TKMarkup createMarkup (String name, TKHashtable params, int pos, boolean backsl) { 59 60 return new TKMarkup (name,params,pos,backsl); 61 } 62 63 public void register (TKMarkup markup) { 64 65 currentMarkup = markup; 66 markups.put(markup.toString(),markup); 67 } 68 69 public void deregister (TKMarkup markup) { 70 71 currentMarkup = null; 72 markups.remove(markup.toString()); 73 } 74 75 public void registerMarkup (String markupName) { } 76 77 public void registerParam (String paramName) { } 78 79 public Enumeration allMarkups () { 80 81 Enumeration e = markups.elements(); 82 TKVector vec = new TKVector(); 83 vec.fill (e); 84 85 return vec.elements(); 86 } 87 88 public void cleanup (TKMarkupItemList itemList, int pos) { } 89 90 public void cleanupCloseLevel () { } 91 92 public boolean closeLevel(TKMarkupItemList itemList) { return false; } 93 94 public static boolean quotingRequired (String text) { 95 96 boolean isId = true; 97 boolean isInt = true; 98 boolean isFloat = true; 99 100 if (text == null) return false; 101 102 int pos = 0; 103 while (pos < text.length()) { 104 105 char chr = text.charAt (pos++); 106 107 if ((pos == 0) && (IDENTIFIERFIRSTCODES.indexOf(chr) == -1)) isId = false; 108 else if ((pos != 0) && (IDENTIFIERCODES.indexOf(chr) == -1)) isId = false; 109 110 if (chr == '.') 111 { 112 if (!isInt) isFloat = false; 113 else isInt = false; 114 } 115 else if (DIGITCODES.indexOf(chr) == -1) 116 { 117 isInt = false; 118 isFloat = false; 119 } 120 121 if (!isId && !isInt && !isFloat) return true; 122 } 123 124 return false; 125 } 126 127 public static String doEscapes (String text) { 128 129 if (text == null) return null; 130 131 StringBuffer buf = new StringBuffer (); 132 133 int pos = 0; 134 while (pos < text.length()) { 135 136 char chr = text.charAt (pos++); 137 138 if (chr == '\\') { 139 140 if (pos+1 < text.length()) buf.append (text.charAt (pos++)); 141 else buf.append (chr); 142 143 } else buf.append (chr); 144 } 145 146 return buf.toString(); 147 } 148 149 public static String par2tmpl (String text) { 150 151 if (text == null) return null; 152 153 StringBuffer buf = new StringBuffer (); 154 155 int pos = 0; 156 while (pos < text.length()) { 157 158 char chr = text.charAt (pos++); 159 160 if ((ESCAPECODES.indexOf(chr) != -1) || 161 (chr == '\\') || (chr == ';') || (chr == '=')) buf.append ('\\'); 162 163 buf.append (chr); 164 } 165 166 return buf.toString(); 167 } 168 169 public static String par2quotes (String text) { 170 171 if (text == null) return null; 172 173 StringBuffer buf = new StringBuffer (); 174 buf.append ('"'); 175 176 int pos = 0; 177 while (pos < text.length()) { 178 179 char chr = text.charAt (pos++); 180 181 if ((chr == '\\') || (chr == '"')) buf.append ('\\'); 182 183 buf.append (chr); 184 } 185 186 buf.append ('"'); 187 return buf.toString(); 188 } 189 190 public int parseText (String text, int pos, StringBuffer str) { 191 192 while (pos < text.length()) { 193 194 char chr = text.charAt (pos); 195 196 if ((chr == '\\') && (pos+1 < text.length())) { 197 198 if (str == null) pos++; 199 200 else { 201 202 char escapedChar = text.charAt (++pos); 203 204 if ((ESCAPECODES.indexOf(escapedChar) != -1) || 205 (escapedChar == chr)) str.append (chr); 206 207 str.append (escapedChar); 208 209 } 210 } 211 212 else if (chr == '<') break; 213 214 else if (str != null) { 215 216 if (chr == '\\') str.append (chr).append (chr); 217 else str.append (chr); 218 } 219 220 pos++; 221 } 222 223 return pos; 224 } 225 226 public int parsePattern (String text, int pos, StringBuffer str, String pattern) { 227 228 int i = 0; 229 230 while ((pos+i < text.length()) && (i < pattern.length())) { 231 232 char chr = text.charAt (pos+i); 233 234 if (chr != pattern.charAt(i++)) return pos; 235 else if (str != null) str.append (chr); 236 } 237 238 if (i == pattern.length()) return pos+i; 239 else return pos; 240 } 241 242 public int parsePatternIgnoreCase (String text, int pos, StringBuffer str, String pattern) { 243 244 int i = 0; 245 246 while ((pos+i < text.length()) && (i < pattern.length())) { 247 248 char chr = Character.toUpperCase(text.charAt (pos+i)); 249 250 if (chr != Character.toUpperCase(pattern.charAt(i++))) return pos; 251 else if (str != null) str.append (chr); 252 } 253 254 if (i == pattern.length()) return pos+i; 255 else return pos; 256 } 257 258 public int parseWhitespace (String text, int pos, StringBuffer space) { 259 260 while (pos < text.length()) { 261 262 char chr = text.charAt (pos); 263 264 if (Character.isWhitespace (chr)) { 265 266 if (space != null) space.append (chr); 267 268 } else break; 269 270 pos++; 271 } 272 273 return pos; 274 } 275 276 public int parseIdentifier (String text, int pos, StringBuffer identifier) { 277 278 while (pos < text.length()) { 279 280 char chr = text.charAt (pos); 281 282 if (((identifier.length() == 0) && (IDENTIFIERFIRSTCODES.indexOf(chr) != -1)) || 283 (IDENTIFIERCODES.indexOf(chr) != -1)) { 284 285 if (identifier != null) identifier.append (chr); 286 287 } else break; 288 289 pos++; 290 } 291 292 return pos; 293 } 294 295 public int parseStringValue (String text, int pos, StringBuffer value) 296 throws TKMarkupParserException { 297 298 int oldPos = pos; 299 pos = parsePattern (text,pos,null,"\""); 300 if (pos <= oldPos) return oldPos; 301 302 while (pos < text.length()) { 303 304 char chr = text.charAt (pos); 305 306 if (chr == '"') break; 307 308 else if ((chr == '\\') && (pos+1 < text.length())) { 309 310 if (value == null) pos++; 311 else value.append (text.charAt (++pos)); 312 313 } else if (value != null) value.append (chr); 314 315 pos++; 316 } 317 318 return forcePattern (text,pos,null,"\""); 319 } 320 321 public int parseValue (String text, int pos, StringBuffer value) 322 throws TKMarkupParserException { 323 324 int oldPos = pos; 325 pos = parseStringValue (text,pos,value); 326 if (pos > oldPos) return pos; 327 328 boolean isId = true; 329 boolean isInt = true; 330 boolean isFloat = true; 331 332 while (pos < text.length()) { 333 334 char chr = text.charAt (pos); 335 336 if ((pos == 0) && (IDENTIFIERFIRSTCODES.indexOf(chr) == -1)) isId = false; 337 else if ((pos != 0) && (IDENTIFIERCODES.indexOf(chr) == -1)) isId = false; 338 339 if (chr == '.') 340 { 341 if (!isInt) isFloat = false; 342 else isInt = false; 343 } 344 else if (DIGITCODES.indexOf(chr) == -1) 345 { 346 isInt = false; 347 isFloat = false; 348 } 349 350 if (!isId && !isInt && !isFloat) break; 351 if (value != null) value.append (chr); 352 353 pos++; 354 } 355 356 return pos; 357 } 358 359 public int forceText (String text, int pos, TKMarkupItemList itemList) 360 throws TKMarkupParserException { 361 362 StringBuffer str = itemList != null ? new StringBuffer () : null; 363 int oldPos = pos; 364 365 pos = parseText (text,pos,str); 366 if (pos == oldPos) throw new TKMarkupParserException( "Fehler: Text erwartet", pos); 367 368 if (itemList != null) itemList.addElement(new String (str)); 369 370 return pos; 371 } 372 373 public int forcePattern (String text, int pos, TKMarkupItemList itemList, String pattern) 374 throws TKMarkupParserException { 375 376 StringBuffer str = itemList != null ? new StringBuffer () : null; 377 int oldPos = pos; 378 379 pos = parsePattern (text,pos,str,pattern); 380 if (pattern.length() != (pos - oldPos)) 381 throw new TKMarkupParserException( "Syntax: '"+pattern+"' erwartet", pos); 382 383 if (itemList != null) itemList.addElement(new String (str)); 384 385 return pos; 386 } 387 388 public int forceWhitespace (String text, int pos, TKMarkupItemList itemList) 389 throws TKMarkupParserException { 390 391 StringBuffer space = itemList != null ? new StringBuffer () : null; 392 int oldPos = pos; 393 394 pos = parseWhitespace (text,pos,space); 395 if (pos == oldPos) throw new TKMarkupParserException( "Syntax: Leerraum erwartet", pos); 396 397 if (itemList != null) itemList.addElement(new String (space)); 398 399 return pos; 400 } 401 402 public int forceValue (String text, int pos, StringBuffer value) 403 throws TKMarkupParserException { 404 405 int oldPos = pos; 406 407 pos = parseValue (text,pos,value); 408 if (pos == oldPos) throw new TKMarkupParserException( "Syntax: Wert erwartet", pos); 409 410 return pos; 411 } 412 413 public int forceIdentifier (String text, int pos, StringBuffer identifier) 414 throws TKMarkupParserException { 415 416 int oldPos = pos; 417 418 pos = parseIdentifier (text,pos,identifier); 419 if (pos == oldPos) throw new TKMarkupParserException( "Syntax: Bezeichner erwartet", pos); 420 421 return pos; 422 } 423 424 public int forceIdentifier (String text, int pos, TKMarkupItemList itemList) 425 throws TKMarkupParserException { 426 427 StringBuffer identifier = itemList != null ? new StringBuffer () : null; 428 429 pos = forceIdentifier (text,pos,identifier); 430 431 if (itemList != null) itemList.addElement(new String (identifier)); 432 433 return pos; 434 } 435 436 public int forceParam (String text, int pos, TKHashtable params) 437 throws TKMarkupParserException { 438 439 StringBuffer name = new StringBuffer (); 440 String valueStr = null; 441 442 pos = forceIdentifier (text,pos,name); 443 pos = parseWhitespace (text,pos,null); 444 445 String nameStr = new String (name).toUpperCase(); 446 registerParam (nameStr); 447 448 if ((pos < text.length()) && (text.charAt (pos) == '=')) { 449 450 StringBuffer value = new StringBuffer (); 451 452 pos = parseWhitespace (text,++pos,null); 453 pos = forceValue (text,pos,value); 454 455 valueStr = new String (value); 456 } 457 458 TKMarkupParam old = (TKMarkupParam) params.get(name); 459 if (old != null) throw new TKMarkupParserException( "Syntax: Parameter "+nameStr+" mehrfach", pos); 460 461 TKMarkupParam param = createParam (nameStr,valueStr); 462 params.put(nameStr,param); 463 464 return pos; 465 } 466 467 public int forceMarkup (String text, int pos, TKMarkupItemList itemList) 468 throws TKMarkupParserException { 469 470 if (pos >= text.length()) return pos; 471 472 initMarkupParsing(); 473 474 StringBuffer name = new StringBuffer (); 475 int startPos = pos; 476 477 pos = parseAliens (text,pos); 478 if (pos > startPos) return pos; 479 480 try { pos = forceIdentifier (text,pos,name); } 481 catch (TKMarkupParserException ex) { ex.throwAgain(pos); } 482 483 String markupName = new String (name).toUpperCase(); 484 TKHashtable params = new TKHashtable (); 485 registerMarkup(markupName); 486 boolean backsl = false; 487 try { 488 pos = parseWhitespace (text,pos,null); 489 490 while (pos < text.length()) { 491 492 if (text.charAt (pos) == '>') break; 493 494 if (pos + 1 < text.length()) 495 { 496 if (text.charAt(pos + 1) == '>' && text.charAt(pos) == '/') 497 { 498 backsl = true; 499 break; 500 } 501 } 502 int oldPos = pos; 503 pos = parseAlienTrailer (text,pos); 504 if (pos > oldPos) break; 505 506 pos = forceParam (text,pos,params); 507 pos = parseWhitespace (text,pos,null); 508 } 509 510 if (backsl) 511 pos = forcePattern (text,pos,null,"/>"); 512 else 513 pos = forcePattern (text,pos,null,">"); 514 515 } catch (TKMarkupParserException ex) { ex.throwAgain(pos); 516 } catch (Exception ex) { 517 518 TKMarkupParserException.throwAgain(ex,"Fehler in "+ markupName+": ",pos); 519 } 520 521 TKMarkup markup = createMarkup (markupName,params,startPos,backsl); 522 523 register (markup); 524 pos = tieMarkup(text,pos,markup,itemList); 525 526 return pos; 527 } 528 529 public int parseAliens (String text, int pos) throws TKMarkupParserException { 530 531 return pos; 532 } 533 534 public int parseAlienTrailer (String text, int pos) throws TKMarkupParserException { 535 536 return pos; 537 } 538 539 public String compoundName() { return null; } 540 541 public int parse (String text, int pos, TKMarkupItemList itemList) { 542 543 TKMarkup storeMarkup = currentMarkup; 544 currentMarkup = null; 545 546 while ((pos < text.length()) && !closeLevel(itemList)) { 547 548 try { 549 char chr = text.charAt (pos); 550 551 if (chr == '<') pos = forceMarkup (text,pos+1,itemList); 552 else pos = forceText (text,pos,itemList); 553 554 } catch (TKMarkupParserException ex) { 555 556 diagnostics = ex.handle (diagnostics); 557 pos = ex.pos+1; 558 } 559 } 560 561 currentMarkup = storeMarkup; 562 563 return pos; 564 } 565 566 public void parse (String text) { 567 568 int pos = 0; 569 while ((text != null) && (pos < text.length())) { 570 571 pos = parse (text,pos,itemList); 572 cleanup (itemList,pos); 573 } 574 } 575 576 public int tieMarkup (String text, int pos, TKMarkup markup, TKMarkupItemList itemList) { 577 578 itemList.addElement(markup); 579 580 return pos; 581 } 582 583 public TKVector dump () { 584 585 TKVector dump = new TKVector(); 586 if (itemList != null) itemList.dump (dump,0); 587 return dump; 588 } 589 590 public String normalize () { 591 592 return itemList == null ? "" : itemList.toString(); 593 } 594 595 public String expand () { 596 597 return itemList == null ? "" : itemList.expand(); 598 } 599 600 public String convert2Tmpl () { 601 602 return itemList == null ? "" : itemList.convert2Tmpl(); 603 } 604 605 public String convert2Xml () { 606 607 return itemList == null ? "" : itemList.convert2Xml(); 608 } 609 } 612 613 | Popular Tags |