Source Code Cross Referenced for PPrint.java in  » Groupware » hipergate » org » w3c » tidy » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Groupware » hipergate » org.w3c.tidy 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * @(#)PPrint.java   1.11 2000/08/16
0003:         *
0004:         */
0005:
0006:        package org.w3c.tidy;
0007:
0008:        /**
0009:         *
0010:         * Pretty print parse tree
0011:         *
0012:         * (c) 1998-2000 (W3C) MIT, INRIA, Keio University
0013:         * See Tidy.java for the copyright notice.
0014:         * Derived from <a href="http://www.w3.org/People/Raggett/tidy">
0015:         * HTML Tidy Release 4 Aug 2000</a>
0016:         *
0017:         * @author  Dave Raggett <dsr@w3.org>
0018:         * @author  Andy Quick <ac.quick@sympatico.ca> (translation to Java)
0019:         * @version 1.0, 1999/05/22
0020:         * @version 1.0.1, 1999/05/29
0021:         * @version 1.1, 1999/06/18 Java Bean
0022:         * @version 1.2, 1999/07/10 Tidy Release 7 Jul 1999
0023:         * @version 1.3, 1999/07/30 Tidy Release 26 Jul 1999
0024:         * @version 1.4, 1999/09/04 DOM support
0025:         * @version 1.5, 1999/10/23 Tidy Release 27 Sep 1999
0026:         * @version 1.6, 1999/11/01 Tidy Release 22 Oct 1999
0027:         * @version 1.7, 1999/12/06 Tidy Release 30 Nov 1999
0028:         * @version 1.8, 2000/01/22 Tidy Release 13 Jan 2000
0029:         * @version 1.9, 2000/06/03 Tidy Release 30 Apr 2000
0030:         * @version 1.10, 2000/07/22 Tidy Release 8 Jul 2000
0031:         * @version 1.11, 2000/08/16 Tidy Release 4 Aug 2000
0032:         */
0033:
0034:        /*
0035:         Block-level and unknown elements are printed on
0036:         new lines and their contents indented 2 spaces
0037:
0038:         Inline elements are printed inline.
0039:
0040:         Inline content is wrapped on spaces (except in
0041:         attribute values or preformatted text, after
0042:         start tags and before end tags
0043:         */
0044:
0045:        import java.io.FileOutputStream;
0046:        import java.io.File;
0047:
0048:        import java.io.IOException;
0049:        import java.io.FileNotFoundException;
0050:
0051:        public class PPrint {
0052:
0053:            /* page transition effects */
0054:
0055:            public static final short EFFECT_BLEND = -1;
0056:            public static final short EFFECT_BOX_IN = 0;
0057:            public static final short EFFECT_BOX_OUT = 1;
0058:            public static final short EFFECT_CIRCLE_IN = 2;
0059:            public static final short EFFECT_CIRCLE_OUT = 3;
0060:            public static final short EFFECT_WIPE_UP = 4;
0061:            public static final short EFFECT_WIPE_DOWN = 5;
0062:            public static final short EFFECT_WIPE_RIGHT = 6;
0063:            public static final short EFFECT_WIPE_LEFT = 7;
0064:            public static final short EFFECT_VERT_BLINDS = 8;
0065:            public static final short EFFECT_HORZ_BLINDS = 9;
0066:            public static final short EFFECT_CHK_ACROSS = 10;
0067:            public static final short EFFECT_CHK_DOWN = 11;
0068:            public static final short EFFECT_RND_DISSOLVE = 12;
0069:            public static final short EFFECT_SPLIT_VIRT_IN = 13;
0070:            public static final short EFFECT_SPLIT_VIRT_OUT = 14;
0071:            public static final short EFFECT_SPLIT_HORZ_IN = 15;
0072:            public static final short EFFECT_SPLIT_HORZ_OUT = 16;
0073:            public static final short EFFECT_STRIPS_LEFT_DOWN = 17;
0074:            public static final short EFFECT_STRIPS_LEFT_UP = 18;
0075:            public static final short EFFECT_STRIPS_RIGHT_DOWN = 19;
0076:            public static final short EFFECT_STRIPS_RIGHT_UP = 20;
0077:            public static final short EFFECT_RND_BARS_HORZ = 21;
0078:            public static final short EFFECT_RND_BARS_VERT = 22;
0079:            public static final short EFFECT_RANDOM = 23;
0080:
0081:            private static final short NORMAL = 0;
0082:            private static final short PREFORMATTED = 1;
0083:            private static final short COMMENT = 2;
0084:            private static final short ATTRIBVALUE = 4;
0085:            private static final short NOWRAP = 8;
0086:            private static final short CDATA = 16;
0087:
0088:            private int[] linebuf = null;
0089:            private int lbufsize = 0;
0090:            private int linelen = 0;
0091:            private int wraphere = 0;
0092:            private boolean inAttVal = false;
0093:            private boolean InString = false;
0094:
0095:            private int slide = 0;
0096:            private int count = 0;
0097:            private Node slidecontent = null;
0098:
0099:            private Configuration configuration;
0100:
0101:            public PPrint(Configuration configuration) {
0102:                this .configuration = configuration;
0103:            }
0104:
0105:            /*
0106:              1010  A
0107:              1011  B
0108:              1100  C
0109:              1101  D
0110:              1110  E
0111:              1111  F
0112:             */
0113:
0114:            /* return one less that the number of bytes used by UTF-8 char */
0115:            /* str points to 1st byte, *ch initialized to 1st byte */
0116:            public static int getUTF8(byte[] str, int start, MutableInteger ch) {
0117:                int c, n, i, bytes;
0118:
0119:                c = ((int) str[start]) & 0xFF; // Convert to unsigned.
0120:
0121:                if ((c & 0xE0) == 0xC0) /* 110X XXXX  two bytes */
0122:                {
0123:                    n = c & 31;
0124:                    bytes = 2;
0125:                } else if ((c & 0xF0) == 0xE0) /* 1110 XXXX  three bytes */
0126:                {
0127:                    n = c & 15;
0128:                    bytes = 3;
0129:                } else if ((c & 0xF8) == 0xF0) /* 1111 0XXX  four bytes */
0130:                {
0131:                    n = c & 7;
0132:                    bytes = 4;
0133:                } else if ((c & 0xFC) == 0xF8) /* 1111 10XX  five bytes */
0134:                {
0135:                    n = c & 3;
0136:                    bytes = 5;
0137:                } else if ((c & 0xFE) == 0xFC) /* 1111 110X  six bytes */
0138:
0139:                {
0140:                    n = c & 1;
0141:                    bytes = 6;
0142:                } else /* 0XXX XXXX one byte */
0143:                {
0144:                    ch.value = c;
0145:                    return 0;
0146:                }
0147:
0148:                /* successor bytes should have the form 10XX XXXX */
0149:                for (i = 1; i < bytes; ++i) {
0150:                    c = ((int) str[start + i]) & 0xFF; // Convert to unsigned.
0151:                    n = (n << 6) | (c & 0x3F);
0152:                }
0153:
0154:                ch.value = n;
0155:                return bytes - 1;
0156:            }
0157:
0158:            /* store char c as UTF-8 encoded byte stream */
0159:            public static int putUTF8(byte[] buf, int start, int c) {
0160:                if (c < 128)
0161:                    buf[start++] = (byte) c;
0162:                else if (c <= 0x7FF) {
0163:                    buf[start++] = (byte) (0xC0 | (c >> 6));
0164:                    buf[start++] = (byte) (0x80 | (c & 0x3F));
0165:                } else if (c <= 0xFFFF) {
0166:                    buf[start++] = (byte) (0xE0 | (c >> 12));
0167:                    buf[start++] = (byte) (0x80 | ((c >> 6) & 0x3F));
0168:                    buf[start++] = (byte) (0x80 | (c & 0x3F));
0169:                } else if (c <= 0x1FFFFF) {
0170:                    buf[start++] = (byte) (0xF0 | (c >> 18));
0171:                    buf[start++] = (byte) (0x80 | ((c >> 12) & 0x3F));
0172:                    buf[start++] = (byte) (0x80 | ((c >> 6) & 0x3F));
0173:                    buf[start++] = (byte) (0x80 | (c & 0x3F));
0174:                } else {
0175:                    buf[start++] = (byte) (0xF8 | (c >> 24));
0176:                    buf[start++] = (byte) (0x80 | ((c >> 18) & 0x3F));
0177:                    buf[start++] = (byte) (0x80 | ((c >> 12) & 0x3F));
0178:                    buf[start++] = (byte) (0x80 | ((c >> 6) & 0x3F));
0179:                    buf[start++] = (byte) (0x80 | (c & 0x3F));
0180:                }
0181:
0182:                return start;
0183:            }
0184:
0185:            private void addC(int c, int index) {
0186:                if (index + 1 >= lbufsize) {
0187:                    while (index + 1 >= lbufsize) {
0188:                        if (lbufsize == 0)
0189:                            lbufsize = 256;
0190:                        else
0191:                            lbufsize = lbufsize * 2;
0192:                    }
0193:
0194:                    int[] temp = new int[lbufsize];
0195:                    if (linebuf != null)
0196:                        System.arraycopy(linebuf, 0, temp, 0, index);
0197:                    linebuf = temp;
0198:                }
0199:
0200:                linebuf[index] = c;
0201:            }
0202:
0203:            private void wrapLine(Out fout, int indent) {
0204:                int i, p, q;
0205:
0206:                if (wraphere == 0)
0207:                    return;
0208:
0209:                for (i = 0; i < indent; ++i)
0210:                    fout.outc((int) ' ');
0211:
0212:                for (i = 0; i < wraphere; ++i)
0213:                    fout.outc(linebuf[i]);
0214:
0215:                if (InString) {
0216:                    fout.outc((int) ' ');
0217:                    fout.outc((int) '\\');
0218:                }
0219:
0220:                fout.newline();
0221:
0222:                if (linelen > wraphere) {
0223:                    p = 0;
0224:
0225:                    if (linebuf[wraphere] == ' ')
0226:                        ++wraphere;
0227:
0228:                    q = wraphere;
0229:                    addC('\0', linelen);
0230:
0231:                    while (true) {
0232:                        linebuf[p] = linebuf[q];
0233:                        if (linebuf[q] == 0)
0234:                            break;
0235:                        p++;
0236:                        q++;
0237:                    }
0238:                    linelen -= wraphere;
0239:                } else
0240:                    linelen = 0;
0241:
0242:                wraphere = 0;
0243:            }
0244:
0245:            private void wrapAttrVal(Out fout, int indent, boolean inString) {
0246:                int i, p, q;
0247:
0248:                for (i = 0; i < indent; ++i)
0249:                    fout.outc((int) ' ');
0250:
0251:                for (i = 0; i < wraphere; ++i)
0252:                    fout.outc(linebuf[i]);
0253:
0254:                fout.outc((int) ' ');
0255:
0256:                if (inString)
0257:                    fout.outc((int) '\\');
0258:
0259:                fout.newline();
0260:
0261:                if (linelen > wraphere) {
0262:                    p = 0;
0263:
0264:                    if (linebuf[wraphere] == ' ')
0265:                        ++wraphere;
0266:
0267:                    q = wraphere;
0268:                    addC('\0', linelen);
0269:
0270:                    while (true) {
0271:                        linebuf[p] = linebuf[q];
0272:                        if (linebuf[q] == 0)
0273:                            break;
0274:                        p++;
0275:                        q++;
0276:                    }
0277:                    linelen -= wraphere;
0278:                } else
0279:                    linelen = 0;
0280:
0281:                wraphere = 0;
0282:            }
0283:
0284:            public void flushLine(Out fout, int indent) {
0285:                int i;
0286:
0287:                if (linelen > 0) {
0288:                    if (indent + linelen >= this .configuration.wraplen)
0289:                        wrapLine(fout, indent);
0290:
0291:                    if (!inAttVal || this .configuration.IndentAttributes) {
0292:                        for (i = 0; i < indent; ++i)
0293:                            fout.outc((int) ' ');
0294:                    }
0295:
0296:                    for (i = 0; i < linelen; ++i)
0297:                        fout.outc(linebuf[i]);
0298:                }
0299:
0300:                fout.newline();
0301:                linelen = 0;
0302:                wraphere = 0;
0303:                inAttVal = false;
0304:            }
0305:
0306:            public void condFlushLine(Out fout, int indent) {
0307:                int i;
0308:
0309:                if (linelen > 0) {
0310:                    if (indent + linelen >= this .configuration.wraplen)
0311:                        wrapLine(fout, indent);
0312:
0313:                    if (!inAttVal || this .configuration.IndentAttributes) {
0314:                        for (i = 0; i < indent; ++i)
0315:                            fout.outc((int) ' ');
0316:                    }
0317:
0318:                    for (i = 0; i < linelen; ++i)
0319:                        fout.outc(linebuf[i]);
0320:
0321:                    fout.newline();
0322:                    linelen = 0;
0323:                    wraphere = 0;
0324:                    inAttVal = false;
0325:                }
0326:            }
0327:
0328:            private void printChar(int c, short mode) {
0329:                String entity;
0330:
0331:                if (c == ' '
0332:                        && !((mode & (PREFORMATTED | COMMENT | ATTRIBVALUE)) != 0)) {
0333:                    /* coerce a space character to a non-breaking space */
0334:                    if ((mode & NOWRAP) != 0) {
0335:                        /* by default XML doesn't define &nbsp; */
0336:                        if (this .configuration.NumEntities
0337:                                || this .configuration.XmlTags) {
0338:                            addC('&', linelen++);
0339:                            addC('#', linelen++);
0340:                            addC('1', linelen++);
0341:                            addC('6', linelen++);
0342:                            addC('0', linelen++);
0343:                            addC(';', linelen++);
0344:                        } else /* otherwise use named entity */
0345:                        {
0346:                            addC('&', linelen++);
0347:                            addC('n', linelen++);
0348:                            addC('b', linelen++);
0349:                            addC('s', linelen++);
0350:                            addC('p', linelen++);
0351:                            addC(';', linelen++);
0352:                        }
0353:                        return;
0354:                    } else
0355:                        wraphere = linelen;
0356:                }
0357:
0358:                /* comment characters are passed raw */
0359:                if ((mode & COMMENT) != 0) {
0360:                    addC(c, linelen++);
0361:                    return;
0362:                }
0363:
0364:                /* except in CDATA map < to &lt; etc. */
0365:                if (!((mode & CDATA) != 0)) {
0366:                    if (c == '<') {
0367:                        addC('&', linelen++);
0368:                        addC('l', linelen++);
0369:                        addC('t', linelen++);
0370:                        addC(';', linelen++);
0371:                        return;
0372:                    }
0373:
0374:                    if (c == '>') {
0375:                        addC('&', linelen++);
0376:                        addC('g', linelen++);
0377:                        addC('t', linelen++);
0378:                        addC(';', linelen++);
0379:                        return;
0380:                    }
0381:
0382:                    /*
0383:                      naked '&' chars can be left alone or
0384:                      quoted as &amp; The latter is required
0385:                      for XML where naked '&' are illegal.
0386:                     */
0387:                    if (c == '&' && this .configuration.QuoteAmpersand) {
0388:                        addC('&', linelen++);
0389:                        addC('a', linelen++);
0390:                        addC('m', linelen++);
0391:                        addC('p', linelen++);
0392:                        addC(';', linelen++);
0393:                        return;
0394:                    }
0395:
0396:                    if (c == '"' && this .configuration.QuoteMarks) {
0397:                        addC('&', linelen++);
0398:                        addC('q', linelen++);
0399:                        addC('u', linelen++);
0400:                        addC('o', linelen++);
0401:                        addC('t', linelen++);
0402:                        addC(';', linelen++);
0403:                        return;
0404:                    }
0405:
0406:                    if (c == '\'' && this .configuration.QuoteMarks) {
0407:                        addC('&', linelen++);
0408:                        addC('#', linelen++);
0409:                        addC('3', linelen++);
0410:                        addC('9', linelen++);
0411:                        addC(';', linelen++);
0412:                        return;
0413:                    }
0414:
0415:                    if (c == 160
0416:                            && this .configuration.CharEncoding != Configuration.RAW) {
0417:                        if (this .configuration.QuoteNbsp) {
0418:                            addC('&', linelen++);
0419:
0420:                            if (this .configuration.NumEntities) {
0421:                                addC('#', linelen++);
0422:                                addC('1', linelen++);
0423:                                addC('6', linelen++);
0424:                                addC('0', linelen++);
0425:                            } else {
0426:                                addC('n', linelen++);
0427:                                addC('b', linelen++);
0428:                                addC('s', linelen++);
0429:                                addC('p', linelen++);
0430:                            }
0431:
0432:                            addC(';', linelen++);
0433:                        } else
0434:                            addC(c, linelen++);
0435:
0436:                        return;
0437:                    }
0438:                }
0439:
0440:                /* otherwise ISO 2022 characters are passed raw */
0441:                if (this .configuration.CharEncoding == Configuration.ISO2022
0442:                        || this .configuration.CharEncoding == Configuration.RAW) {
0443:                    addC(c, linelen++);
0444:                    return;
0445:                }
0446:
0447:                /* if preformatted text, map &nbsp; to space */
0448:                if (c == 160 && ((mode & PREFORMATTED) != 0)) {
0449:                    addC(' ', linelen++);
0450:                    return;
0451:                }
0452:
0453:                /*
0454:                 Filters from Word and PowerPoint often use smart
0455:                 quotes resulting in character codes between 128
0456:                 and 159. Unfortunately, the corresponding HTML 4.0
0457:                 entities for these are not widely supported. The
0458:                 following converts dashes and quotation marks to
0459:                 the nearest ASCII equivalent. My thanks to
0460:                 Andrzej Novosiolov for his help with this code.
0461:                 */
0462:
0463:                if (this .configuration.MakeClean) {
0464:                    if (c >= 0x2013 && c <= 0x201E) {
0465:                        switch (c) {
0466:                        case 0x2013:
0467:                        case 0x2014:
0468:                            c = '-';
0469:                            break;
0470:                        case 0x2018:
0471:                        case 0x2019:
0472:                        case 0x201A:
0473:                            c = '\'';
0474:                            break;
0475:                        case 0x201C:
0476:                        case 0x201D:
0477:                        case 0x201E:
0478:                            c = '"';
0479:                            break;
0480:                        }
0481:                    }
0482:                }
0483:
0484:                /* don't map latin-1 chars to entities */
0485:                if (this .configuration.CharEncoding == Configuration.LATIN1) {
0486:                    if (c > 255) /* multi byte chars */
0487:                    {
0488:                        if (!this .configuration.NumEntities) {
0489:                            entity = EntityTable.getDefaultEntityTable()
0490:                                    .entityName((short) c);
0491:                            if (entity != null)
0492:                                entity = "&" + entity + ";";
0493:                            else
0494:                                entity = "&#" + c + ";";
0495:                        } else
0496:                            entity = "&#" + c + ";";
0497:
0498:                        for (int i = 0; i < entity.length(); i++)
0499:                            addC((int) entity.charAt(i), linelen++);
0500:
0501:                        return;
0502:                    }
0503:
0504:                    if (c > 126 && c < 160) {
0505:                        entity = "&#" + c + ";";
0506:
0507:                        for (int i = 0; i < entity.length(); i++)
0508:                            addC((int) entity.charAt(i), linelen++);
0509:
0510:                        return;
0511:                    }
0512:
0513:                    addC(c, linelen++);
0514:                    return;
0515:                }
0516:
0517:                /* don't map utf8 chars to entities */
0518:                if (this .configuration.CharEncoding == Configuration.UTF8) {
0519:                    addC(c, linelen++);
0520:                    return;
0521:                }
0522:
0523:                /* use numeric entities only  for XML */
0524:                if (this .configuration.XmlTags) {
0525:                    /* if ASCII use numeric entities for chars > 127 */
0526:                    if (c > 127
0527:                            && this .configuration.CharEncoding == Configuration.ASCII) {
0528:                        entity = "&#" + c + ";";
0529:
0530:                        for (int i = 0; i < entity.length(); i++)
0531:                            addC((int) entity.charAt(i), linelen++);
0532:
0533:                        return;
0534:                    }
0535:
0536:                    /* otherwise output char raw */
0537:                    addC(c, linelen++);
0538:                    return;
0539:                }
0540:
0541:                /* default treatment for ASCII */
0542:                if (c > 126 || (c < ' ' && c != '\t')) {
0543:                    if (!this .configuration.NumEntities) {
0544:                        entity = EntityTable.getDefaultEntityTable()
0545:                                .entityName((short) c);
0546:                        if (entity != null)
0547:                            entity = "&" + entity + ";";
0548:                        else
0549:                            entity = "&#" + c + ";";
0550:                    } else
0551:                        entity = "&#" + c + ";";
0552:
0553:                    for (int i = 0; i < entity.length(); i++)
0554:                        addC((int) entity.charAt(i), linelen++);
0555:
0556:                    return;
0557:                }
0558:
0559:                addC(c, linelen++);
0560:            }
0561:
0562:            /* 
0563:              The line buffer is uint not char so we can
0564:              hold Unicode values unencoded. The translation
0565:              to UTF-8 is deferred to the outc routine called
0566:              to flush the line buffer.
0567:             */
0568:            private void printText(Out fout, short mode, int indent,
0569:                    byte[] textarray, int start, int end) {
0570:                int i, c;
0571:                MutableInteger ci = new MutableInteger();
0572:
0573:                for (i = start; i < end; ++i) {
0574:                    if (indent + linelen >= this .configuration.wraplen)
0575:                        wrapLine(fout, indent);
0576:
0577:                    c = ((int) textarray[i]) & 0xFF; // Convert to unsigned.
0578:
0579:                    /* look for UTF-8 multibyte character */
0580:                    if (c > 0x7F) {
0581:                        i += getUTF8(textarray, i, ci);
0582:                        c = ci.value;
0583:                    }
0584:
0585:                    if (c == '\n') {
0586:                        flushLine(fout, indent);
0587:                        continue;
0588:                    }
0589:
0590:                    printChar(c, mode);
0591:                }
0592:            }
0593:
0594:            private void printString(Out fout, int indent, String str) {
0595:                for (int i = 0; i < str.length(); i++)
0596:                    addC((int) str.charAt(i), linelen++);
0597:            }
0598:
0599:            private void printAttrValue(Out fout, int indent, String value,
0600:                    int delim, boolean wrappable) {
0601:                int c;
0602:                MutableInteger ci = new MutableInteger();
0603:                boolean wasinstring = false;
0604:                byte[] valueChars = null;
0605:                int i;
0606:                short mode = (wrappable ? (short) (NORMAL | ATTRIBVALUE)
0607:                        : (short) (PREFORMATTED | ATTRIBVALUE));
0608:
0609:                if (value != null) {
0610:                    valueChars = Lexer.getBytes(value);
0611:                }
0612:
0613:                /* look for ASP, Tango or PHP instructions for computed attribute value */
0614:                if (valueChars != null && valueChars.length >= 5
0615:                        && valueChars[0] == '<') {
0616:                    if (valueChars[1] == '%' || valueChars[1] == '@'
0617:                            || (new String(valueChars, 0, 5)).equals("<?php"))
0618:                        mode |= CDATA;
0619:                }
0620:
0621:                if (delim == 0)
0622:                    delim = '"';
0623:
0624:                addC('=', linelen++);
0625:
0626:                /* don't wrap after "=" for xml documents */
0627:                if (!this .configuration.XmlOut) {
0628:
0629:                    if (indent + linelen < this .configuration.wraplen)
0630:                        wraphere = linelen;
0631:
0632:                    if (indent + linelen >= this .configuration.wraplen)
0633:                        wrapLine(fout, indent);
0634:
0635:                    if (indent + linelen < this .configuration.wraplen)
0636:                        wraphere = linelen;
0637:                    else
0638:                        condFlushLine(fout, indent);
0639:                }
0640:
0641:                addC(delim, linelen++);
0642:
0643:                if (value != null) {
0644:                    InString = false;
0645:
0646:                    i = 0;
0647:                    while (i < valueChars.length) {
0648:                        c = ((int) valueChars[i]) & 0xFF; // Convert to unsigned.
0649:
0650:                        if (wrappable
0651:                                && c == ' '
0652:                                && indent + linelen < this .configuration.wraplen) {
0653:                            wraphere = linelen;
0654:                            wasinstring = InString;
0655:                        }
0656:
0657:                        if (wrappable
0658:                                && wraphere > 0
0659:                                && indent + linelen >= this .configuration.wraplen)
0660:                            wrapAttrVal(fout, indent, wasinstring);
0661:
0662:                        if (c == delim) {
0663:                            String entity;
0664:
0665:                            entity = (c == '"' ? "&quot;" : "&#39;");
0666:
0667:                            for (int j = 0; j < entity.length(); j++)
0668:                                addC(entity.charAt(j), linelen++);
0669:
0670:                            ++i;
0671:                            continue;
0672:                        } else if (c == '"') {
0673:                            if (this .configuration.QuoteMarks) {
0674:                                addC('&', linelen++);
0675:                                addC('q', linelen++);
0676:                                addC('u', linelen++);
0677:                                addC('o', linelen++);
0678:                                addC('t', linelen++);
0679:                                addC(';', linelen++);
0680:                            } else
0681:                                addC('"', linelen++);
0682:
0683:                            if (delim == '\'')
0684:                                InString = !InString;
0685:
0686:                            ++i;
0687:                            continue;
0688:                        } else if (c == '\'') {
0689:                            if (this .configuration.QuoteMarks) {
0690:                                addC('&', linelen++);
0691:                                addC('#', linelen++);
0692:                                addC('3', linelen++);
0693:                                addC('9', linelen++);
0694:                                addC(';', linelen++);
0695:                            } else
0696:                                addC('\'', linelen++);
0697:
0698:                            if (delim == '"')
0699:                                InString = !InString;
0700:
0701:                            ++i;
0702:                            continue;
0703:                        }
0704:
0705:                        /* look for UTF-8 multibyte character */
0706:                        if (c > 0x7F) {
0707:                            i += getUTF8(valueChars, i, ci);
0708:                            c = ci.value;
0709:                        }
0710:
0711:                        ++i;
0712:
0713:                        if (c == '\n') {
0714:                            flushLine(fout, indent);
0715:                            continue;
0716:                        }
0717:
0718:                        printChar(c, mode);
0719:                    }
0720:                }
0721:
0722:                InString = false;
0723:                addC(delim, linelen++);
0724:            }
0725:
0726:            private void printAttribute(Out fout, int indent, Node node,
0727:                    AttVal attr) {
0728:                String name;
0729:                boolean wrappable = false;
0730:
0731:                if (this .configuration.IndentAttributes) {
0732:                    flushLine(fout, indent);
0733:                    indent += this .configuration.spaces;
0734:                }
0735:
0736:                name = attr.attribute;
0737:
0738:                if (indent + linelen >= this .configuration.wraplen)
0739:                    wrapLine(fout, indent);
0740:
0741:                if (!this .configuration.XmlTags && !this .configuration.XmlOut
0742:                        && attr.dict != null) {
0743:                    if (AttributeTable.getDefaultAttributeTable()
0744:                            .isScript(name))
0745:                        wrappable = this .configuration.WrapScriptlets;
0746:                    else if (!attr.dict.nowrap
0747:                            && this .configuration.WrapAttVals)
0748:                        wrappable = true;
0749:                }
0750:
0751:                if (indent + linelen < this .configuration.wraplen) {
0752:                    wraphere = linelen;
0753:                    addC(' ', linelen++);
0754:                } else {
0755:                    condFlushLine(fout, indent);
0756:                    addC(' ', linelen++);
0757:                }
0758:
0759:                for (int i = 0; i < name.length(); i++)
0760:                    addC((int) Lexer.foldCase(name.charAt(i),
0761:                            this .configuration.UpperCaseAttrs,
0762:                            this .configuration.XmlTags), linelen++);
0763:
0764:                if (indent + linelen >= this .configuration.wraplen)
0765:                    wrapLine(fout, indent);
0766:
0767:                if (attr.value == null) {
0768:                    if (this .configuration.XmlTags || this .configuration.XmlOut)
0769:                        printAttrValue(fout, indent, attr.attribute,
0770:                                attr.delim, true);
0771:                    else if (!attr.isBoolAttribute() && !Node.isNewNode(node))
0772:                        printAttrValue(fout, indent, "", attr.delim, true);
0773:                    else if (indent + linelen < this .configuration.wraplen)
0774:                        wraphere = linelen;
0775:
0776:                } else
0777:                    printAttrValue(fout, indent, attr.value, attr.delim,
0778:                            wrappable);
0779:            }
0780:
0781:            private void printAttrs(Out fout, int indent, Node node, AttVal attr) {
0782:                if (attr != null) {
0783:                    if (attr.next != null)
0784:                        printAttrs(fout, indent, node, attr.next);
0785:
0786:                    if (attr.attribute != null)
0787:                        printAttribute(fout, indent, node, attr);
0788:                    else if (attr.asp != null) {
0789:                        addC(' ', linelen++);
0790:                        printAsp(fout, indent, attr.asp);
0791:                    } else if (attr.php != null) {
0792:                        addC(' ', linelen++);
0793:                        printPhp(fout, indent, attr.php);
0794:                    }
0795:                }
0796:
0797:                /* add xml:space attribute to pre and other elements */
0798:                if (configuration.XmlOut
0799:                        && configuration.XmlSpace
0800:                        && ParserImpl.XMLPreserveWhiteSpace(node,
0801:                                configuration.tt)
0802:                        && node.getAttrByName("xml:space") == null)
0803:                    printString(fout, indent, " xml:space=\"preserve\"");
0804:            }
0805:
0806:            /*
0807:             Line can be wrapped immediately after inline start tag provided
0808:             if follows a text node ending in a space, or it parent is an
0809:             inline element that that rule applies to. This behaviour was
0810:             reverse engineered from Netscape 3.0
0811:             */
0812:            private static boolean afterSpace(Node node) {
0813:                Node prev;
0814:                int c;
0815:
0816:                if (node == null || node.tag == null
0817:                        || !((node.tag.model & Dict.CM_INLINE) != 0))
0818:                    return true;
0819:
0820:                prev = node.prev;
0821:
0822:                if (prev != null) {
0823:                    if (prev.type == Node.TextNode && prev.end > prev.start) {
0824:                        c = ((int) prev.textarray[prev.end - 1]) & 0xFF; // Convert to unsigned.
0825:
0826:                        if (c == 160 || c == ' ' || c == '\n')
0827:                            return true;
0828:                    }
0829:
0830:                    return false;
0831:                }
0832:
0833:                return afterSpace(node.parent);
0834:            }
0835:
0836:            private void printTag(Lexer lexer, Out fout, short mode,
0837:                    int indent, Node node) {
0838:                char c;
0839:                String p;
0840:                TagTable tt = this .configuration.tt;
0841:
0842:                addC('<', linelen++);
0843:
0844:                if (node.type == Node.EndTag)
0845:                    addC('/', linelen++);
0846:
0847:                p = node.element;
0848:                for (int i = 0; i < p.length(); i++)
0849:                    addC((int) Lexer.foldCase(p.charAt(i),
0850:                            this .configuration.UpperCaseTags,
0851:                            this .configuration.XmlTags), linelen++);
0852:
0853:                printAttrs(fout, indent, node, node.attributes);
0854:
0855:                if ((this .configuration.XmlOut || lexer != null
0856:                        && lexer.isvoyager)
0857:                        && (node.type == Node.StartEndTag || (node.tag.model & Dict.CM_EMPTY) != 0)) {
0858:                    addC(' ', linelen++); /* compatibility hack */
0859:                    addC('/', linelen++);
0860:                }
0861:
0862:                addC('>', linelen++);
0863:                ;
0864:
0865:                if (node.type != Node.StartEndTag
0866:                        && !((mode & PREFORMATTED) != 0)) {
0867:                    if (indent + linelen >= this .configuration.wraplen)
0868:                        wrapLine(fout, indent);
0869:
0870:                    if (indent + linelen < this .configuration.wraplen) {
0871:                        /*
0872:                         wrap after start tag if is <br/> or if it's not
0873:                         inline or it is an empty tag followed by </a>
0874:                         */
0875:                        if (afterSpace(node)) {
0876:                            if (!((mode & NOWRAP) != 0)
0877:                                    && (!((node.tag.model & Dict.CM_INLINE) != 0)
0878:                                            || (node.tag == tt.tagBr) || (((node.tag.model & Dict.CM_EMPTY) != 0)
0879:                                            && node.next == null && node.parent.tag == tt.tagA))) {
0880:                                wraphere = linelen;
0881:                            }
0882:                        }
0883:                    } else
0884:                        condFlushLine(fout, indent);
0885:                }
0886:            }
0887:
0888:            private void printEndTag(Out fout, short mode, int indent, Node node) {
0889:                char c;
0890:                String p;
0891:
0892:                /*
0893:                  Netscape ignores SGML standard by not ignoring a
0894:                  line break before </A> or </U> etc. To avoid rendering 
0895:                  this as an underlined space, I disable line wrapping
0896:                  before inline end tags by the #if 0 ... #endif
0897:                 */
0898:                if (false) {
0899:                    if (indent + linelen < this .configuration.wraplen
0900:                            && !((mode & NOWRAP) != 0))
0901:                        wraphere = linelen;
0902:                }
0903:
0904:                addC('<', linelen++);
0905:                addC('/', linelen++);
0906:
0907:                p = node.element;
0908:                for (int i = 0; i < p.length(); i++)
0909:                    addC((int) Lexer.foldCase(p.charAt(i),
0910:                            this .configuration.UpperCaseTags,
0911:                            this .configuration.XmlTags), linelen++);
0912:
0913:                addC('>', linelen++);
0914:            }
0915:
0916:            private void printComment(Out fout, int indent, Node node) {
0917:                if (indent + linelen < this .configuration.wraplen)
0918:                    wraphere = linelen;
0919:
0920:                addC('<', linelen++);
0921:                addC('!', linelen++);
0922:                addC('-', linelen++);
0923:                addC('-', linelen++);
0924:                if (false) {
0925:                    if (linelen < this .configuration.wraplen)
0926:                        wraphere = linelen;
0927:                }
0928:                printText(fout, COMMENT, indent, node.textarray, node.start,
0929:                        node.end);
0930:                if (false) {
0931:                    if (indent + linelen < this .configuration.wraplen)
0932:                        wraphere = linelen;
0933:                }
0934:                // See Lexer.java: AQ 8Jul2000
0935:                addC('-', linelen++);
0936:                addC('-', linelen++);
0937:                addC('>', linelen++);
0938:
0939:                if (node.linebreak)
0940:                    flushLine(fout, indent);
0941:            }
0942:
0943:            private void printDocType(Out fout, int indent, Node node) {
0944:                boolean q = this .configuration.QuoteMarks;
0945:
0946:                this .configuration.QuoteMarks = false;
0947:
0948:                if (indent + linelen < this .configuration.wraplen)
0949:                    wraphere = linelen;
0950:
0951:                condFlushLine(fout, indent);
0952:
0953:                addC('<', linelen++);
0954:                addC('!', linelen++);
0955:                addC('D', linelen++);
0956:                addC('O', linelen++);
0957:                addC('C', linelen++);
0958:                addC('T', linelen++);
0959:                addC('Y', linelen++);
0960:                addC('P', linelen++);
0961:                addC('E', linelen++);
0962:                addC(' ', linelen++);
0963:
0964:                if (indent + linelen < this .configuration.wraplen)
0965:                    wraphere = linelen;
0966:
0967:                printText(fout, (short) 0, indent, node.textarray, node.start,
0968:                        node.end);
0969:
0970:                if (linelen < this .configuration.wraplen)
0971:                    wraphere = linelen;
0972:
0973:                addC('>', linelen++);
0974:                this .configuration.QuoteMarks = q;
0975:                condFlushLine(fout, indent);
0976:            }
0977:
0978:            private void printPI(Out fout, int indent, Node node) {
0979:                if (indent + linelen < this .configuration.wraplen)
0980:                    wraphere = linelen;
0981:
0982:                addC('<', linelen++);
0983:                addC('?', linelen++);
0984:
0985:                /* set CDATA to pass < and > unescaped */
0986:                printText(fout, CDATA, indent, node.textarray, node.start,
0987:                        node.end);
0988:
0989:                if (node.textarray[node.end - 1] != (byte) '?')
0990:                    addC('?', linelen++);
0991:
0992:                addC('>', linelen++);
0993:                condFlushLine(fout, indent);
0994:            }
0995:
0996:            /* note ASP and JSTE share <% ... %> syntax */
0997:            private void printAsp(Out fout, int indent, Node node) {
0998:                int savewraplen = this .configuration.wraplen;
0999:
1000:                /* disable wrapping if so requested */
1001:
1002:                if (!this .configuration.WrapAsp || !this .configuration.WrapJste)
1003:                    this .configuration.wraplen = 0xFFFFFF; /* a very large number */
1004:                if (false) { //#if 0
1005:                    if (indent + linelen < this .configuration.wraplen)
1006:                        wraphere = linelen;
1007:                } //#endif
1008:
1009:                addC('<', linelen++);
1010:                addC('%', linelen++);
1011:
1012:                printText(fout, (this .configuration.WrapAsp ? CDATA : COMMENT),
1013:                        indent, node.textarray, node.start, node.end);
1014:
1015:                addC('%', linelen++);
1016:                addC('>', linelen++);
1017:                /* condFlushLine(fout, indent); */
1018:                this .configuration.wraplen = savewraplen;
1019:            }
1020:
1021:            /* JSTE also supports <# ... #> syntax */
1022:            private void printJste(Out fout, int indent, Node node) {
1023:                int savewraplen = this .configuration.wraplen;
1024:
1025:                /* disable wrapping if so requested */
1026:
1027:                if (!this .configuration.WrapJste)
1028:                    this .configuration.wraplen = 0xFFFFFF; /* a very large number */
1029:
1030:                addC('<', linelen++);
1031:                addC('#', linelen++);
1032:
1033:                printText(fout,
1034:                        (this .configuration.WrapJste ? CDATA : COMMENT),
1035:                        indent, node.textarray, node.start, node.end);
1036:
1037:                addC('#', linelen++);
1038:                addC('>', linelen++);
1039:                /* condFlushLine(fout, indent); */
1040:                this .configuration.wraplen = savewraplen;
1041:            }
1042:
1043:            /* PHP is based on XML processing instructions */
1044:            private void printPhp(Out fout, int indent, Node node) {
1045:                int savewraplen = this .configuration.wraplen;
1046:
1047:                /* disable wrapping if so requested */
1048:
1049:                if (!this .configuration.WrapPhp)
1050:                    this .configuration.wraplen = 0xFFFFFF; /* a very large number */
1051:
1052:                if (false) { //#if 0
1053:                    if (indent + linelen < this .configuration.wraplen)
1054:                        wraphere = linelen;
1055:                } //#endif
1056:                addC('<', linelen++);
1057:                addC('?', linelen++);
1058:
1059:                printText(fout, (this .configuration.WrapPhp ? CDATA : COMMENT),
1060:                        indent, node.textarray, node.start, node.end);
1061:
1062:                addC('?', linelen++);
1063:                addC('>', linelen++);
1064:                /* PCondFlushLine(fout, indent); */
1065:                this .configuration.wraplen = savewraplen;
1066:            }
1067:
1068:            private void printCDATA(Out fout, int indent, Node node) {
1069:                int savewraplen = this .configuration.wraplen;
1070:
1071:                condFlushLine(fout, indent);
1072:
1073:                /* disable wrapping */
1074:
1075:                this .configuration.wraplen = 0xFFFFFF; /* a very large number */
1076:
1077:                addC('<', linelen++);
1078:                addC('!', linelen++);
1079:                addC('[', linelen++);
1080:                addC('C', linelen++);
1081:                addC('D', linelen++);
1082:                addC('A', linelen++);
1083:                addC('T', linelen++);
1084:                addC('A', linelen++);
1085:                addC('[', linelen++);
1086:
1087:                printText(fout, COMMENT, indent, node.textarray, node.start,
1088:                        node.end);
1089:
1090:                addC(']', linelen++);
1091:                addC(']', linelen++);
1092:                addC('>', linelen++);
1093:                condFlushLine(fout, indent);
1094:                this .configuration.wraplen = savewraplen;
1095:            }
1096:
1097:            private void printSection(Out fout, int indent, Node node) {
1098:                int savewraplen = this .configuration.wraplen;
1099:
1100:                /* disable wrapping if so requested */
1101:
1102:                if (!this .configuration.WrapSection)
1103:                    this .configuration.wraplen = 0xFFFFFF; /* a very large number */
1104:
1105:                if (false) { //#if 0
1106:                    if (indent + linelen < this .configuration.wraplen)
1107:                        wraphere = linelen;
1108:                } //#endif
1109:                addC('<', linelen++);
1110:                addC('!', linelen++);
1111:                addC('[', linelen++);
1112:
1113:                printText(fout, (this .configuration.WrapSection ? CDATA
1114:                        : COMMENT), indent, node.textarray, node.start,
1115:                        node.end);
1116:
1117:                addC(']', linelen++);
1118:                addC('>', linelen++);
1119:                /* PCondFlushLine(fout, indent); */
1120:                this .configuration.wraplen = savewraplen;
1121:            }
1122:
1123:            private boolean shouldIndent(Node node) {
1124:                TagTable tt = this .configuration.tt;
1125:
1126:                if (!this .configuration.IndentContent)
1127:                    return false;
1128:
1129:                if (this .configuration.SmartIndent) {
1130:                    if (node.content != null
1131:                            && ((node.tag.model & Dict.CM_NO_INDENT) != 0)) {
1132:                        for (node = node.content; node != null; node = node.next)
1133:                            if (node.tag != null
1134:                                    && (node.tag.model & Dict.CM_BLOCK) != 0)
1135:                                return true;
1136:
1137:                        return false;
1138:                    }
1139:
1140:                    if ((node.tag.model & Dict.CM_HEADING) != 0)
1141:                        return false;
1142:
1143:                    if (node.tag == tt.tagP)
1144:                        return false;
1145:
1146:                    if (node.tag == tt.tagTitle)
1147:                        return false;
1148:                }
1149:
1150:                if ((node.tag.model & (Dict.CM_FIELD | Dict.CM_OBJECT)) != 0)
1151:                    return true;
1152:
1153:                if (node.tag == tt.tagMap)
1154:                    return true;
1155:
1156:                return !((node.tag.model & Dict.CM_INLINE) != 0);
1157:            }
1158:
1159:            public void printTree(Out fout, short mode, int indent,
1160:                    Lexer lexer, Node node) {
1161:                Node content, last;
1162:                TagTable tt = this .configuration.tt;
1163:
1164:                if (node == null)
1165:                    return;
1166:
1167:                if (node.type == Node.TextNode)
1168:                    printText(fout, mode, indent, node.textarray, node.start,
1169:                            node.end);
1170:                else if (node.type == Node.CommentTag) {
1171:                    printComment(fout, indent, node);
1172:                } else if (node.type == Node.RootNode) {
1173:                    for (content = node.content; content != null; content = content.next)
1174:                        printTree(fout, mode, indent, lexer, content);
1175:                } else if (node.type == Node.DocTypeTag)
1176:                    printDocType(fout, indent, node);
1177:                else if (node.type == Node.ProcInsTag)
1178:                    printPI(fout, indent, node);
1179:                else if (node.type == Node.CDATATag)
1180:                    printCDATA(fout, indent, node);
1181:                else if (node.type == Node.SectionTag)
1182:                    printSection(fout, indent, node);
1183:                else if (node.type == Node.AspTag)
1184:                    printAsp(fout, indent, node);
1185:                else if (node.type == Node.JsteTag)
1186:                    printJste(fout, indent, node);
1187:                else if (node.type == Node.PhpTag)
1188:                    printPhp(fout, indent, node);
1189:                else if ((node.tag.model & Dict.CM_EMPTY) != 0
1190:                        || node.type == Node.StartEndTag) {
1191:                    if (!((node.tag.model & Dict.CM_INLINE) != 0))
1192:                        condFlushLine(fout, indent);
1193:
1194:                    if (node.tag == tt.tagBr && node.prev != null
1195:                            && node.prev.tag != tt.tagBr
1196:                            && this .configuration.BreakBeforeBR)
1197:                        flushLine(fout, indent);
1198:
1199:                    if (this .configuration.MakeClean && node.tag == tt.tagWbr)
1200:                        printString(fout, indent, " ");
1201:                    else
1202:                        printTag(lexer, fout, mode, indent, node);
1203:
1204:                    if (node.tag == tt.tagParam || node.tag == tt.tagArea)
1205:                        condFlushLine(fout, indent);
1206:                    else if (node.tag == tt.tagBr || node.tag == tt.tagHr)
1207:                        flushLine(fout, indent);
1208:                } else /* some kind of container element */
1209:                {
1210:                    if (node.tag != null
1211:                            && node.tag.parser == ParserImpl.getParsePre()) {
1212:                        condFlushLine(fout, indent);
1213:
1214:                        indent = 0;
1215:                        condFlushLine(fout, indent);
1216:                        printTag(lexer, fout, mode, indent, node);
1217:                        flushLine(fout, indent);
1218:
1219:                        for (content = node.content; content != null; content = content.next)
1220:                            printTree(fout,
1221:                                    (short) (mode | PREFORMATTED | NOWRAP),
1222:                                    indent, lexer, content);
1223:
1224:                        condFlushLine(fout, indent);
1225:                        printEndTag(fout, mode, indent, node);
1226:                        flushLine(fout, indent);
1227:
1228:                        if (this .configuration.IndentContent == false
1229:                                && node.next != null)
1230:                            flushLine(fout, indent);
1231:                    } else if (node.tag == tt.tagStyle
1232:                            || node.tag == tt.tagScript) {
1233:                        condFlushLine(fout, indent);
1234:
1235:                        indent = 0;
1236:                        condFlushLine(fout, indent);
1237:                        printTag(lexer, fout, mode, indent, node);
1238:                        flushLine(fout, indent);
1239:
1240:                        for (content = node.content; content != null; content = content.next)
1241:                            printTree(fout, (short) (mode | PREFORMATTED
1242:                                    | NOWRAP | CDATA), indent, lexer, content);
1243:
1244:                        condFlushLine(fout, indent);
1245:                        printEndTag(fout, mode, indent, node);
1246:                        flushLine(fout, indent);
1247:
1248:                        if (this .configuration.IndentContent == false
1249:                                && node.next != null)
1250:                            flushLine(fout, indent);
1251:                    } else if ((node.tag.model & Dict.CM_INLINE) != 0) {
1252:                        if (this .configuration.MakeClean) {
1253:                            /* discards <font> and </font> tags */
1254:                            if (node.tag == tt.tagFont) {
1255:                                for (content = node.content; content != null; content = content.next)
1256:                                    printTree(fout, mode, indent, lexer,
1257:                                            content);
1258:                                return;
1259:                            }
1260:
1261:                            /* replace <nobr>...</nobr> by &nbsp; or &#160; etc. */
1262:                            if (node.tag == tt.tagNobr) {
1263:                                for (content = node.content; content != null; content = content.next)
1264:                                    printTree(fout, (short) (mode | NOWRAP),
1265:                                            indent, lexer, content);
1266:                                return;
1267:                            }
1268:                        }
1269:
1270:                        /* otherwise a normal inline element */
1271:
1272:                        printTag(lexer, fout, mode, indent, node);
1273:
1274:                        /* indent content for SELECT, TEXTAREA, MAP, OBJECT and APPLET */
1275:
1276:                        if (shouldIndent(node)) {
1277:                            condFlushLine(fout, indent);
1278:                            indent += this .configuration.spaces;
1279:
1280:                            for (content = node.content; content != null; content = content.next)
1281:                                printTree(fout, mode, indent, lexer, content);
1282:
1283:                            condFlushLine(fout, indent);
1284:                            indent -= this .configuration.spaces;
1285:                            condFlushLine(fout, indent);
1286:                        } else {
1287:
1288:                            for (content = node.content; content != null; content = content.next)
1289:                                printTree(fout, mode, indent, lexer, content);
1290:                        }
1291:
1292:                        printEndTag(fout, mode, indent, node);
1293:                    } else /* other tags */
1294:                    {
1295:                        condFlushLine(fout, indent);
1296:
1297:                        if (this .configuration.SmartIndent && node.prev != null)
1298:                            flushLine(fout, indent);
1299:
1300:                        if (this .configuration.HideEndTags == false
1301:                                || !(node.tag != null && ((node.tag.model & Dict.CM_OMITST) != 0))) {
1302:                            printTag(lexer, fout, mode, indent, node);
1303:
1304:                            if (shouldIndent(node))
1305:                                condFlushLine(fout, indent);
1306:                            else if ((node.tag.model & Dict.CM_HTML) != 0
1307:                                    || node.tag == tt.tagNoframes
1308:                                    || ((node.tag.model & Dict.CM_HEAD) != 0 && !(node.tag == tt.tagTitle)))
1309:                                flushLine(fout, indent);
1310:                        }
1311:
1312:                        if (node.tag == tt.tagBody
1313:                                && this .configuration.BurstSlides)
1314:                            printSlide(fout, mode,
1315:                                    (this .configuration.IndentContent ? indent
1316:                                            + this .configuration.spaces
1317:                                            : indent), lexer);
1318:                        else {
1319:                            last = null;
1320:
1321:                            for (content = node.content; content != null; content = content.next) {
1322:                                /* kludge for naked text before block level tag */
1323:                                if (last != null
1324:                                        && !this .configuration.IndentContent
1325:                                        && last.type == Node.TextNode
1326:                                        && content.tag != null
1327:                                        && (content.tag.model & Dict.CM_BLOCK) != 0) {
1328:                                    flushLine(fout, indent);
1329:                                    flushLine(fout, indent);
1330:                                }
1331:
1332:                                printTree(fout, mode,
1333:                                        (shouldIndent(node) ? indent
1334:                                                + this .configuration.spaces
1335:                                                : indent), lexer, content);
1336:
1337:                                last = content;
1338:                            }
1339:                        }
1340:
1341:                        /* don't flush line for td and th */
1342:                        if (shouldIndent(node)
1343:                                || (((node.tag.model & Dict.CM_HTML) != 0
1344:                                        || node.tag == tt.tagNoframes || ((node.tag.model & Dict.CM_HEAD) != 0 && !(node.tag == tt.tagTitle))) && this .configuration.HideEndTags == false)) {
1345:                            condFlushLine(fout,
1346:                                    (this .configuration.IndentContent ? indent
1347:                                            + this .configuration.spaces
1348:                                            : indent));
1349:
1350:                            if (this .configuration.HideEndTags == false
1351:                                    || !((node.tag.model & Dict.CM_OPT) != 0)) {
1352:                                printEndTag(fout, mode, indent, node);
1353:                                flushLine(fout, indent);
1354:                            }
1355:                        } else {
1356:                            if (this .configuration.HideEndTags == false
1357:                                    || !((node.tag.model & Dict.CM_OPT) != 0))
1358:                                printEndTag(fout, mode, indent, node);
1359:
1360:                            flushLine(fout, indent);
1361:                        }
1362:
1363:                        if (this .configuration.IndentContent == false
1364:                                && node.next != null
1365:                                && this .configuration.HideEndTags == false
1366:                                && (node.tag.model & (Dict.CM_BLOCK
1367:                                        | Dict.CM_LIST | Dict.CM_DEFLIST | Dict.CM_TABLE)) != 0) {
1368:                            flushLine(fout, indent);
1369:                        }
1370:                    }
1371:                }
1372:            }
1373:
1374:            public void printXMLTree(Out fout, short mode, int indent,
1375:                    Lexer lexer, Node node) {
1376:                TagTable tt = this .configuration.tt;
1377:
1378:                if (node == null)
1379:                    return;
1380:
1381:                if (node.type == Node.TextNode) {
1382:                    printText(fout, mode, indent, node.textarray, node.start,
1383:                            node.end);
1384:                } else if (node.type == Node.CommentTag) {
1385:                    condFlushLine(fout, indent);
1386:                    printComment(fout, 0, node);
1387:                    condFlushLine(fout, 0);
1388:                } else if (node.type == Node.RootNode) {
1389:                    Node content;
1390:
1391:                    for (content = node.content; content != null; content = content.next)
1392:                        printXMLTree(fout, mode, indent, lexer, content);
1393:                } else if (node.type == Node.DocTypeTag)
1394:                    printDocType(fout, indent, node);
1395:                else if (node.type == Node.ProcInsTag)
1396:                    printPI(fout, indent, node);
1397:                else if (node.type == Node.SectionTag)
1398:                    printSection(fout, indent, node);
1399:                else if (node.type == Node.AspTag)
1400:                    printAsp(fout, indent, node);
1401:                else if (node.type == Node.JsteTag)
1402:                    printJste(fout, indent, node);
1403:                else if (node.type == Node.PhpTag)
1404:                    printPhp(fout, indent, node);
1405:                else if ((node.tag.model & Dict.CM_EMPTY) != 0
1406:                        || node.type == Node.StartEndTag) {
1407:                    condFlushLine(fout, indent);
1408:                    printTag(lexer, fout, mode, indent, node);
1409:                    flushLine(fout, indent);
1410:
1411:                    if (node.next != null)
1412:                        flushLine(fout, indent);
1413:                } else /* some kind of container element */
1414:                {
1415:                    Node content;
1416:                    boolean mixed = false;
1417:                    int cindent;
1418:
1419:                    for (content = node.content; content != null; content = content.next) {
1420:                        if (content.type == Node.TextNode) {
1421:                            mixed = true;
1422:                            break;
1423:                        }
1424:                    }
1425:
1426:                    condFlushLine(fout, indent);
1427:
1428:                    if (ParserImpl.XMLPreserveWhiteSpace(node, tt)) {
1429:                        indent = 0;
1430:                        cindent = 0;
1431:                        mixed = false;
1432:                    } else if (mixed)
1433:                        cindent = indent;
1434:                    else
1435:                        cindent = indent + this .configuration.spaces;
1436:
1437:                    printTag(lexer, fout, mode, indent, node);
1438:
1439:                    if (!mixed)
1440:                        flushLine(fout, indent);
1441:
1442:                    for (content = node.content; content != null; content = content.next)
1443:                        printXMLTree(fout, mode, cindent, lexer, content);
1444:
1445:                    if (!mixed)
1446:                        condFlushLine(fout, cindent);
1447:                    printEndTag(fout, mode, indent, node);
1448:                    condFlushLine(fout, indent);
1449:
1450:                    if (node.next != null)
1451:                        flushLine(fout, indent);
1452:                }
1453:            }
1454:
1455:            /* split parse tree by h2 elements and output to separate files */
1456:
1457:            /* counts number of h2 children belonging to node */
1458:            public int countSlides(Node node) {
1459:                int n = 1;
1460:                TagTable tt = this .configuration.tt;
1461:
1462:                for (node = node.content; node != null; node = node.next)
1463:                    if (node.tag == tt.tagH2)
1464:                        ++n;
1465:
1466:                return n;
1467:            }
1468:
1469:            /*
1470:               inserts a space gif called "dot.gif" to ensure
1471:               that the  slide is at least n pixels high
1472:             */
1473:            private void printVertSpacer(Out fout, int indent) {
1474:                condFlushLine(fout, indent);
1475:                printString(
1476:                        fout,
1477:                        indent,
1478:                        "<img width=\"0\" height=\"0\" hspace=\"1\" src=\"dot.gif\" vspace=\"%d\" align=\"left\">");
1479:                condFlushLine(fout, indent);
1480:            }
1481:
1482:            private void printNavBar(Out fout, int indent) {
1483:                String buf;
1484:
1485:                condFlushLine(fout, indent);
1486:                printString(fout, indent, "<center><small>");
1487:
1488:                if (slide > 1) {
1489:                    buf = "<a href=\"slide"
1490:                            + (new Integer(slide - 1)).toString()
1491:                            + ".html\">previous</a> | ";
1492:                    printString(fout, indent, buf);
1493:                    condFlushLine(fout, indent);
1494:
1495:                    if (slide < count)
1496:                        printString(fout, indent,
1497:                                "<a href=\"slide1.html\">start</a> | ");
1498:                    else
1499:                        printString(fout, indent,
1500:                                "<a href=\"slide1.html\">start</a>");
1501:
1502:                    condFlushLine(fout, indent);
1503:                }
1504:
1505:                if (slide < count) {
1506:                    buf = "<a href=\"slide"
1507:                            + (new Integer(slide + 1)).toString()
1508:                            + ".html\">next</a>";
1509:                    printString(fout, indent, buf);
1510:                }
1511:
1512:                printString(fout, indent, "</small></center>");
1513:                condFlushLine(fout, indent);
1514:            }
1515:
1516:            /*
1517:              Called from printTree to print the content of a slide from
1518:              the node slidecontent. On return slidecontent points to the
1519:              node starting the next slide or null. The variables slide
1520:              and count are used to customise the navigation bar.
1521:             */
1522:            public void printSlide(Out fout, short mode, int indent, Lexer lexer) {
1523:                Node content, last;
1524:                TagTable tt = this .configuration.tt;
1525:
1526:                /* insert div for onclick handler */
1527:                String s;
1528:                s = "<div onclick=\"document.location='slide"
1529:                        + (new Integer(slide < count ? slide + 1 : 1))
1530:                                .toString() + ".html'\">";
1531:                printString(fout, indent, s);
1532:                condFlushLine(fout, indent);
1533:
1534:                /* first print the h2 element and navbar */
1535:                if (slidecontent.tag == tt.tagH2) {
1536:                    printNavBar(fout, indent);
1537:
1538:                    /* now print an hr after h2 */
1539:
1540:                    addC('<', linelen++);
1541:
1542:                    addC((int) Lexer.foldCase('h',
1543:                            this .configuration.UpperCaseTags,
1544:                            this .configuration.XmlTags), linelen++);
1545:                    addC((int) Lexer.foldCase('r',
1546:                            this .configuration.UpperCaseTags,
1547:                            this .configuration.XmlTags), linelen++);
1548:
1549:                    if (this .configuration.XmlOut == true)
1550:                        printString(fout, indent, " />");
1551:                    else
1552:                        addC('>', linelen++);
1553:
1554:                    if (this .configuration.IndentContent == true)
1555:                        condFlushLine(fout, indent);
1556:
1557:                    /* PrintVertSpacer(fout, indent); */
1558:
1559:                    /*condFlushLine(fout, indent); */
1560:
1561:                    /* print the h2 element */
1562:                    printTree(fout, mode,
1563:                            (this .configuration.IndentContent ? indent
1564:                                    + this .configuration.spaces : indent),
1565:                            lexer, slidecontent);
1566:
1567:                    slidecontent = slidecontent.next;
1568:                }
1569:
1570:                /* now continue until we reach the next h2 */
1571:
1572:                last = null;
1573:                content = slidecontent;
1574:
1575:                for (; content != null; content = content.next) {
1576:                    if (content.tag == tt.tagH2)
1577:                        break;
1578:
1579:                    /* kludge for naked text before block level tag */
1580:                    if (last != null && !this .configuration.IndentContent
1581:                            && last.type == Node.TextNode
1582:                            && content.tag != null
1583:                            && (content.tag.model & Dict.CM_BLOCK) != 0) {
1584:                        flushLine(fout, indent);
1585:                        flushLine(fout, indent);
1586:                    }
1587:
1588:                    printTree(fout, mode,
1589:                            (this .configuration.IndentContent ? indent
1590:                                    + this .configuration.spaces : indent),
1591:                            lexer, content);
1592:
1593:                    last = content;
1594:                }
1595:
1596:                slidecontent = content;
1597:
1598:                /* now print epilog */
1599:
1600:                condFlushLine(fout, indent);
1601:
1602:                printString(fout, indent, "<br clear=\"all\">");
1603:                condFlushLine(fout, indent);
1604:
1605:                addC('<', linelen++);
1606:
1607:                addC((int) Lexer.foldCase('h',
1608:                        this .configuration.UpperCaseTags,
1609:                        this .configuration.XmlTags), linelen++);
1610:                addC((int) Lexer.foldCase('r',
1611:                        this .configuration.UpperCaseTags,
1612:                        this .configuration.XmlTags), linelen++);
1613:
1614:                if (this .configuration.XmlOut == true)
1615:                    printString(fout, indent, " />");
1616:                else
1617:                    addC('>', linelen++);
1618:
1619:                if (this .configuration.IndentContent == true)
1620:                    condFlushLine(fout, indent);
1621:
1622:                printNavBar(fout, indent);
1623:
1624:                /* end tag for div */
1625:                printString(fout, indent, "</div>");
1626:                condFlushLine(fout, indent);
1627:            }
1628:
1629:            /*
1630:            Add meta element for page transition effect, this works on IE but not NS
1631:             */
1632:
1633:            public void addTransitionEffect(Lexer lexer, Node root,
1634:                    short effect, double duration) {
1635:                Node head = root.findHEAD(lexer.configuration.tt);
1636:                String transition;
1637:
1638:                if (0 <= effect && effect <= 23)
1639:                    transition = "revealTrans(Duration="
1640:                            + (new Double(duration)).toString()
1641:                            + ",Transition=" + effect + ")";
1642:                else
1643:                    transition = "blendTrans(Duration="
1644:                            + (new Double(duration)).toString() + ")";
1645:
1646:                if (head != null) {
1647:                    Node meta = lexer.inferredTag("meta");
1648:                    meta.addAttribute("http-equiv", "Page-Enter");
1649:                    meta.addAttribute("content", transition);
1650:                    Node.insertNodeAtStart(head, meta);
1651:                }
1652:            }
1653:
1654:            public void createSlides(Lexer lexer, Node root) {
1655:                Node body;
1656:                String buf;
1657:                Out out = new OutImpl();
1658:
1659:                body = root.findBody(lexer.configuration.tt);
1660:                count = countSlides(body);
1661:                slidecontent = body.content;
1662:                addTransitionEffect(lexer, root, EFFECT_BLEND, 3.0);
1663:
1664:                for (slide = 1; slide <= count; ++slide) {
1665:                    buf = "slide" + slide + ".html";
1666:                    out.state = StreamIn.FSM_ASCII;
1667:                    out.encoding = this .configuration.CharEncoding;
1668:
1669:                    try {
1670:                        out.out = new FileOutputStream(buf);
1671:                        printTree(out, (short) 0, 0, lexer, root);
1672:                        flushLine(out, 0);
1673:                        out.out.close();
1674:                    } catch (IOException e) {
1675:                        System.err.println(buf + e.toString());
1676:                    }
1677:                }
1678:
1679:                /*
1680:                 delete superfluous slides by deleting slideN.html
1681:                 for N = count+1, count+2, etc. until no such file
1682:                 is found.     
1683:                 */
1684:
1685:                for (;;) {
1686:                    buf = "slide" + slide + "html";
1687:
1688:                    if (!(new File(buf)).delete())
1689:                        break;
1690:
1691:                    ++slide;
1692:                }
1693:            }
1694:
1695:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.