1 5 6 package org.w3c.tidy; 7 8 33 34 44 45 import java.io.FileOutputStream ; 46 import java.io.File ; 47 48 import java.io.IOException ; 49 import java.io.FileNotFoundException ; 50 51 public class PPrint { 52 53 54 55 public static final short EFFECT_BLEND = -1; 56 public static final short EFFECT_BOX_IN = 0; 57 public static final short EFFECT_BOX_OUT = 1; 58 public static final short EFFECT_CIRCLE_IN = 2; 59 public static final short EFFECT_CIRCLE_OUT = 3; 60 public static final short EFFECT_WIPE_UP = 4; 61 public static final short EFFECT_WIPE_DOWN = 5; 62 public static final short EFFECT_WIPE_RIGHT = 6; 63 public static final short EFFECT_WIPE_LEFT = 7; 64 public static final short EFFECT_VERT_BLINDS = 8; 65 public static final short EFFECT_HORZ_BLINDS = 9; 66 public static final short EFFECT_CHK_ACROSS = 10; 67 public static final short EFFECT_CHK_DOWN = 11; 68 public static final short EFFECT_RND_DISSOLVE = 12; 69 public static final short EFFECT_SPLIT_VIRT_IN = 13; 70 public static final short EFFECT_SPLIT_VIRT_OUT = 14; 71 public static final short EFFECT_SPLIT_HORZ_IN = 15; 72 public static final short EFFECT_SPLIT_HORZ_OUT = 16; 73 public static final short EFFECT_STRIPS_LEFT_DOWN = 17; 74 public static final short EFFECT_STRIPS_LEFT_UP = 18; 75 public static final short EFFECT_STRIPS_RIGHT_DOWN = 19; 76 public static final short EFFECT_STRIPS_RIGHT_UP = 20; 77 public static final short EFFECT_RND_BARS_HORZ = 21; 78 public static final short EFFECT_RND_BARS_VERT = 22; 79 public static final short EFFECT_RANDOM = 23; 80 81 private static final short NORMAL = 0; 82 private static final short PREFORMATTED = 1; 83 private static final short COMMENT = 2; 84 private static final short ATTRIBVALUE = 4; 85 private static final short NOWRAP = 8; 86 private static final short CDATA = 16; 87 88 private int[] linebuf = null; 89 private int lbufsize = 0; 90 private int linelen = 0; 91 private int wraphere = 0; 92 private boolean inAttVal = false; 93 private boolean InString = false; 94 95 private int slide = 0; 96 private int count = 0; 97 private Node slidecontent = null; 98 99 private Configuration configuration; 100 101 public PPrint(Configuration configuration) 102 { 103 this.configuration = configuration; 104 } 105 106 114 115 116 117 public static int getUTF8(byte[] str, int start, MutableInteger ch) 118 { 119 int c, n, i, bytes; 120 121 c = ((int)str[start]) & 0xFF; 123 if ((c & 0xE0) == 0xC0) 124 { 125 n = c & 31; 126 bytes = 2; 127 } 128 else if ((c & 0xF0) == 0xE0) 129 { 130 n = c & 15; 131 bytes = 3; 132 } 133 else if ((c & 0xF8) == 0xF0) 134 { 135 n = c & 7; 136 bytes = 4; 137 } 138 else if ((c & 0xFC) == 0xF8) 139 { 140 n = c & 3; 141 bytes = 5; 142 } 143 else if ((c & 0xFE) == 0xFC) 144 145 { 146 n = c & 1; 147 bytes = 6; 148 } 149 else 150 { 151 ch.value = c; 152 return 0; 153 } 154 155 156 for (i = 1; i < bytes; ++i) 157 { 158 c = ((int)str[start + i]) & 0xFF; n = (n << 6) | (c & 0x3F); 160 } 161 162 ch.value = n; 163 return bytes - 1; 164 } 165 166 167 public static int putUTF8(byte[] buf, int start, int c) 168 { 169 if (c < 128) 170 buf[start++] = (byte)c; 171 else if (c <= 0x7FF) 172 { 173 buf[start++] = (byte)(0xC0 | (c >> 6)); 174 buf[start++] = (byte)(0x80 | (c & 0x3F)); 175 } 176 else if (c <= 0xFFFF) 177 { 178 buf[start++] = (byte)(0xE0 | (c >> 12)); 179 buf[start++] = (byte)(0x80 | ((c >> 6) & 0x3F)); 180 buf[start++] = (byte)(0x80 | (c & 0x3F)); 181 } 182 else if (c <= 0x1FFFFF) 183 { 184 buf[start++] = (byte)(0xF0 | (c >> 18)); 185 buf[start++] = (byte)(0x80 | ((c >> 12) & 0x3F)); 186 buf[start++] = (byte)(0x80 | ((c >> 6) & 0x3F)); 187 buf[start++] = (byte)(0x80 | (c & 0x3F)); 188 } 189 else 190 { 191 buf[start++] = (byte)(0xF8 | (c >> 24)); 192 buf[start++] = (byte)(0x80 | ((c >> 18) & 0x3F)); 193 buf[start++] = (byte)(0x80 | ((c >> 12) & 0x3F)); 194 buf[start++] = (byte)(0x80 | ((c >> 6) & 0x3F)); 195 buf[start++] = (byte)(0x80 | (c & 0x3F)); 196 } 197 198 return start; 199 } 200 201 private void addC(int c, int index) 202 { 203 if (index + 1 >= lbufsize) 204 { 205 while (index + 1 >= lbufsize) 206 { 207 if (lbufsize == 0) 208 lbufsize = 256; 209 else 210 lbufsize = lbufsize * 2; 211 } 212 213 int[] temp = new int[ lbufsize ]; 214 if (linebuf != null) 215 System.arraycopy(linebuf, 0, temp, 0, index); 216 linebuf = temp; 217 } 218 219 linebuf[index] = c; 220 } 221 222 private void wrapLine(Out fout, int indent) 223 { 224 int i, p, q; 225 226 if (wraphere == 0) 227 return; 228 229 for (i = 0; i < indent; ++i) 230 fout.outc((int)' '); 231 232 for (i = 0; i < wraphere; ++i) 233 fout.outc(linebuf[i]); 234 235 if (InString) 236 { 237 fout.outc((int)' '); 238 fout.outc((int)'\\'); 239 } 240 241 fout.newline(); 242 243 if (linelen > wraphere) 244 { 245 p = 0; 246 247 if (linebuf[wraphere] == ' ') 248 ++wraphere; 249 250 q = wraphere; 251 addC('\0', linelen); 252 253 while (true) 254 { 255 linebuf[p] = linebuf[q]; 256 if (linebuf[q] == 0) break; 257 p++; 258 q++; 259 } 260 linelen -= wraphere; 261 } 262 else 263 linelen = 0; 264 265 wraphere = 0; 266 } 267 268 private void wrapAttrVal(Out fout, int indent, boolean inString) 269 { 270 int i, p, q; 271 272 for (i = 0; i < indent; ++i) 273 fout.outc((int)' '); 274 275 for (i = 0; i < wraphere; ++i) 276 fout.outc(linebuf[i]); 277 278 fout.outc((int)' '); 279 280 if (inString) 281 fout.outc((int)'\\'); 282 283 fout.newline(); 284 285 if (linelen > wraphere) 286 { 287 p = 0; 288 289 if (linebuf[wraphere] == ' ') 290 ++wraphere; 291 292 q = wraphere; 293 addC('\0', linelen); 294 295 while (true) 296 { 297 linebuf[p] = linebuf[q]; 298 if (linebuf[q] == 0) break; 299 p++; 300 q++; 301 } 302 linelen -= wraphere; 303 } 304 else 305 linelen = 0; 306 307 wraphere = 0; 308 } 309 310 public void flushLine(Out fout, int indent) 311 { 312 int i; 313 314 if (linelen > 0) 315 { 316 if (indent + linelen >= this.configuration.wraplen) 317 wrapLine(fout, indent); 318 319 if (!inAttVal || this.configuration.IndentAttributes) 320 { 321 for (i = 0; i < indent; ++i) 322 fout.outc((int)' '); 323 } 324 325 for (i = 0; i < linelen; ++i) 326 fout.outc(linebuf[i]); 327 } 328 329 fout.newline(); 330 linelen = 0; 331 wraphere = 0; 332 inAttVal = false; 333 } 334 335 public void condFlushLine(Out fout, int indent) 336 { 337 int i; 338 339 if (linelen > 0) 340 { 341 if (indent + linelen >= this.configuration.wraplen) 342 wrapLine(fout, indent); 343 344 if (!inAttVal || this.configuration.IndentAttributes) 345 { 346 for (i = 0; i < indent; ++i) 347 fout.outc((int)' '); 348 } 349 350 for (i = 0; i < linelen; ++i) 351 fout.outc(linebuf[i]); 352 353 fout.newline(); 354 linelen = 0; 355 wraphere = 0; 356 inAttVal = false; 357 } 358 } 359 360 private void printChar(int c, short mode) 361 { 362 String entity; 363 364 if (c == ' ' && !((mode & (PREFORMATTED | COMMENT | ATTRIBVALUE)) != 0)) 365 { 366 367 if ((mode & NOWRAP) != 0) 368 { 369 370 if (this.configuration.NumEntities || this.configuration.XmlTags) 371 { 372 addC('&', linelen++); 373 addC('#', linelen++); 374 addC('1', linelen++); 375 addC('6', linelen++); 376 addC('0', linelen++); 377 addC(';', linelen++); 378 } 379 else 380 { 381 addC('&', linelen++); 382 addC('n', linelen++); 383 addC('b', linelen++); 384 addC('s', linelen++); 385 addC('p', linelen++); 386 addC(';', linelen++); 387 } 388 return; 389 } 390 else 391 wraphere = linelen; 392 } 393 394 395 if ((mode & COMMENT) != 0) 396 { 397 addC(c, linelen++); 398 return; 399 } 400 401 402 if (! ((mode & CDATA) != 0) ) 403 { 404 if (c == '<') 405 { 406 addC('&', linelen++); 407 addC('l', linelen++); 408 addC('t', linelen++); 409 addC(';', linelen++); 410 return; 411 } 412 413 if (c == '>') 414 { 415 addC('&', linelen++); 416 addC('g', linelen++); 417 addC('t', linelen++); 418 addC(';', linelen++); 419 return; 420 } 421 422 427 if (c == '&' && this.configuration.QuoteAmpersand) 428 { 429 addC('&', linelen++); 430 addC('a', linelen++); 431 addC('m', linelen++); 432 addC('p', linelen++); 433 addC(';', linelen++); 434 return; 435 } 436 437 if (c == '"' && this.configuration.QuoteMarks) 438 { 439 addC('&', linelen++); 440 addC('q', linelen++); 441 addC('u', linelen++); 442 addC('o', linelen++); 443 addC('t', linelen++); 444 addC(';', linelen++); 445 return; 446 } 447 448 if (c == '\'' && this.configuration.QuoteMarks) 449 { 450 addC('&', linelen++); 451 addC('#', linelen++); 452 addC('3', linelen++); 453 addC('9', linelen++); 454 addC(';', linelen++); 455 return; 456 } 457 458 if (c == 160 && this.configuration.CharEncoding != Configuration.RAW) 459 { 460 if (this.configuration.QuoteNbsp) 461 { 462 addC('&', linelen++); 463 464 if (this.configuration.NumEntities) 465 { 466 addC('#', linelen++); 467 addC('1', linelen++); 468 addC('6', linelen++); 469 addC('0', linelen++); 470 } 471 else 472 { 473 addC('n', linelen++); 474 addC('b', linelen++); 475 addC('s', linelen++); 476 addC('p', linelen++); 477 } 478 479 addC(';', linelen++); 480 } 481 else 482 addC(c, linelen++); 483 484 return; 485 } 486 } 487 488 489 if (this.configuration.CharEncoding == Configuration.ISO2022 || 490 this.configuration.CharEncoding == Configuration.RAW) 491 { 492 addC(c, linelen++); 493 return; 494 } 495 496 497 if (c == 160 && ((mode & PREFORMATTED) != 0)) 498 { 499 addC(' ', linelen++); 500 return; 501 } 502 503 512 513 if (this.configuration.MakeClean) 514 { 515 if (c >= 0x2013 && c <= 0x201E) 516 { 517 switch (c) { 518 case 0x2013: 519 case 0x2014: 520 c = '-'; 521 break; 522 case 0x2018: 523 case 0x2019: 524 case 0x201A: 525 c = '\''; 526 break; 527 case 0x201C: 528 case 0x201D: 529 case 0x201E: 530 c = '"'; 531 break; 532 } 533 } 534 } 535 536 537 if (this.configuration.CharEncoding == Configuration.LATIN1) 538 { 539 if (c > 255) 540 { 541 if (!this.configuration.NumEntities) 542 { 543 entity = EntityTable.getDefaultEntityTable().entityName((short)c); 544 if (entity != null) 545 entity = "&" + entity + ";"; 546 else 547 entity = "&#" + c + ";"; 548 } 549 else 550 entity = "&#" + c + ";"; 551 552 for (int i = 0; i < entity.length(); i++) 553 addC((int)entity.charAt(i), linelen++); 554 555 return; 556 } 557 558 if (c > 126 && c < 160) 559 { 560 entity = "&#" + c + ";"; 561 562 for (int i = 0; i < entity.length(); i++) 563 addC((int)entity.charAt(i), linelen++); 564 565 return; 566 } 567 568 addC(c, linelen++); 569 return; 570 } 571 572 573 if (this.configuration.CharEncoding == Configuration.UTF8) 574 { 575 addC(c, linelen++); 576 return; 577 } 578 579 580 if (this.configuration.XmlTags) 581 { 582 583 if (c > 127 && this.configuration.CharEncoding == Configuration.ASCII) 584 { 585 entity = "&#" + c + ";"; 586 587 for (int i = 0; i < entity.length(); i++) 588 addC((int)entity.charAt(i), linelen++); 589 590 return; 591 } 592 593 594 addC(c, linelen++); 595 return; 596 } 597 598 599 if (c > 126 || (c < ' ' && c != '\t')) 600 { 601 if (!this.configuration.NumEntities) 602 { 603 entity = EntityTable.getDefaultEntityTable().entityName((short)c); 604 if (entity != null) 605 entity = "&" + entity + ";"; 606 else 607 entity = "&#" + c + ";"; 608 } 609 else 610 entity = "&#" + c + ";"; 611 612 for (int i = 0; i < entity.length(); i++) 613 addC((int)entity.charAt(i), linelen++); 614 615 return; 616 } 617 618 addC(c, linelen++); 619 } 620 621 627 private void printText(Out fout, short mode, int indent, 628 byte[] textarray, int start, int end) 629 { 630 int i, c; 631 MutableInteger ci = new MutableInteger(); 632 633 for (i = start; i < end; ++i) 634 { 635 if (indent + linelen >= this.configuration.wraplen) 636 wrapLine(fout, indent); 637 638 c = ((int)textarray[i]) & 0xFF; 640 641 if (c > 0x7F) 642 { 643 i += getUTF8(textarray, i, ci); 644 c = ci.value; 645 } 646 647 if (c == '\n') 648 { 649 flushLine(fout, indent); 650 continue; 651 } 652 653 printChar(c, mode); 654 } 655 } 656 657 private void printString(Out fout, int indent, String str) 658 { 659 for (int i = 0; i < str.length(); i++ ) 660 addC((int)str.charAt(i), linelen++); 661 } 662 663 private void printAttrValue(Out fout, int indent, String value, int delim, boolean wrappable) 664 { 665 int c; 666 MutableInteger ci = new MutableInteger(); 667 boolean wasinstring = false; 668 byte[] valueChars = null; 669 int i; 670 short mode = (wrappable ? (short)(NORMAL | ATTRIBVALUE) : 671 (short)(PREFORMATTED | ATTRIBVALUE)); 672 673 if (value != null) 674 { 675 valueChars = Lexer.getBytes(value); 676 } 677 678 679 if (valueChars != null && valueChars.length >= 5 && valueChars[0] == '<') 680 { 681 if (valueChars[1] == '%' || valueChars[1] == '@'|| 682 (new String (valueChars, 0, 5)).equals("<?php")) 683 mode |= CDATA; 684 } 685 686 if (delim == 0) 687 delim = '"'; 688 689 addC('=', linelen++); 690 691 692 if (!this.configuration.XmlOut) { 693 694 if (indent + linelen < this.configuration.wraplen) 695 wraphere = linelen; 696 697 if (indent + linelen >= this.configuration.wraplen) 698 wrapLine(fout, indent); 699 700 if (indent + linelen < this.configuration.wraplen) 701 wraphere = linelen; 702 else 703 condFlushLine(fout, indent); 704 } 705 706 addC(delim, linelen++); 707 708 if (value != null) 709 { 710 InString = false; 711 712 i = 0; 713 while (i < valueChars.length) 714 { 715 c = ((int)valueChars[i]) & 0xFF; 717 if (wrappable && c == ' ' && indent + linelen < this.configuration.wraplen) 718 { 719 wraphere = linelen; 720 wasinstring = InString; 721 } 722 723 if (wrappable && wraphere > 0 && indent + linelen >= this.configuration.wraplen) 724 wrapAttrVal(fout, indent, wasinstring); 725 726 if (c == delim) 727 { 728 String entity; 729 730 entity = (c == '"' ? """ : "'"); 731 732 for (int j = 0; j < entity.length(); j++ ) 733 addC(entity.charAt(j), linelen++); 734 735 ++i; 736 continue; 737 } 738 else if (c == '"') 739 { 740 if (this.configuration.QuoteMarks) 741 { 742 addC('&', linelen++); 743 addC('q', linelen++); 744 addC('u', linelen++); 745 addC('o', linelen++); 746 addC('t', linelen++); 747 addC(';', linelen++); 748 } 749 else 750 addC('"', linelen++); 751 752 if (delim == '\'') 753 InString = !InString; 754 755 ++i; 756 continue; 757 } 758 else if (c == '\'') 759 { 760 if (this.configuration.QuoteMarks) 761 { 762 addC('&', linelen++); 763 addC('#', linelen++); 764 addC('3', linelen++); 765 addC('9', linelen++); 766 addC(';', linelen++); 767 } 768 else 769 addC('\'', linelen++); 770 771 if (delim == '"') 772 InString = !InString; 773 774 ++i; 775 continue; 776 } 777 778 779 if (c > 0x7F) 780 { 781 i += getUTF8(valueChars, i, ci); 782 c = ci.value; 783 } 784 785 ++i; 786 787 if (c == '\n') 788 { 789 flushLine(fout, indent); 790 continue; 791 } 792 793 printChar(c, mode); 794 } 795 } 796 797 InString = false; 798 addC(delim, linelen++); 799 } 800 801 private void printAttribute(Out fout, int indent, Node node, AttVal attr) 802 { 803 String name; 804 boolean wrappable = false; 805 806 if (this.configuration.IndentAttributes) 807 { 808 flushLine(fout, indent); 809 indent += this.configuration.spaces; 810 } 811 812 name = attr.attribute; 813 814 if (indent + linelen >= this.configuration.wraplen) 815 wrapLine(fout, indent); 816 817 if (!this.configuration.XmlTags && !this.configuration.XmlOut && attr.dict != null) 818 { 819 if (AttributeTable.getDefaultAttributeTable().isScript(name)) 820 wrappable = this.configuration.WrapScriptlets; 821 else if (!attr.dict.nowrap && this.configuration.WrapAttVals) 822 wrappable = true; 823 } 824 825 if (indent + linelen < this.configuration.wraplen) 826 { 827 wraphere = linelen; 828 addC(' ', linelen++); 829 } 830 else 831 { 832 condFlushLine(fout, indent); 833 addC(' ', linelen++); 834 } 835 836 for (int i = 0; i < name.length(); i++ ) 837 addC((int)Lexer.foldCase(name.charAt(i), 838 this.configuration.UpperCaseAttrs, 839 this.configuration.XmlTags), 840 linelen++); 841 842 if (indent + linelen >= this.configuration.wraplen) 843 wrapLine(fout, indent); 844 845 if (attr.value == null) 846 { 847 if (this.configuration.XmlTags || this.configuration.XmlOut) 848 printAttrValue(fout, indent, attr.attribute, attr.delim, true); 849 else if (!attr.isBoolAttribute() && !Node.isNewNode(node)) 850 printAttrValue(fout, indent, "", attr.delim, true); 851 else if (indent + linelen < this.configuration.wraplen) 852 wraphere = linelen; 853 854 } 855 else 856 printAttrValue(fout, indent, attr.value, attr.delim, wrappable); 857 } 858 859 private void printAttrs(Out fout, int indent, 860 Node node, AttVal attr) 861 { 862 if (attr != null) 863 { 864 if (attr.next != null) 865 printAttrs(fout, indent, node, attr.next); 866 867 if (attr.attribute != null) 868 printAttribute(fout, indent, node, attr); 869 else if (attr.asp != null) 870 { 871 addC(' ', linelen++); 872 printAsp(fout, indent, attr.asp); 873 } 874 else if (attr.php != null) 875 { 876 addC(' ', linelen++); 877 printPhp(fout, indent, attr.php); 878 } 879 } 880 881 882 if (configuration.XmlOut && 883 configuration.XmlSpace && 884 ParserImpl.XMLPreserveWhiteSpace(node, configuration.tt) && 885 node.getAttrByName("xml:space") == null) 886 printString(fout, indent, " xml:space=\"preserve\""); 887 } 888 889 895 private static boolean afterSpace(Node node) 896 { 897 Node prev; 898 int c; 899 900 if (node == null || node.tag == null || !((node.tag.model & Dict.CM_INLINE) != 0)) 901 return true; 902 903 prev = node.prev; 904 905 if (prev != null) 906 { 907 if (prev.type == Node.TextNode && prev.end > prev.start) 908 { 909 c = ((int)prev.textarray[prev.end - 1]) & 0xFF; 911 if (c == 160 || c == ' ' || c == '\n') 912 return true; 913 } 914 915 return false; 916 } 917 918 return afterSpace(node.parent); 919 } 920 921 private void printTag(Lexer lexer, Out fout, short mode, int indent, Node node) 922 { 923 char c; 924 String p; 925 TagTable tt = this.configuration.tt; 926 927 addC('<', linelen++); 928 929 if (node.type == Node.EndTag) 930 addC('/', linelen++); 931 932 p = node.element; 933 for (int i = 0; i < p.length(); i++ ) 934 addC((int)Lexer.foldCase(p.charAt(i), 935 this.configuration.UpperCaseTags, 936 this.configuration.XmlTags), 937 linelen++); 938 939 printAttrs(fout, indent, node, node.attributes); 940 941 if ((this.configuration.XmlOut || lexer != null && lexer.isvoyager) && 942 (node.type == Node.StartEndTag || (node.tag.model & Dict.CM_EMPTY) != 0)) 943 { 944 addC(' ', linelen++); 945 addC('/', linelen++); 946 } 947 948 addC('>', linelen++);; 949 950 if (node.type != Node.StartEndTag && !((mode & PREFORMATTED) != 0)) 951 { 952 if (indent + linelen >= this.configuration.wraplen) 953 wrapLine(fout, indent); 954 955 if (indent + linelen < this.configuration.wraplen) 956 { 957 961 if (afterSpace(node)) 962 { 963 if (!((mode & NOWRAP) != 0) && 964 (!((node.tag.model & Dict.CM_INLINE) != 0) || 965 (node.tag == tt.tagBr) || 966 (((node.tag.model & Dict.CM_EMPTY) != 0) && 967 node.next == null && 968 node.parent.tag == tt.tagA))) 969 { 970 wraphere = linelen; 971 } 972 } 973 } 974 else 975 condFlushLine(fout, indent); 976 } 977 } 978 979 private void printEndTag(Out fout, short mode, int indent, Node node) 980 { 981 char c; 982 String p; 983 984 990 if (false) { 991 if (indent + linelen < this.configuration.wraplen && !((mode & NOWRAP) != 0)) 992 wraphere = linelen; 993 } 994 995 addC('<', linelen++); 996 addC('/', linelen++); 997 998 p = node.element; 999 for (int i = 0; i < p.length(); i++ ) 1000 addC((int)Lexer.foldCase(p.charAt(i), 1001 this.configuration.UpperCaseTags, 1002 this.configuration.XmlTags), 1003 linelen++); 1004 1005 addC('>', linelen++); 1006 } 1007 1008 private void printComment(Out fout, int indent, Node node) 1009 { 1010 if (indent + linelen < this.configuration.wraplen) 1011 wraphere = linelen; 1012 1013 addC('<', linelen++); 1014 addC('!', linelen++); 1015 addC('-', linelen++); 1016 addC('-', linelen++); 1017if (false) { 1018 if (linelen < this.configuration.wraplen) 1019 wraphere = linelen; 1020} 1021 printText(fout, COMMENT, indent, 1022 node.textarray, node.start, node.end); 1023if (false) { 1024 if (indent + linelen < this.configuration.wraplen) 1025 wraphere = linelen; 1026} 1027 addC('-', linelen++); 1029 addC('-', linelen++); 1030 addC('>', linelen++); 1031 1032 if (node.linebreak) 1033 flushLine(fout, indent); 1034 } 1035 1036 private void printDocType(Out fout, int indent, Node node) 1037 { 1038 boolean q = this.configuration.QuoteMarks; 1039 1040 this.configuration.QuoteMarks = false; 1041 1042 if (indent + linelen < this.configuration.wraplen) 1043 wraphere = linelen; 1044 1045 condFlushLine(fout, indent); 1046 1047 addC('<', linelen++); 1048 addC('!', linelen++); 1049 addC('D', linelen++); 1050 addC('O', linelen++); 1051 addC('C', linelen++); 1052 addC('T', linelen++); 1053 addC('Y', linelen++); 1054 addC('P', linelen++); 1055 addC('E', linelen++); 1056 addC(' ', linelen++); 1057 1058 if (indent + linelen < this.configuration.wraplen) 1059 wraphere = linelen; 1060 1061 printText(fout, (short)0, indent, 1062 node.textarray, node.start, node.end); 1063 1064 if (linelen < this.configuration.wraplen) 1065 wraphere = linelen; 1066 1067 addC('>', linelen++); 1068 this.configuration.QuoteMarks = q; 1069 condFlushLine(fout, indent); 1070 } 1071 1072 private void printPI(Out fout, int indent, Node node) 1073 { 1074 if (indent + linelen < this.configuration.wraplen) 1075 wraphere = linelen; 1076 1077 addC('<', linelen++); 1078 addC('?', linelen++); 1079 1080 1081 printText(fout, CDATA, indent, 1082 node.textarray, node.start, node.end); 1083 1084 if (node.textarray[node.end - 1] != (byte)'?') 1085 addC('?', linelen++); 1086 1087 addC('>', linelen++); 1088 condFlushLine(fout, indent); 1089 } 1090 1091 1092 private void printAsp(Out fout, int indent, Node node) 1093 { 1094 int savewraplen = this.configuration.wraplen; 1095 1096 1097 1098 if (!this.configuration.WrapAsp || !this.configuration.WrapJste) 1099 this.configuration.wraplen = 0xFFFFFF; 1100if (false) { if (indent + linelen < this.configuration.wraplen) 1102 wraphere = linelen; 1103} 1105 addC('<', linelen++); 1106 addC('%', linelen++); 1107 1108 printText(fout, (this.configuration.WrapAsp ? CDATA : COMMENT), indent, 1109 node.textarray, node.start, node.end); 1110 1111 addC('%', linelen++); 1112 addC('>', linelen++); 1113 1114 this.configuration.wraplen = savewraplen; 1115 } 1116 1117 1118 private void printJste(Out fout, int indent, Node node) 1119 { 1120 int savewraplen = this.configuration.wraplen; 1121 1122 1123 1124 if (!this.configuration.WrapJste) 1125 this.configuration.wraplen = 0xFFFFFF; 1126 1127 addC('<', linelen++); 1128 addC('#', linelen++); 1129 1130 printText(fout, (this.configuration.WrapJste ? CDATA : COMMENT), indent, 1131 node.textarray, node.start, node.end); 1132 1133 addC('#', linelen++); 1134 addC('>', linelen++); 1135 1136 this.configuration.wraplen = savewraplen; 1137 } 1138 1139 1140 private void printPhp(Out fout, int indent, Node node) 1141 { 1142 int savewraplen = this.configuration.wraplen; 1143 1144 1145 1146 if (!this.configuration.WrapPhp) 1147 this.configuration.wraplen = 0xFFFFFF; 1148 1149if (false) { if (indent + linelen < this.configuration.wraplen) 1151 wraphere = linelen; 1152} addC('<', linelen++); 1154 addC('?', linelen++); 1155 1156 printText(fout, (this.configuration.WrapPhp ? CDATA : COMMENT), indent, 1157 node.textarray, node.start, node.end); 1158 1159 addC('?', linelen++); 1160 addC('>', linelen++); 1161 1162 this.configuration.wraplen = savewraplen; 1163 } 1164 1165 private void printCDATA(Out fout, int indent, Node node) 1166 { 1167 int savewraplen = this.configuration.wraplen; 1168 1169 condFlushLine(fout, indent); 1170 1171 1172 1173 this.configuration.wraplen = 0xFFFFFF; 1174 1175 addC('<', linelen++); 1176 addC('!', linelen++); 1177 addC('[', linelen++); 1178 addC('C', linelen++); 1179 addC('D', linelen++); 1180 addC('A', linelen++); 1181 addC('T', linelen++); 1182 addC('A', linelen++); 1183 addC('[', linelen++); 1184 1185 printText(fout, COMMENT, indent, 1186 node.textarray, node.start, node.end); 1187 1188 addC(']', linelen++); 1189 addC(']', linelen++); 1190 addC('>', linelen++); 1191 condFlushLine(fout, indent); 1192 this.configuration.wraplen = savewraplen; 1193 } 1194 1195 private void printSection(Out fout, int indent, Node node) 1196 { 1197 int savewraplen = this.configuration.wraplen; 1198 1199 1200 1201 if (!this.configuration.WrapSection) 1202 this.configuration.wraplen = 0xFFFFFF; 1203 1204if (false) { if (indent + linelen < this.configuration.wraplen) 1206 wraphere = linelen; 1207} addC('<', linelen++); 1209 addC('!', linelen++); 1210 addC('[', linelen++); 1211 1212 printText(fout, (this.configuration.WrapSection ? CDATA : COMMENT), indent, 1213 node.textarray, node.start, node.end); 1214 1215 addC(']', linelen++); 1216 addC('>', linelen++); 1217 1218 this.configuration.wraplen = savewraplen; 1219 } 1220 1221 private boolean shouldIndent(Node node) 1222 { 1223 TagTable tt = this.configuration.tt; 1224 1225 if (!this.configuration.IndentContent) 1226 return false; 1227 1228 if (this.configuration.SmartIndent) 1229 { 1230 if (node.content != null && ((node.tag.model & Dict.CM_NO_INDENT) != 0)) 1231 { 1232 for (node = node.content; node != null; node = node.next) 1233 if (node.tag != null && (node.tag.model & Dict.CM_BLOCK) != 0) 1234 return true; 1235 1236 return false; 1237 } 1238 1239 if ((node.tag.model & Dict.CM_HEADING) != 0) 1240 return false; 1241 1242 if (node.tag == tt.tagP) 1243 return false; 1244 1245 if (node.tag == tt.tagTitle) 1246 return false; 1247 } 1248 1249 if ((node.tag.model & (Dict.CM_FIELD | Dict.CM_OBJECT)) != 0) 1250 return true; 1251 1252 if (node.tag == tt.tagMap) 1253 return true; 1254 1255 return !((node.tag.model & Dict.CM_INLINE) != 0); 1256 } 1257 1258 public void printTree(Out fout, short mode, int indent, 1259 Lexer lexer, Node node) 1260 { 1261 Node content, last; 1262 TagTable tt = this.configuration.tt; 1263 1264 if (node == null) 1265 return; 1266 1267 if (node.type == Node.TextNode) 1268 printText(fout, mode, indent, 1269 node.textarray, node.start, node.end); 1270 else if (node.type == Node.CommentTag) 1271 { 1272 printComment(fout, indent, node); 1273 } 1274 else if (node.type == Node.RootNode) 1275 { 1276 for (content = node.content; 1277 content != null; 1278 content = content.next) 1279 printTree(fout, mode, indent, lexer, content); 1280 } 1281 else if (node.type == Node.DocTypeTag) 1282 printDocType(fout, indent, node); 1283 else if (node.type == Node.ProcInsTag) 1284 printPI(fout, indent, node); 1285 else if (node.type == Node.CDATATag) 1286 printCDATA(fout, indent, node); 1287 else if (node.type == Node.SectionTag) 1288 printSection(fout, indent, node); 1289 else if (node.type == Node.AspTag) 1290 printAsp(fout, indent, node); 1291 else if (node.type == Node.JsteTag) 1292 printJste(fout, indent, node); 1293 else if (node.type == Node.PhpTag) 1294 printPhp(fout, indent, node); 1295 else if ((node.tag.model & Dict.CM_EMPTY) != 0 || node.type == Node.StartEndTag) 1296 { 1297 if (!((node.tag.model & Dict.CM_INLINE) != 0)) 1298 condFlushLine(fout, indent); 1299 1300 if (node.tag == tt.tagBr && node.prev != null && 1301 node.prev.tag != tt.tagBr && this.configuration.BreakBeforeBR) 1302 flushLine(fout, indent); 1303 1304 if (this.configuration.MakeClean && node.tag == tt.tagWbr) 1305 printString(fout, indent, " "); 1306 else 1307 printTag(lexer, fout, mode, indent, node); 1308 1309 if (node.tag == tt.tagParam || node.tag == tt.tagArea) 1310 condFlushLine(fout, indent); 1311 else if (node.tag == tt.tagBr || node.tag == tt.tagHr) 1312 flushLine(fout, indent); 1313 } 1314 else 1315 { 1316 if (node.tag != null && node.tag.parser == ParserImpl.getParsePre()) 1317 { 1318 condFlushLine(fout, indent); 1319 1320 indent = 0; 1321 condFlushLine(fout, indent); 1322 printTag(lexer, fout, mode, indent, node); 1323 flushLine(fout, indent); 1324 1325 for (content = node.content; 1326 content != null; 1327 content = content.next) 1328 printTree(fout, (short)(mode | PREFORMATTED | NOWRAP), indent, lexer, content); 1329 1330 condFlushLine(fout, indent); 1331 printEndTag(fout, mode, indent, node); 1332 flushLine(fout, indent); 1333 1334 if (this.configuration.IndentContent == false && node.next != null) 1335 flushLine(fout, indent); 1336 } 1337 else if (node.tag == tt.tagStyle || node.tag == tt.tagScript) 1338 { 1339 condFlushLine(fout, indent); 1340 1341 indent = 0; 1342 condFlushLine(fout, indent); 1343 printTag(lexer, fout, mode, indent, node); 1344 flushLine(fout, indent); 1345 1346 for (content = node.content; 1347 content != null; 1348 content = content.next) 1349 printTree(fout, (short)(mode | PREFORMATTED | NOWRAP |CDATA), indent, lexer, content); 1350 1351 condFlushLine(fout, indent); 1352 printEndTag(fout, mode, indent, node); 1353 flushLine(fout, indent); 1354 1355 if (this.configuration.IndentContent == false && node.next != null) 1356 flushLine(fout, indent); 1357 } 1358 else if ((node.tag.model & Dict.CM_INLINE) != 0) 1359 { 1360 if (this.configuration.MakeClean) 1361 { 1362 1363 if (node.tag == tt.tagFont) 1364 { 1365 for (content = node.content; 1366 content != null; 1367 content = content.next) 1368 printTree(fout, mode, indent, lexer, content); 1369 return; 1370 } 1371 1372 1373 if (node.tag == tt.tagNobr) 1374 { 1375 for (content = node.content; 1376 content != null; 1377 content = content.next) 1378 printTree(fout, (short)(mode|NOWRAP), indent, lexer, content); 1379 return; 1380 } 1381 } 1382 1383 1384 1385 printTag(lexer, fout, mode, indent, node); 1386 1387 1388 1389 if (shouldIndent(node)) 1390 { 1391 condFlushLine(fout, indent); 1392 indent += this.configuration.spaces; 1393 1394 for (content = node.content; 1395 content != null; 1396 content = content.next) 1397 printTree(fout, mode, indent, lexer, content); 1398 1399 condFlushLine(fout, indent); 1400 indent -= this.configuration.spaces; 1401 condFlushLine(fout, indent); 1402 } 1403 else 1404 { 1405 1406 for (content = node.content; 1407 content != null; 1408 content = content.next) 1409 printTree(fout, mode, indent, lexer, content); 1410 } 1411 1412 printEndTag(fout, mode, indent, node); 1413 } 1414 else 1415 { 1416 condFlushLine(fout, indent); 1417 1418 if (this.configuration.SmartIndent && node.prev != null) 1419 flushLine(fout, indent); 1420 1421 if (this.configuration.HideEndTags == false || 1422 !(node.tag != null && ((node.tag.model & Dict.CM_OMITST) != 0))) 1423 { 1424 printTag(lexer, fout, mode, indent, node); 1425 1426 if (shouldIndent(node)) 1427 condFlushLine(fout, indent); 1428 else if ((node.tag.model & Dict.CM_HTML) != 0 || 1429 node.tag == tt.tagNoframes || 1430 ((node.tag.model & Dict.CM_HEAD) != 0 && 1431 !(node.tag == tt.tagTitle))) 1432 flushLine(fout, indent); 1433 } 1434 1435 if (node.tag == tt.tagBody && this.configuration.BurstSlides) 1436 printSlide(fout, mode, (this.configuration.IndentContent ? indent+this.configuration.spaces : indent), lexer); 1437 else 1438 { 1439 last = null; 1440 1441 for (content = node.content; 1442 content != null; content = content.next) 1443 { 1444 1445 if (last != null && !this.configuration.IndentContent && last.type == Node.TextNode && 1446 content.tag != null && (content.tag.model & Dict.CM_BLOCK) != 0) 1447 { 1448 flushLine(fout, indent); 1449 flushLine(fout, indent); 1450 } 1451 1452 printTree(fout, mode, 1453 (shouldIndent(node) ? indent+this.configuration.spaces : indent), lexer, content); 1454 1455 last = content; 1456 } 1457 } 1458 1459 1460 if (shouldIndent(node) || 1461 (((node.tag.model & Dict.CM_HTML) != 0 || node.tag == tt.tagNoframes || 1462 ((node.tag.model & Dict.CM_HEAD) != 0 && !(node.tag == tt.tagTitle))) 1463 && this.configuration.HideEndTags == false)) 1464 { 1465 condFlushLine(fout, (this.configuration.IndentContent ? indent+this.configuration.spaces : indent)); 1466 1467 if (this.configuration.HideEndTags == false || !((node.tag.model & Dict.CM_OPT) != 0)) 1468 { 1469 printEndTag(fout, mode, indent, node); 1470 flushLine(fout, indent); 1471 } 1472 } 1473 else 1474 { 1475 if (this.configuration.HideEndTags == false || !((node.tag.model & Dict.CM_OPT) != 0)) 1476 printEndTag(fout, mode, indent, node); 1477 1478 flushLine(fout, indent); 1479 } 1480 1481 if (this.configuration.IndentContent == false && 1482 node.next != null && 1483 this.configuration.HideEndTags == false && 1484 (node.tag.model & (Dict.CM_BLOCK|Dict.CM_LIST|Dict.CM_DEFLIST|Dict.CM_TABLE)) != 0) 1485 { 1486 flushLine(fout, indent); 1487 } 1488 } 1489 } 1490 } 1491 1492 public void printXMLTree(Out fout, short mode, int indent, 1493 Lexer lexer, Node node) 1494 { 1495 TagTable tt = this.configuration.tt; 1496 1497 if (node == null) 1498 return; 1499 1500 if (node.type == Node.TextNode) 1501 { 1502 printText(fout, mode, indent, 1503 node.textarray, node.start, node.end); 1504 } 1505 else if (node.type == Node.CommentTag) 1506 { 1507 condFlushLine(fout, indent); 1508 printComment(fout, 0, node); 1509 condFlushLine(fout, 0); 1510 } 1511 else if (node.type == Node.RootNode) 1512 { 1513 Node content; 1514 1515 for (content = node.content; 1516 content != null; 1517 content = content.next) 1518 printXMLTree(fout, mode, indent, lexer, content); 1519 } 1520 else if (node.type == Node.DocTypeTag) 1521 printDocType(fout, indent, node); 1522 else if (node.type == Node.ProcInsTag) 1523 printPI(fout, indent, node); 1524 else if (node.type == Node.SectionTag) 1525 printSection(fout, indent, node); 1526 else if (node.type == Node.AspTag) 1527 printAsp(fout, indent, node); 1528 else if (node.type == Node.JsteTag) 1529 printJste(fout, indent, node); 1530 else if (node.type == Node.PhpTag) 1531 printPhp(fout, indent, node); 1532 else if ((node.tag.model & Dict.CM_EMPTY) != 0 || node.type == Node.StartEndTag) 1533 { 1534 condFlushLine(fout, indent); 1535 printTag(lexer, fout, mode, indent, node); 1536 flushLine(fout, indent); 1537 1538 if (node.next != null) 1539 flushLine(fout, indent); 1540 } 1541 else 1542 { 1543 Node content; 1544 boolean mixed = false; 1545 int cindent; 1546 1547 for (content = node.content; content != null; content = content.next) 1548 { 1549 if (content.type == Node.TextNode) 1550 { 1551 mixed = true; 1552 break; 1553 } 1554 } 1555 1556 condFlushLine(fout, indent); 1557 1558 if (ParserImpl.XMLPreserveWhiteSpace(node, tt)) 1559 { 1560 indent = 0; 1561 cindent = 0; 1562 mixed = false; 1563 } 1564 else if (mixed) 1565 cindent = indent; 1566 else 1567 cindent = indent + this.configuration.spaces; 1568 1569 printTag(lexer, fout, mode, indent, node); 1570 1571 if (!mixed) 1572 flushLine(fout, indent); 1573 1574 for (content = node.content; 1575 content != null; 1576 content = content.next) 1577 printXMLTree(fout, mode, cindent, lexer, content); 1578 1579 if (!mixed) 1580 condFlushLine(fout, cindent); 1581 printEndTag(fout, mode, indent, node); 1582 condFlushLine(fout, indent); 1583 1584 if (node.next != null) 1585 flushLine(fout, indent); 1586 } 1587 } 1588 1589 1590 1591 1592 1593 public int countSlides(Node node) 1594 { 1595 int n = 1; 1596 TagTable tt = this.configuration.tt; 1597 1598 for (node = node.content; node != null; node = node.next) 1599 if (node.tag == tt.tagH2) 1600 ++n; 1601 1602 return n; 1603 } 1604 1605 1609 private void printVertSpacer(Out fout, int indent) 1610 { 1611 condFlushLine(fout, indent); 1612 printString(fout, indent , 1613 "<img width=\"0\" height=\"0\" hspace=\"1\" SRC=\"dot.gif\" vspace=\"%d\" align=\"left\">"); 1614 condFlushLine(fout, indent); 1615 } 1616 1617 private void printNavBar(Out fout, int indent) 1618 { 1619 String buf; 1620 1621 condFlushLine(fout, indent); 1622 printString(fout, indent , "<center><small>"); 1623 1624 if (slide > 1) 1625 { 1626 buf = "<a HREF=\"slide" + 1627 (new Integer (slide - 1)).toString() + 1628 ".html\">previous</a> | "; 1629 printString(fout, indent , buf); 1630 condFlushLine(fout, indent); 1631 1632 if (slide < count) 1633 printString(fout, indent , "<a HREF=\"slide1.html\">start</a> | "); 1634 else 1635 printString(fout, indent , "<a HREF=\"slide1.html\">start</a>"); 1636 1637 condFlushLine(fout, indent); 1638 } 1639 1640 if (slide < count) 1641 { 1642 buf = "<a HREF=\"slide" + 1643 (new Integer (slide + 1)).toString() + 1644 ".html\">next</a>"; 1645 printString(fout, indent , buf); 1646 } 1647 1648 printString(fout, indent , "</small></center>"); 1649 condFlushLine(fout, indent); 1650 } 1651 1652 1658 public void printSlide(Out fout, short mode, int indent, Lexer lexer) 1659 { 1660 Node content, last; 1661 TagTable tt = this.configuration.tt; 1662 1663 1664 String s; 1665 s = "<div onclick=\"document.location='slide" + 1666 (new Integer (slide < count ? slide + 1 : 1)).toString() + 1667 ".html'\">"; 1668 printString(fout, indent, s); 1669 condFlushLine(fout, indent); 1670 1671 1672 if (slidecontent.tag == tt.tagH2) 1673 { 1674 printNavBar(fout, indent); 1675 1676 1677 1678 addC('<', linelen++); 1679 1680 1681 addC((int)Lexer.foldCase('h', 1682 this.configuration.UpperCaseTags, 1683 this.configuration.XmlTags), 1684 linelen++); 1685 addC((int)Lexer.foldCase('r', 1686 this.configuration.UpperCaseTags, 1687 this.configuration.XmlTags), 1688 linelen++); 1689 1690 if (this.configuration.XmlOut == true) 1691 printString(fout, indent , " />"); 1692 else 1693 addC('>', linelen++); 1694 1695 1696 if (this.configuration.IndentContent == true) 1697 condFlushLine(fout, indent); 1698 1699 1700 1701 1702 1703 1704 printTree(fout, mode, 1705 (this.configuration.IndentContent ? indent+this.configuration.spaces : indent), lexer, slidecontent); 1706 1707 slidecontent = slidecontent.next; 1708 } 1709 1710 1711 1712 last = null; 1713 content = slidecontent; 1714 1715 for (; content != null; content = content.next) 1716 { 1717 if (content.tag == tt.tagH2) 1718 break; 1719 1720 1721 if (last != null && !this.configuration.IndentContent && last.type == Node.TextNode && 1722 content.tag != null && (content.tag.model & Dict.CM_BLOCK) != 0) 1723 { 1724 flushLine(fout, indent); 1725 flushLine(fout, indent); 1726 } 1727 1728 printTree(fout, mode, 1729 (this.configuration.IndentContent ? indent+this.configuration.spaces : indent), lexer, content); 1730 1731 last = content; 1732 } 1733 1734 slidecontent = content; 1735 1736 1737 1738 condFlushLine(fout, indent); 1739 1740 printString(fout, indent , "<br clear=\"all\">"); 1741 condFlushLine(fout, indent); 1742 1743 addC('<', linelen++); 1744 1745 1746 addC((int)Lexer.foldCase('h', 1747 this.configuration.UpperCaseTags, 1748 this.configuration.XmlTags), 1749 linelen++); 1750 addC((int)Lexer.foldCase('r', 1751 this.configuration.UpperCaseTags, 1752 this.configuration.XmlTags), 1753 linelen++); 1754 1755 if (this.configuration.XmlOut == true) 1756 printString(fout, indent , " />"); 1757 else 1758 addC('>', linelen++); 1759 1760 1761 if (this.configuration.IndentContent == true) 1762 condFlushLine(fout, indent); 1763 1764 printNavBar(fout, indent); 1765 1766 1767 printString(fout, indent, "</div>"); 1768 condFlushLine(fout, indent); 1769 } 1770 1771 1772 1775 1776 public void addTransitionEffect(Lexer lexer, Node root, short effect, double duration) 1777 { 1778 Node head = root.findHEAD(lexer.configuration.tt); 1779 String transition; 1780 1781 if (0 <= effect && effect <= 23) 1782 transition = "revealTrans(Duration=" + 1783 (new Double (duration)).toString() + 1784 ",Transition=" + effect + ")"; 1785 else 1786 transition = "blendTrans(Duration=" + 1787 (new Double (duration)).toString() + ")"; 1788 1789 if (head != null) 1790 { 1791 Node meta = lexer.inferredTag("meta"); 1792 meta.addAttribute("http-equiv", "Page-Enter"); 1793 meta.addAttribute("content", transition); 1794 Node.insertNodeAtStart(head, meta); 1795 } 1796 } 1797 1798 public void createSlides(Lexer lexer, Node root) 1799 { 1800 Node body; 1801 String buf; 1802 Out out = new OutImpl(); 1803 1804 body = root.findBody(lexer.configuration.tt); 1805 count = countSlides(body); 1806 slidecontent = body.content; 1807 addTransitionEffect(lexer, root, EFFECT_BLEND, 3.0); 1808 1809 for (slide = 1; slide <= count; ++slide) 1810 { 1811 buf = "slide" + slide + ".html"; 1812 out.state = StreamIn.FSM_ASCII; 1813 out.encoding = this.configuration.CharEncoding; 1814 1815 try 1816 { 1817 out.out = new FileOutputStream (buf); 1818 printTree(out, (short)0, 0, lexer, root); 1819 flushLine(out, 0); 1820 out.out.close(); 1821 } 1822 catch (IOException e) 1823 { 1824 System.err.println(buf + e.toString() ); 1825 } 1826 } 1827 1828 1833 1834 for (;;) 1835 { 1836 buf = "slide" + slide + "html"; 1837 1838 if (!(new File (buf)).delete()) 1839 break; 1840 1841 ++slide; 1842 } 1843 } 1844 1845} 1846 | Popular Tags |