View Javadoc

1   /*
2    *  Java HTML Tidy - JTidy
3    *  HTML parser and pretty printer
4    *
5    *  Copyright (c) 1998-2000 World Wide Web Consortium (Massachusetts
6    *  Institute of Technology, Institut National de Recherche en
7    *  Informatique et en Automatique, Keio University). All Rights
8    *  Reserved.
9    *
10   *  Contributing Author(s):
11   *
12   *     Dave Raggett <dsr@w3.org>
13   *     Andy Quick <ac.quick@sympatico.ca> (translation to Java)
14   *     Gary L Peskin <garyp@firstech.com> (Java development)
15   *     Sami Lempinen <sami@lempinen.net> (release management)
16   *     Fabrizio Giustina <fgiust at users.sourceforge.net>
17   *
18   *  The contributing author(s) would like to thank all those who
19   *  helped with testing, bug fixes, and patience.  This wouldn't
20   *  have been possible without all of you.
21   *
22   *  COPYRIGHT NOTICE:
23   * 
24   *  This software and documentation is provided "as is," and
25   *  the copyright holders and contributing author(s) make no
26   *  representations or warranties, express or implied, including
27   *  but not limited to, warranties of merchantability or fitness
28   *  for any particular purpose or that the use of the software or
29   *  documentation will not infringe any third party patents,
30   *  copyrights, trademarks or other rights. 
31   *
32   *  The copyright holders and contributing author(s) will not be
33   *  liable for any direct, indirect, special or consequential damages
34   *  arising out of any use of the software or documentation, even if
35   *  advised of the possibility of such damage.
36   *
37   *  Permission is hereby granted to use, copy, modify, and distribute
38   *  this source code, or portions hereof, documentation and executables,
39   *  for any purpose, without fee, subject to the following restrictions:
40   *
41   *  1. The origin of this source code must not be misrepresented.
42   *  2. Altered versions must be plainly marked as such and must
43   *     not be misrepresented as being the original source.
44   *  3. This Copyright notice may not be removed or altered from any
45   *     source or altered source distribution.
46   * 
47   *  The copyright holders and contributing author(s) specifically
48   *  permit, without fee, and encourage the use of this source code
49   *  as a component for supporting the Hypertext Markup Language in
50   *  commercial products. If you use this source code in a product,
51   *  acknowledgment is not required but would be appreciated.
52   *
53   */
54  package org.w3c.tidy;
55  
56  import java.io.FileInputStream;
57  import java.io.FileNotFoundException;
58  import java.io.FileOutputStream;
59  import java.io.FileWriter;
60  import java.io.IOException;
61  import java.io.InputStream;
62  import java.io.OutputStream;
63  import java.io.PrintWriter;
64  import java.io.Serializable;
65  import java.util.HashMap;
66  import java.util.Map;
67  import java.util.Properties;
68  
69  
70  /***
71   * HTML parser and pretty printer.
72   * @author Dave Raggett <a href="mailto:dsr@w3.org">dsr@w3.org </a>
73   * @author Andy Quick <a href="mailto:ac.quick@sympatico.ca">ac.quick@sympatico.ca </a> (translation to Java)
74   * @author Fabrizio Giustina
75   * @version $Revision: 1.61 $ ($Author: fgiust $)
76   */
77  public class Tidy implements Serializable
78  {
79  
80      /***
81       * Serial Version UID to avoid problems during serialization.
82       */
83      static final long serialVersionUID = -2794371560623987718L;
84  
85      /***
86       * Alias for configuration options accepted in command line.
87       */
88      private static final Map CMDLINE_ALIAS = new HashMap();
89  
90      static
91      {
92          CMDLINE_ALIAS.put("xml", "input-xml");
93          CMDLINE_ALIAS.put("xml", "output-xhtml");
94          CMDLINE_ALIAS.put("asxml", "output-xhtml");
95          CMDLINE_ALIAS.put("ashtml", "output-html");
96          CMDLINE_ALIAS.put("omit", "hide-endtags");
97          CMDLINE_ALIAS.put("upper", "uppercase-tags");
98          CMDLINE_ALIAS.put("raw", "output-raw");
99          CMDLINE_ALIAS.put("numeric", "numeric-entities");
100         CMDLINE_ALIAS.put("change", "write-back");
101         CMDLINE_ALIAS.put("update", "write-back");
102         CMDLINE_ALIAS.put("modify", "write-back");
103         CMDLINE_ALIAS.put("errors", "only-errors");
104         CMDLINE_ALIAS.put("slides", "split");
105         CMDLINE_ALIAS.put("lang", "language");
106         CMDLINE_ALIAS.put("w", "wrap");
107         CMDLINE_ALIAS.put("file", "error-file");
108         CMDLINE_ALIAS.put("f", "error-file");
109     }
110 
111     /***
112      * Error output stream.
113      */
114     private PrintWriter errout;
115 
116     private PrintWriter stderr;
117 
118     private Configuration configuration;
119 
120     private String inputStreamName = "InputStream";
121 
122     private int parseErrors;
123 
124     private int parseWarnings;
125 
126     private Report report;
127 
128     /***
129      * Instantiates a new Tidy instance. It's reccomended that a new instance is used at each parsing.
130      */
131     public Tidy()
132     {
133         this.report = new Report();
134         configuration = new Configuration(this.report);
135         if (configuration == null)
136         {
137             return;
138         }
139 
140         AttributeTable at = AttributeTable.getDefaultAttributeTable();
141         if (at == null)
142         {
143             return;
144         }
145         TagTable tt = new TagTable();
146         if (tt == null)
147         {
148             return;
149         }
150         tt.setConfiguration(configuration);
151         configuration.tt = tt;
152         EntityTable et = EntityTable.getDefaultEntityTable();
153         if (et == null)
154         {
155             return;
156         }
157 
158         configuration.errfile = null;
159         stderr = new PrintWriter(System.err, true);
160         errout = stderr;
161     }
162 
163     /***
164      * Returns the actual configuration
165      * @return tidy configuration
166      */
167     public Configuration getConfiguration()
168     {
169         return configuration;
170     }
171 
172     public PrintWriter getStderr()
173     {
174         return stderr;
175     }
176 
177     /***
178      * ParseErrors - the number of errors that occurred in the most recent parse operation.
179      * @return number of errors that occurred in the most recent parse operation.
180      */
181     public int getParseErrors()
182     {
183         return parseErrors;
184     }
185 
186     /***
187      * ParseWarnings - the number of warnings that occurred in the most recent parse operation.
188      * @return number of warnings that occurred in the most recent parse operation.
189      */
190     public int getParseWarnings()
191     {
192         return parseWarnings;
193     }
194 
195     /***
196      * InputStreamName - the name of the input stream (printed in the header information).
197      * @param name input stream name
198      */
199     public void setInputStreamName(String name)
200     {
201         if (name != null)
202         {
203             inputStreamName = name;
204         }
205     }
206 
207     public String getInputStreamName()
208     {
209         return inputStreamName;
210     }
211 
212     /***
213      * Errout - the error output stream.
214      * @return error output stream.
215      */
216     public PrintWriter getErrout()
217     {
218         return errout;
219     }
220 
221     public void setErrout(PrintWriter out)
222     {
223         this.errout = out;
224     }
225 
226     /***
227      * Sets the configuration from a configuration file.
228      * @param filename configuration file name/path.
229      */
230     public void setConfigurationFromFile(String filename)
231     {
232         configuration.parseFile(filename);
233     }
234 
235     /***
236      * Sets the configuration from a properties object.
237      * @param props Properties object
238      */
239     public void setConfigurationFromProps(Properties props)
240     {
241         configuration.addProps(props);
242     }
243 
244     /***
245      * Parses InputStream in and returns the root Node. If out is non-null, pretty prints to OutputStream out.
246      * @param in input stream
247      * @param out optional output stream
248      * @return parsed org.w3c.tidy.Node
249      */
250     public Node parse(InputStream in, OutputStream out)
251     {
252         Node document = null;
253 
254         try
255         {
256             document = parse(in, null, out);
257         }
258         catch (FileNotFoundException fnfe)
259         {
260             // ignore
261         }
262         catch (IOException e)
263         {
264             // ignore
265         }
266 
267         return document;
268     }
269 
270     /***
271      * Internal routine that actually does the parsing. The caller can pass either an InputStream or file name. If both
272      * are passed, the file name is preferred.
273      * @param in input stream (used only if <code>file</code> is null)
274      * @param file file name
275      * @param out output stream
276      * @return parsed org.w3c.tidy.Node
277      * @throws FileNotFoundException if <code>file</code> is not null but it can't be found
278      * @throws IOException for errors in reading input stream or file
279      */
280     private Node parse(InputStream in, String file, OutputStream out) throws FileNotFoundException, IOException
281     {
282         Lexer lexer;
283         Node document = null;
284         Node doctype;
285         PPrint pprint;
286 
287         if (errout == null)
288         {
289             return null;
290         }
291 
292         parseErrors = 0;
293         parseWarnings = 0;
294 
295         // ensure config is self-consistent
296         configuration.adjust();
297 
298         if (file != null)
299         {
300             in = new FileInputStream(file);
301             inputStreamName = file;
302         }
303         else if (in == null)
304         {
305             in = System.in;
306             inputStreamName = "stdin";
307         }
308 
309         if (in != null)
310         {
311 
312             StreamIn streamIn = StreamInFactory.getStreamIn(configuration, in);
313 
314             lexer = new Lexer(streamIn, configuration, this.report);
315             lexer.errout = errout;
316 
317             // store pointer to lexer in input stream to allow character encoding errors to be reported
318             streamIn.setLexer(lexer);
319 
320             this.report.setFilename(inputStreamName); // #431895 - fix by Dave Bryan 04 Jan 01
321 
322             if (!configuration.quiet)
323             {
324                 this.report.helloMessage(errout);
325             }
326 
327             // skip byte order mark
328 
329             //            if (lexer.configuration.getInCharEncoding() == Configuration.UTF8
330             //                || lexer.configuration.getInCharEncoding() == Configuration.UTF16LE
331             //                || lexer.configuration.getInCharEncoding() == Configuration.UTF16BE
332             //                || lexer.configuration.getInCharEncoding() == Configuration.UTF16)
333             //            {
334             //                int c = lexer.in.readChar();
335             //                if (c != EncodingUtils.UNICODE_BOM)
336             //                {
337             //                    lexer.in.ungetChar(c);
338             //                }
339             //            }
340 
341             // Tidy doesn't alter the doctype for generic XML docs
342             if (configuration.xmlTags)
343             {
344                 document = ParserImpl.parseXMLDocument(lexer);
345                 if (!document.checkNodeIntegrity())
346                 {
347                     if (!configuration.quiet)
348                     {
349                         report.badTree(errout);
350                     }
351                     return null;
352                 }
353             }
354             else
355             {
356                 lexer.warnings = 0;
357 
358                 document = ParserImpl.parseDocument(lexer);
359 
360                 if (!document.checkNodeIntegrity())
361                 {
362                     if (!configuration.quiet)
363                     {
364                         this.report.badTree(errout);
365                     }
366                     return null;
367                 }
368 
369                 Clean cleaner = new Clean(configuration.tt);
370 
371                 // simplifies <b><b> ... </b> ... </b> etc.
372                 cleaner.nestedEmphasis(document);
373 
374                 // cleans up <dir> indented text </dir> etc.
375                 cleaner.list2BQ(document);
376                 cleaner.bQ2Div(document);
377 
378                 // replaces i by em and b by strong
379                 if (configuration.logicalEmphasis)
380                 {
381                     cleaner.emFromI(document);
382                 }
383 
384                 if (configuration.word2000 && cleaner.isWord2000(document))
385                 {
386                     // prune Word2000's <![if ...]> ... <![endif]>
387                     cleaner.dropSections(lexer, document);
388 
389                     // drop style & class attributes and empty p, span elements
390                     cleaner.cleanWord2000(lexer, document);
391                 }
392 
393                 // replaces presentational markup by style rules
394                 if (configuration.makeClean || configuration.dropFontTags)
395                 {
396                     cleaner.cleanTree(lexer, document);
397                 }
398 
399                 if (!document.checkNodeIntegrity())
400                 {
401                     this.report.badTree(errout);
402                     return null;
403                 }
404 
405                 doctype = document.findDocType();
406 
407                 // remember given doctype
408                 if (doctype != null)
409                 {
410                     doctype = (Node) doctype.clone();
411                 }
412 
413                 if (document.content != null)
414                 {
415                     if (configuration.xHTML)
416                     {
417                         lexer.setXHTMLDocType(document);
418                     }
419                     else
420                     {
421                         lexer.fixDocType(document);
422                     }
423 
424                     if (configuration.tidyMark)
425                     {
426                         lexer.addGenerator(document);
427                     }
428                 }
429 
430                 // ensure presence of initial <?XML version="1.0"?>
431                 if (configuration.xmlOut && configuration.xmlPi)
432                 {
433                     lexer.fixXmlDecl(document);
434                 }
435 
436                 if (!configuration.quiet && document.content != null)
437                 {
438                     this.report.reportVersion(errout, lexer, inputStreamName, doctype);
439                 }
440             }
441 
442             // Try to close the InputStream but only if if we created it.
443             if ((file != null) && (in != System.in))
444             {
445                 try
446                 {
447                     in.close();
448                 }
449                 catch (IOException e)
450                 {
451                     // ignore
452                 }
453             }
454 
455             if (!configuration.quiet)
456             {
457                 parseWarnings = lexer.warnings;
458                 parseErrors = lexer.errors;
459                 this.report.reportNumWarnings(errout, lexer);
460             }
461 
462             if (!configuration.quiet && lexer.errors > 0 && !configuration.forceOutput)
463             {
464                 this.report.needsAuthorIntervention(errout);
465             }
466 
467             if (!configuration.onlyErrors && (lexer.errors == 0 || configuration.forceOutput))
468             {
469                 if (configuration.burstSlides)
470                 {
471                     Node body;
472 
473                     body = null;
474                     // remove doctype to avoid potential clash with markup introduced when bursting into slides
475 
476                     // discard the document type
477                     doctype = document.findDocType();
478 
479                     if (doctype != null)
480                     {
481                         Node.discardElement(doctype);
482                     }
483 
484                     /* slides use transitional features */
485                     lexer.versions |= Dict.VERS_HTML40_LOOSE;
486 
487                     // and patch up doctype to match
488                     if (configuration.xHTML)
489                     {
490                         lexer.setXHTMLDocType(document);
491                     }
492                     else
493                     {
494                         lexer.fixDocType(document);
495                     }
496 
497                     // find the body element which may be implicit
498                     body = document.findBody(configuration.tt);
499 
500                     if (body != null)
501                     {
502                         pprint = new PPrint(configuration);
503                         if (!configuration.quiet)
504                         {
505                             this.report.reportNumberOfSlides(errout, pprint.countSlides(body));
506                         }
507                         pprint.createSlides(lexer, document);
508                     }
509                     else if (!configuration.quiet)
510                     {
511                         this.report.missingBody(errout);
512                     }
513                 }
514                 else if (configuration.writeback && (file != null))
515                 {
516                     try
517                     {
518                         pprint = new PPrint(configuration);
519                         FileOutputStream fis = new FileOutputStream(file);
520 
521                         Out o = OutFactory.getOut(this.configuration, fis);
522 
523                         if (document.findDocType() == null)
524                         {
525                             // only use numeric character references if no doctype could be determined (e.g., because
526                             // the document contains proprietary features) to ensure well-formedness.
527                             configuration.numEntities = true;
528                         }
529                         if (configuration.bodyOnly)
530                         {
531                             // Feature request #434940 - fix by Dave Raggett/Ignacio Vazquez-Abrams 21 Jun 01
532                             pprint.printBody(o, lexer, document, configuration.xmlOut);
533                         }
534                         else if (configuration.xmlOut && !configuration.xHTML)
535                         {
536                             pprint.printXMLTree(o, (short) 0, 0, lexer, document);
537                         }
538                         else
539                         {
540                             pprint.printTree(o, (short) 0, 0, lexer, document);
541                         }
542 
543                         pprint.flushLine(o, 0);
544                         o.close();
545                     }
546                     catch (IOException e)
547                     {
548                         errout.println(file + e.toString());
549                     }
550                 }
551                 else if (out != null)
552                 {
553                     pprint = new PPrint(configuration);
554 
555                     Out o = OutFactory.getOut(this.configuration, out); // normal output stream
556 
557                     if (document.findDocType() == null)
558                     {
559                         // only use numeric character references if no doctype could be determined (e.g., because
560                         // the document contains proprietary features) to ensure well-formedness.
561                         configuration.numEntities = true;
562                     }
563                     if (configuration.bodyOnly)
564                     {
565                         // Feature request #434940 - fix by Dave Raggett/Ignacio Vazquez-Abrams 21 Jun 01
566                         pprint.printBody(o, lexer, document, configuration.xmlOut);
567                     }
568                     else if (configuration.xmlOut && !configuration.xHTML)
569                     {
570                         pprint.printXMLTree(o, (short) 0, 0, lexer, document);
571                     }
572                     else
573                     {
574                         pprint.printTree(o, (short) 0, 0, lexer, document);
575                     }
576 
577                     pprint.flushLine(o, 0);
578                     o.close();
579                 }
580 
581             }
582 
583             if (!configuration.quiet)
584             {
585                 this.report.errorSummary(lexer);
586             }
587         }
588         return document;
589     }
590 
591     /***
592      * Parses InputStream in and returns a DOM Document node. If out is non-null, pretty prints to OutputStream out.
593      * @param in input stream
594      * @param out optional output stream
595      * @return parsed org.w3c.dom.Document
596      */
597     public org.w3c.dom.Document parseDOM(InputStream in, OutputStream out)
598     {
599         Node document = parse(in, out);
600         if (document != null)
601         {
602             return (org.w3c.dom.Document) document.getAdapter();
603         }
604         return null;
605     }
606 
607     /***
608      * Creates an empty DOM Document.
609      * @return a new org.w3c.dom.Document
610      */
611     public static org.w3c.dom.Document createEmptyDocument()
612     {
613         Node document = new Node(Node.ROOT_NODE, new byte[0], 0, 0);
614         Node node = new Node(Node.START_TAG, new byte[0], 0, 0, "html", new TagTable());
615         if (document != null && node != null)
616         {
617             document.insertNodeAtStart(node);
618             return (org.w3c.dom.Document) document.getAdapter();
619         }
620 
621         return null;
622     }
623 
624     /***
625      * Pretty-prints a DOM Document. Must be an instance of org.w3c.tidy.DOMDocumentImpl.
626      * @param doc org.w3c.dom.Document
627      * @param out output stream
628      */
629     public void pprint(org.w3c.dom.Document doc, OutputStream out)
630     {
631         if (!(doc instanceof DOMDocumentImpl))
632         {
633             // @todo should we inform users that tidy can't print a generic Document or change the method signature?
634             return;
635         }
636 
637         pprint(((DOMDocumentImpl) doc).adaptee, out);
638     }
639 
640     /***
641      * Pretty-prints a DOM Node.
642      * @param node org.w3c.dom.Node. Must be an instance of org.w3c.tidy.DOMNodeImpl.
643      * @param out output stream
644      */
645     public void pprint(org.w3c.dom.Node node, OutputStream out)
646     {
647         if (!(node instanceof DOMNodeImpl))
648         {
649             // @todo should we inform users than tidy can't print a generic Node or change the method signature?
650             return;
651         }
652 
653         pprint(((DOMNodeImpl) node).adaptee, out);
654     }
655 
656     /***
657      * Pretty-prints a tidy Node.
658      * @param node org.w3c.tidy.Node
659      * @param out output stream
660      */
661     private void pprint(Node node, OutputStream out)
662     {
663         PPrint pprint;
664 
665         if (out != null)
666         {
667 
668             Out o = OutFactory.getOut(this.configuration, out);
669 
670             Lexer lexer = new Lexer(null, this.configuration, this.report);
671 
672             pprint = new PPrint(configuration);
673 
674             if (configuration.xmlTags)
675             {
676                 pprint.printXMLTree(o, (short) 0, 0, lexer, node);
677             }
678             else
679             {
680                 pprint.printTree(o, (short) 0, 0, lexer, node);
681             }
682 
683             pprint.flushLine(o, 0);
684         }
685     }
686 
687     /***
688      * Command line interface to parser and pretty printer.
689      * @param argv command line parameters
690      */
691     public static void main(String[] argv)
692     {
693         Tidy tidy = new Tidy();
694         int returnCode = tidy.mainExec(argv);
695         System.exit(returnCode);
696     }
697 
698     /***
699      * Main method, but returns the return code as an int instead of calling System.exit(code). Needed for testing main
700      * method without shutting down tests.
701      * @param argv command line parameters
702      * @return return code
703      */
704     protected int mainExec(String[] argv)
705     {
706         String file;
707         int argCount = argv.length;
708         int argIndex = 0;
709 
710         // read command line
711         Properties properties = new Properties();
712 
713         while (argCount > 0)
714         {
715             if (argv[argIndex].startsWith("-"))
716             {
717                 // support -foo and --foo
718                 String argName = argv[argIndex].toLowerCase();
719                 while (argName.length() > 0 && argName.charAt(0) == '-')
720                 {
721                     argName = argName.substring(1);
722                 }
723 
724                 // "exclusive" options
725                 if (argName.equals("help") || argName.equals("h") || argName.equals("?"))
726                 {
727                     this.report.helpText(new PrintWriter(System.out, true));
728                     return 0;
729                 }
730                 else if (argName.equals("help-config"))
731                 {
732                     configuration.printConfigOptions(new PrintWriter(System.out, true), false);
733                     return 0;
734                 }
735                 else if (argName.equals("show-config"))
736                 {
737                     configuration.adjust(); // ensure config is self-consistent
738                     configuration.printConfigOptions(errout, true);
739                     return 0;
740                 }
741                 else if (argName.equals("version") || argName.equals("v"))
742                 {
743                     this.report.showVersion(errout);
744                     return 0;
745                 }
746 
747                 // optional value for non boolean options
748                 String argValue = null;
749                 if (argCount > 2 && !argv[argIndex + 1].startsWith("-"))
750                 {
751                     argValue = argv[argIndex + 1];
752                     --argCount;
753                     ++argIndex;
754                 }
755 
756                 // handle "special" aliases
757                 String alias = (String) CMDLINE_ALIAS.get(argName);
758                 if (alias != null)
759                 {
760                     argName = alias;
761                 }
762 
763                 if (Configuration.isKnownOption(argName)) // handle any standard config option
764                 {
765                     properties.setProperty(argName, (argValue == null ? "" : argName));
766                 }
767                 else if (argName.equals("config")) // parse a property file
768                 {
769                     if (argValue != null)
770                     {
771                         configuration.parseFile(argValue);
772                     }
773                 }
774                 else if (TidyUtils.isCharEncodingSupported(argName)) // handle any encoding name
775                 {
776                     properties.setProperty("char-encoding", argName);
777                 }
778                 else
779                 {
780 
781                     for (int i = 0; i < argName.length(); i++)
782                     {
783                         switch (argName.charAt(i))
784                         {
785                             case 'i' :
786                                 configuration.indentContent = true;
787                                 configuration.smartIndent = true;
788                                 break;
789 
790                             case 'o' :
791                                 configuration.hideEndTags = true;
792                                 break;
793 
794                             case 'u' :
795                                 configuration.upperCaseTags = true;
796                                 break;
797 
798                             case 'c' :
799                                 configuration.makeClean = true;
800                                 break;
801 
802                             case 'b' :
803                                 configuration.makeBare = true;
804                                 break;
805 
806                             case 'n' :
807                                 configuration.numEntities = true;
808                                 break;
809 
810                             case 'm' :
811                                 configuration.writeback = true;
812                                 break;
813 
814                             case 'e' :
815                                 configuration.onlyErrors = true;
816                                 break;
817 
818                             case 'q' :
819                                 configuration.quiet = true;
820                                 break;
821 
822                             default :
823                                 this.report.unknownOption(this.errout, argName.charAt(i));
824                                 break;
825                         }
826                     }
827                 }
828 
829                 --argCount;
830                 ++argIndex;
831                 continue;
832             }
833 
834             configuration.addProps(properties);
835 
836             // ensure config is self-consistent
837             configuration.adjust();
838 
839             // user specified error file
840             if (configuration.errfile != null)
841             {
842 
843                 String errorfile = "stderr";
844 
845                 // is it same as the currently opened file?
846                 if (!configuration.errfile.equals(errorfile))
847                 {
848                     // no so close previous error file
849 
850                     if (this.errout != this.stderr)
851                     {
852                         this.errout.close();
853                     }
854 
855                     // and try to open the new error file
856                     try
857                     {
858                         this.setErrout(new PrintWriter(new FileWriter(configuration.errfile), true));
859                         errorfile = configuration.errfile;
860                     }
861                     catch (IOException e)
862                     {
863                         // can't be opened so fall back to stderr
864                         errorfile = "stderr";
865                         this.setErrout(stderr);
866                     }
867                 }
868             }
869 
870             if (argCount > 0)
871             {
872                 file = argv[argIndex];
873             }
874             else
875             {
876                 file = "stdin";
877             }
878 
879             try
880             {
881                 parse(null, file, System.out);
882             }
883             catch (FileNotFoundException fnfe)
884             {
885                 this.report.unknownFile(this.errout, file);
886             }
887             catch (IOException ioe)
888             {
889                 this.report.unknownFile(this.errout, file);
890             }
891 
892             --argCount;
893             ++argIndex;
894 
895             if (argCount <= 0)
896             {
897                 break;
898             }
899         }
900 
901         if (this.parseErrors + this.parseWarnings > 0 && !configuration.quiet)
902         {
903             this.report.generalInfo(this.errout);
904         }
905 
906         if (this.errout != this.stderr)
907         {
908             this.errout.close();
909         }
910 
911         // return status can be used by scripts
912         if (this.parseErrors > 0)
913         {
914             return 2;
915         }
916 
917         if (this.parseWarnings > 0)
918         {
919             return 1;
920         }
921 
922         // 0 means all is ok
923         return 0;
924     }
925 
926     /***
927      * Attach a TidyMessageListener which will be notified for messages and errors.
928      * @param listener TidyMessageListener implementation
929      */
930     public void setMessageListener(TidyMessageListener listener)
931     {
932         this.report.addMessageListener(listener);
933     }
934 
935     /***
936      * <code>indent-spaces</code>- default indentation.
937      * @param spaces number of spaces used for indentation
938      * @see Configuration#spaces
939      */
940     public void setSpaces(int spaces)
941     {
942         configuration.spaces = spaces;
943     }
944 
945     /***
946      * <code>indent-spaces</code>- default indentation.
947      * @return number of spaces used for indentation
948      * @see Configuration#spaces
949      */
950     public int getSpaces()
951     {
952         return configuration.spaces;
953     }
954 
955     /***
956      * <code>wrap</code>- default wrap margin.
957      * @param wraplen default wrap margin
958      * @see Configuration#wraplen
959      */
960     public void setWraplen(int wraplen)
961     {
962         configuration.wraplen = wraplen;
963     }
964 
965     /***
966      * <code>wrap</code>- default wrap margin.
967      * @return default wrap margin
968      * @see Configuration#wraplen
969      */
970     public int getWraplen()
971     {
972         return configuration.wraplen;
973     }
974 
975     /***
976      * <code>tab-size</code>- tab size in chars.
977      * @param tabsize tab size in chars
978      * @see Configuration#tabsize
979      */
980     public void setTabsize(int tabsize)
981     {
982         configuration.tabsize = tabsize;
983     }
984 
985     /***
986      * <code>tab-size</code>- tab size in chars.
987      * @return tab size in chars
988      * @see Configuration#tabsize
989      */
990     public int getTabsize()
991     {
992         return configuration.tabsize;
993     }
994 
995     /***
996      * Errfile - file name to write errors to.
997      * @param errfile file name to write errors to
998      * @see Configuration#errfile
999      */
1000     public void setErrfile(String errfile)
1001     {
1002         configuration.errfile = errfile;
1003     }
1004 
1005     /***
1006      * Errfile - file name to write errors to.
1007      * @return error file name
1008      * @see Configuration#errfile
1009      */
1010     public String getErrfile()
1011     {
1012         return configuration.errfile;
1013     }
1014 
1015     /***
1016      * writeback - if true then output tidied markup. NOTE: this property is ignored when parsing from an InputStream.
1017      * @param writeback <code>true</code>= output tidied markup
1018      * @see Configuration#writeback
1019      */
1020     public void setWriteback(boolean writeback)
1021     {
1022         configuration.writeback = writeback;
1023     }
1024 
1025     /***
1026      * writeback - if true then output tidied markup. NOTE: this property is ignored when parsing from an InputStream.
1027      * @return <code>true</code> if tidy will output tidied markup in input file
1028      * @see Configuration#writeback
1029      */
1030     public boolean getWriteback()
1031     {
1032         return configuration.writeback;
1033     }
1034 
1035     /***
1036      * only-errors - if true normal output is suppressed.
1037      * @param onlyErrors if <code>true</code> normal output is suppressed.
1038      * @see Configuration#onlyErrors
1039      */
1040     public void setOnlyErrors(boolean onlyErrors)
1041     {
1042         configuration.onlyErrors = onlyErrors;
1043     }
1044 
1045     /***
1046      * only-errors - if true normal output is suppressed.
1047      * @return <code>true</code> if normal output is suppressed.
1048      * @see Configuration#onlyErrors
1049      */
1050     public boolean getOnlyErrors()
1051     {
1052         return configuration.onlyErrors;
1053     }
1054 
1055     /***
1056      * show-warnings - show warnings? (errors are always shown).
1057      * @param showWarnings if <code>false</code> warnings are not shown
1058      * @see Configuration#showWarnings
1059      */
1060     public void setShowWarnings(boolean showWarnings)
1061     {
1062         configuration.showWarnings = showWarnings;
1063     }
1064 
1065     /***
1066      * show-warnings - show warnings? (errors are always shown).
1067      * @return <code>false</code> if warnings are not shown
1068      * @see Configuration#showWarnings
1069      */
1070     public boolean getShowWarnings()
1071     {
1072         return configuration.showWarnings;
1073     }
1074 
1075     /***
1076      * quiet - no 'Parsing X', guessed DTD or summary.
1077      * @param quiet <code>true</code>= don't output summary, warnings or errors
1078      * @see Configuration#quiet
1079      */
1080     public void setQuiet(boolean quiet)
1081     {
1082         configuration.quiet = quiet;
1083     }
1084 
1085     /***
1086      * quiet - no 'Parsing X', guessed DTD or summary.
1087      * @return <code>true</code> if tidy will not output summary, warnings or errors
1088      * @see Configuration#quiet
1089      */
1090     public boolean getQuiet()
1091     {
1092         return configuration.quiet;
1093     }
1094 
1095     /***
1096      * indent - indent content of appropriate tags.
1097      * @param indentContent indent content of appropriate tags
1098      * @see Configuration#indentContent
1099      */
1100     public void setIndentContent(boolean indentContent)
1101     {
1102         configuration.indentContent = indentContent;
1103     }
1104 
1105     /***
1106      * indent - indent content of appropriate tags.
1107      * @return <code>true</code> if tidy will indent content of appropriate tags
1108      * @see Configuration#indentContent
1109      */
1110     public boolean getIndentContent()
1111     {
1112         return configuration.indentContent;
1113     }
1114 
1115     /***
1116      * SmartIndent - does text/block level content effect indentation.
1117      * @param smartIndent <code>true</code> if text/block level content should effect indentation
1118      * @see Configuration#smartIndent
1119      */
1120     public void setSmartIndent(boolean smartIndent)
1121     {
1122         configuration.smartIndent = smartIndent;
1123     }
1124 
1125     /***
1126      * SmartIndent - does text/block level content effect indentation.
1127      * @return <code>true</code> if text/block level content should effect indentation
1128      * @see Configuration#smartIndent
1129      */
1130     public boolean getSmartIndent()
1131     {
1132         return configuration.smartIndent;
1133     }
1134 
1135     /***
1136      * hide-endtags - suppress optional end tags.
1137      * @param hideEndTags <code>true</code>= suppress optional end tags
1138      * @see Configuration#hideEndTags
1139      */
1140     public void setHideEndTags(boolean hideEndTags)
1141     {
1142         configuration.hideEndTags = hideEndTags;
1143     }
1144 
1145     /***
1146      * hide-endtags - suppress optional end tags.
1147      * @return <code>true</code> if tidy will suppress optional end tags
1148      * @see Configuration#hideEndTags
1149      */
1150     public boolean getHideEndTags()
1151     {
1152         return configuration.hideEndTags;
1153     }
1154 
1155     /***
1156      * input-xml - treat input as XML.
1157      * @param xmlTags <code>true</code> if tidy should treat input as XML
1158      * @see Configuration#xmlTags
1159      */
1160     public void setXmlTags(boolean xmlTags)
1161     {
1162         configuration.xmlTags = xmlTags;
1163     }
1164 
1165     /***
1166      * input-xml - treat input as XML.
1167      * @return <code>true</code> if tidy will treat input as XML
1168      * @see Configuration#xmlTags
1169      */
1170     public boolean getXmlTags()
1171     {
1172         return configuration.xmlTags;
1173     }
1174 
1175     /***
1176      * output-xml - create output as XML.
1177      * @param xmlOut <code>true</code> if tidy should create output as xml
1178      * @see Configuration#xmlOut
1179      */
1180     public void setXmlOut(boolean xmlOut)
1181     {
1182         configuration.xmlOut = xmlOut;
1183     }
1184 
1185     /***
1186      * output-xml - create output as XML.
1187      * @return <code>true</code> if tidy will create output as xml
1188      * @see Configuration#xmlOut
1189      */
1190     public boolean getXmlOut()
1191     {
1192         return configuration.xmlOut;
1193     }
1194 
1195     /***
1196      * output-xhtml - output extensible HTML.
1197      * @param xhtml <code>true</code> if tidy should output XHTML
1198      * @see Configuration#xHTML
1199      */
1200     public void setXHTML(boolean xhtml)
1201     {
1202         configuration.xHTML = xhtml;
1203     }
1204 
1205     /***
1206      * output-xhtml - output extensible HTML.
1207      * @return <code>true</code> if tidy will output XHTML
1208      * @see Configuration#xHTML
1209      */
1210     public boolean getXHTML()
1211     {
1212         return configuration.xHTML;
1213     }
1214 
1215     /***
1216      * uppercase-tags - output tags in upper case.
1217      * @param upperCaseTags <code>true</code> if tidy should output tags in upper case (default is lowercase)
1218      * @see Configuration#upperCaseTags
1219      */
1220     public void setUpperCaseTags(boolean upperCaseTags)
1221     {
1222         configuration.upperCaseTags = upperCaseTags;
1223     }
1224 
1225     /***
1226      * uppercase-tags - output tags in upper case.
1227      * @return <code>true</code> if tidy should will tags in upper case
1228      * @see Configuration#upperCaseTags
1229      */
1230     public boolean getUpperCaseTags()
1231     {
1232         return configuration.upperCaseTags;
1233     }
1234 
1235     /***
1236      * uppercase-attributes - output attributes in upper case.
1237      * @param upperCaseAttrs <code>true</code> if tidy should output attributes in upper case (default is lowercase)
1238      * @see Configuration#upperCaseAttrs
1239      */
1240     public void setUpperCaseAttrs(boolean upperCaseAttrs)
1241     {
1242         configuration.upperCaseAttrs = upperCaseAttrs;
1243     }
1244 
1245     /***
1246      * uppercase-attributes - output attributes in upper case.
1247      * @return <code>true</code> if tidy should will attributes in upper case
1248      * @see Configuration#upperCaseAttrs
1249      */
1250     public boolean getUpperCaseAttrs()
1251     {
1252         return configuration.upperCaseAttrs;
1253     }
1254 
1255     /***
1256      * make-clean - remove presentational clutter.
1257      * @param makeClean true to remove presentational clutter
1258      * @see Configuration#makeClean
1259      */
1260     public void setMakeClean(boolean makeClean)
1261     {
1262         configuration.makeClean = makeClean;
1263     }
1264 
1265     /***
1266      * make-clean - remove presentational clutter.
1267      * @return true if tidy will remove presentational clutter
1268      * @see Configuration#makeClean
1269      */
1270     public boolean getMakeClean()
1271     {
1272         return configuration.makeClean;
1273     }
1274 
1275     /***
1276      * make-bare - remove Microsoft cruft.
1277      * @param makeBare true to remove Microsoft cruft
1278      * @see Configuration#makeBare
1279      */
1280     public void setMakeBare(boolean makeBare)
1281     {
1282         configuration.makeBare = makeBare;
1283     }
1284 
1285     /***
1286      * make-clean - remove Microsoft cruft.
1287      * @return true if tidy will remove Microsoft cruft
1288      * @see Configuration#makeBare
1289      */
1290     public boolean getMakeBare()
1291     {
1292         return configuration.makeBare;
1293     }
1294 
1295     /***
1296      * break-before-br - output newline before &lt;br&gt;.
1297      * @param breakBeforeBR <code>true</code> if tidy should output a newline before &lt;br&gt;
1298      * @see Configuration#breakBeforeBR
1299      */
1300     public void setBreakBeforeBR(boolean breakBeforeBR)
1301     {
1302         configuration.breakBeforeBR = breakBeforeBR;
1303     }
1304 
1305     /***
1306      * break-before-br - output newline before &lt;br&gt;.
1307      * @return <code>true</code> if tidy will output a newline before &lt;br&gt;
1308      * @see Configuration#breakBeforeBR
1309      */
1310     public boolean getBreakBeforeBR()
1311     {
1312         return configuration.breakBeforeBR;
1313     }
1314 
1315     /***
1316      * <code>split</code>- create slides on each h2 element.
1317      * @param burstSlides <code>true</code> if tidy should create slides on each h2 element
1318      * @see Configuration#burstSlides
1319      */
1320     public void setBurstSlides(boolean burstSlides)
1321     {
1322         configuration.burstSlides = burstSlides;
1323     }
1324 
1325     /***
1326      * <code>split</code>- create slides on each h2 element.
1327      * @return <code>true</code> if tidy will create slides on each h2 element
1328      * @see Configuration#burstSlides
1329      */
1330     public boolean getBurstSlides()
1331     {
1332         return configuration.burstSlides;
1333     }
1334 
1335     /***
1336      * <code>numeric-entities</code>- output entities other than the built-in HTML entities in the numeric rather
1337      * than the named entity form.
1338      * @param numEntities <code>true</code> if tidy should output entities in the numeric form.
1339      * @see Configuration#numEntities
1340      */
1341     public void setNumEntities(boolean numEntities)
1342     {
1343         configuration.numEntities = numEntities;
1344     }
1345 
1346     /***
1347      * <code>numeric-entities</code>- output entities other than the built-in HTML entities in the numeric rather
1348      * than the named entity form.
1349      * @return <code>true</code> if tidy will output entities in the numeric form.
1350      * @see Configuration#numEntities
1351      */
1352     public boolean getNumEntities()
1353     {
1354         return configuration.numEntities;
1355     }
1356 
1357     /***
1358      * <code>quote-marks</code>- output " marks as &amp;quot;.
1359      * @param quoteMarks <code>true</code> if tidy should output " marks as &amp;quot;
1360      * @see Configuration#quoteMarks
1361      */
1362     public void setQuoteMarks(boolean quoteMarks)
1363     {
1364         configuration.quoteMarks = quoteMarks;
1365     }
1366 
1367     /***
1368      * <code>quote-marks</code>- output " marks as &amp;quot;.
1369      * @return <code>true</code> if tidy will output " marks as &amp;quot;
1370      * @see Configuration#quoteMarks
1371      */
1372     public boolean getQuoteMarks()
1373     {
1374         return configuration.quoteMarks;
1375     }
1376 
1377     /***
1378      * <code>quote-nbsp</code>- output non-breaking space as entity.
1379      * @param quoteNbsp <code>true</code> if tidy should output non-breaking space as entity
1380      * @see Configuration#quoteNbsp
1381      */
1382     public void setQuoteNbsp(boolean quoteNbsp)
1383     {
1384         configuration.quoteNbsp = quoteNbsp;
1385     }
1386 
1387     /***
1388      * <code>quote-nbsp</code>- output non-breaking space as entity.
1389      * @return <code>true</code> if tidy will output non-breaking space as entity
1390      * @see Configuration#quoteNbsp
1391      */
1392     public boolean getQuoteNbsp()
1393     {
1394         return configuration.quoteNbsp;
1395     }
1396 
1397     /***
1398      * <code>quote-ampersand</code>- output naked ampersand as &amp;.
1399      * @param quoteAmpersand <code>true</code> if tidy should output naked ampersand as &amp;
1400      * @see Configuration#quoteAmpersand
1401      */
1402     public void setQuoteAmpersand(boolean quoteAmpersand)
1403     {
1404         configuration.quoteAmpersand = quoteAmpersand;
1405     }
1406 
1407     /***
1408      * <code>quote-ampersand</code>- output naked ampersand as &amp;.
1409      * @return <code>true</code> if tidy will output naked ampersand as &amp;
1410      * @see Configuration#quoteAmpersand
1411      */
1412     public boolean getQuoteAmpersand()
1413     {
1414         return configuration.quoteAmpersand;
1415     }
1416 
1417     /***
1418      * <code>wrap-attributes</code>- wrap within attribute values.
1419      * @param wrapAttVals <code>true</code> if tidy should wrap within attribute values
1420      * @see Configuration#wrapAttVals
1421      */
1422     public void setWrapAttVals(boolean wrapAttVals)
1423     {
1424         configuration.wrapAttVals = wrapAttVals;
1425     }
1426 
1427     /***
1428      * <code>wrap-attributes</code>- wrap within attribute values.
1429      * @return <code>true</code> if tidy will wrap within attribute values
1430      * @see Configuration#wrapAttVals
1431      */
1432     public boolean getWrapAttVals()
1433     {
1434         return configuration.wrapAttVals;
1435     }
1436 
1437     /***
1438      * <code>wrap-script-literals</code>- wrap within JavaScript string literals.
1439      * @param wrapScriptlets <code>true</code> if tidy should wrap within JavaScript string literals
1440      * @see Configuration#wrapScriptlets
1441      */
1442     public void setWrapScriptlets(boolean wrapScriptlets)
1443     {
1444         configuration.wrapScriptlets = wrapScriptlets;
1445     }
1446 
1447     /***
1448      * <code>wrap-script-literals</code>- wrap within JavaScript string literals.
1449      * @return <code>true</code> if tidy will wrap within JavaScript string literals
1450      * @see Configuration#wrapScriptlets
1451      */
1452     public boolean getWrapScriptlets()
1453     {
1454         return configuration.wrapScriptlets;
1455     }
1456 
1457     /***
1458      * <code>wrap-sections</code>- wrap within &lt;![ ... ]&gt; section tags
1459      * @param wrapSection <code>true</code> if tidy should wrap within &lt;![ ... ]&gt; section tags
1460      * @see Configuration#wrapSection
1461      */
1462     public void setWrapSection(boolean wrapSection)
1463     {
1464         configuration.wrapSection = wrapSection;
1465     }
1466 
1467     /***
1468      * <code>wrap-sections</code>- wrap within &lt;![ ... ]&gt; section tags
1469      * @return <code>true</code> if tidy will wrap within &lt;![ ... ]&gt; section tags
1470      * @see Configuration#wrapSection
1471      */
1472     public boolean getWrapSection()
1473     {
1474         return configuration.wrapSection;
1475     }
1476 
1477     /***
1478      * <code>alt-text</code>- default text for alt attribute.
1479      * @param altText default text for alt attribute
1480      * @see Configuration#altText
1481      */
1482     public void setAltText(String altText)
1483     {
1484         configuration.altText = altText;
1485     }
1486 
1487     /***
1488      * <code>alt-text</code>- default text for alt attribute.
1489      * @return default text for alt attribute
1490      * @see Configuration#altText
1491      */
1492     public String getAltText()
1493     {
1494         return configuration.altText;
1495     }
1496 
1497     /***
1498      * <code>add-xml-pi</code>- add &lt;?xml?&gt; for XML docs.
1499      * @param xmlPi <code>true</code> if tidy should add &lt;?xml?&gt; for XML docs
1500      * @see Configuration#xmlPi
1501      */
1502     public void setXmlPi(boolean xmlPi)
1503     {
1504         configuration.xmlPi = xmlPi;
1505     }
1506 
1507     /***
1508      * <code>add-xml-pi</code>- add &lt;?xml?&gt; for XML docs.
1509      * @return <code>true</code> if tidy will add &lt;?xml?&gt; for XML docs
1510      * @see Configuration#xmlPi
1511      */
1512     public boolean getXmlPi()
1513     {
1514         return configuration.xmlPi;
1515     }
1516 
1517     /***
1518      * <code>drop-font-tags</code>- discard presentation tags.
1519      * @param dropFontTags <code>true</code> if tidy should discard presentation tags
1520      * @see Configuration#dropFontTags
1521      */
1522     public void setDropFontTags(boolean dropFontTags)
1523     {
1524         configuration.dropFontTags = dropFontTags;
1525     }
1526 
1527     /***
1528      * <code>drop-font-tags</code>- discard presentation tags.
1529      * @return <code>true</code> if tidy will discard presentation tags
1530      * @see Configuration#dropFontTags
1531      */
1532     public boolean getDropFontTags()
1533     {
1534         return configuration.dropFontTags;
1535     }
1536 
1537     /***
1538      * <code>drop-proprietary-attributes</code>- discard proprietary attributes.
1539      * @param dropProprietaryAttributes <code>true</code> if tidy should discard proprietary attributes
1540      * @see Configuration#dropProprietaryAttributes
1541      */
1542     public void setDropProprietaryAttributes(boolean dropProprietaryAttributes)
1543     {
1544         configuration.dropProprietaryAttributes = dropProprietaryAttributes;
1545     }
1546 
1547     /***
1548      * <code>drop-proprietary-attributes</code>- discard proprietary attributes.
1549      * @return <code>true</code> if tidy will discard proprietary attributes
1550      * @see Configuration#dropProprietaryAttributes
1551      */
1552     public boolean getDropProprietaryAttributes()
1553     {
1554         return configuration.dropProprietaryAttributes;
1555     }
1556 
1557     /***
1558      * <code>drop-empty-paras</code>- discard empty p elements.
1559      * @param dropEmptyParas <code>true</code> if tidy should discard empty p elements
1560      * @see Configuration#dropEmptyParas
1561      */
1562     public void setDropEmptyParas(boolean dropEmptyParas)
1563     {
1564         configuration.dropEmptyParas = dropEmptyParas;
1565     }
1566 
1567     /***
1568      * <code>drop-empty-paras</code>- discard empty p elements.
1569      * @return <code>true</code> if tidy will discard empty p elements
1570      * @see Configuration#dropEmptyParas
1571      */
1572     public boolean getDropEmptyParas()
1573     {
1574         return configuration.dropEmptyParas;
1575     }
1576 
1577     /***
1578      * <code>fix-bad-comments</code>- fix comments with adjacent hyphens.
1579      * @param fixComments <code>true</code> if tidy should fix comments with adjacent hyphens
1580      * @see Configuration#fixComments
1581      */
1582     public void setFixComments(boolean fixComments)
1583     {
1584         configuration.fixComments = fixComments;
1585     }
1586 
1587     /***
1588      * <code>fix-bad-comments</code>- fix comments with adjacent hyphens.
1589      * @return <code>true</code> if tidy will fix comments with adjacent hyphens
1590      * @see Configuration#fixComments
1591      */
1592     public boolean getFixComments()
1593     {
1594         return configuration.fixComments;
1595     }
1596 
1597     /***
1598      * <code>wrap-asp</code>- wrap within ASP pseudo elements.
1599      * @param wrapAsp <code>true</code> if tidy should wrap within ASP pseudo elements
1600      * @see Configuration#wrapAsp
1601      */
1602     public void setWrapAsp(boolean wrapAsp)
1603     {
1604         configuration.wrapAsp = wrapAsp;
1605     }
1606 
1607     /***
1608      * <code>wrap-asp</code>- wrap within ASP pseudo elements.
1609      * @return <code>true</code> if tidy will wrap within ASP pseudo elements
1610      * @see Configuration#wrapAsp
1611      */
1612     public boolean getWrapAsp()
1613     {
1614         return configuration.wrapAsp;
1615     }
1616 
1617     /***
1618      * <code>wrap-jste</code>- wrap within JSTE pseudo elements.
1619      * @param wrapJste <code>true</code> if tidy should wrap within JSTE pseudo elements
1620      * @see Configuration#wrapJste
1621      */
1622     public void setWrapJste(boolean wrapJste)
1623     {
1624         configuration.wrapJste = wrapJste;
1625     }
1626 
1627     /***
1628      * <code>wrap-jste</code>- wrap within JSTE pseudo elements.
1629      * @return <code>true</code> if tidy will wrap within JSTE pseudo elements
1630      * @see Configuration#wrapJste
1631      */
1632     public boolean getWrapJste()
1633     {
1634         return configuration.wrapJste;
1635     }
1636 
1637     /***
1638      * <code>wrap-php</code>- wrap within PHP pseudo elements.
1639      * @param wrapPhp <code>true</code> if tidy should wrap within PHP pseudo elements
1640      * @see Configuration#wrapPhp
1641      */
1642     public void setWrapPhp(boolean wrapPhp)
1643     {
1644         configuration.wrapPhp = wrapPhp;
1645     }
1646 
1647     /***
1648      * <code>wrap-php</code>- wrap within PHP pseudo elements.
1649      * @return <code>true</code> if tidy will wrap within PHP pseudo elements
1650      * @see Configuration#wrapPhp
1651      */
1652     public boolean getWrapPhp()
1653     {
1654         return configuration.wrapPhp;
1655     }
1656 
1657     /***
1658      * <code>fix-backslash</code>- fix URLs by replacing \ with /.
1659      * @param fixBackslash <code>true</code> if tidy should fix URLs by replacing \ with /
1660      * @see Configuration#fixBackslash
1661      */
1662     public void setFixBackslash(boolean fixBackslash)
1663     {
1664         configuration.fixBackslash = fixBackslash;
1665     }
1666 
1667     /***
1668      * <code>fix-backslash</code>- fix URLs by replacing \ with /.
1669      * @return <code>true</code> if tidy will fix URLs by replacing \ with /
1670      * @see Configuration#fixBackslash
1671      */
1672     public boolean getFixBackslash()
1673     {
1674         return configuration.fixBackslash;
1675     }
1676 
1677     /***
1678      * <code>indent-attributes</code>- newline+indent before each attribute.
1679      * @param indentAttributes <code>true</code> if tidy should output a newline+indent before each attribute
1680      * @see Configuration#indentAttributes
1681      */
1682     public void setIndentAttributes(boolean indentAttributes)
1683     {
1684         configuration.indentAttributes = indentAttributes;
1685     }
1686 
1687     /***
1688      * <code>indent-attributes</code>- newline+indent before each attribute.
1689      * @return <code>true</code> if tidy will output a newline+indent before each attribute
1690      * @see Configuration#indentAttributes
1691      */
1692     public boolean getIndentAttributes()
1693     {
1694         return configuration.indentAttributes;
1695     }
1696 
1697     /***
1698      * <code>doctype</code>- user specified doctype.
1699      * @param doctype <code>omit | auto | strict | loose | <em>fpi</em></code> where the <em>fpi </em> is a string
1700      * similar to &quot;-//ACME//DTD HTML 3.14159//EN&quot; Note: for <em>fpi </em> include the double-quotes in the
1701      * string.
1702      * @see Configuration#docTypeStr
1703      * @see Configuration#docTypeMode
1704      */
1705     public void setDocType(String doctype)
1706     {
1707         if (doctype != null)
1708         {
1709             configuration.docTypeStr = (String) ParsePropertyImpl.DOCTYPE.parse(doctype, "doctype", configuration);
1710         }
1711     }
1712 
1713     /***
1714      * <code>doctype</code>- user specified doctype.
1715      * @return <code>omit | auto | strict | loose | <em>fpi</em></code> where the <em>fpi </em> is a string similar
1716      * to &quot;-//ACME//DTD HTML 3.14159//EN&quot; Note: for <em>fpi </em> include the double-quotes in the string.
1717      * @see Configuration#docTypeStr
1718      * @see Configuration#docTypeMode
1719      */
1720     public String getDocType()
1721     {
1722         String result = null;
1723         switch (configuration.docTypeMode)
1724         {
1725             case Configuration.DOCTYPE_OMIT :
1726                 result = "omit";
1727                 break;
1728             case Configuration.DOCTYPE_AUTO :
1729                 result = "auto";
1730                 break;
1731             case Configuration.DOCTYPE_STRICT :
1732                 result = "strict";
1733                 break;
1734             case Configuration.DOCTYPE_LOOSE :
1735                 result = "loose";
1736                 break;
1737             case Configuration.DOCTYPE_USER :
1738                 result = configuration.docTypeStr;
1739                 break;
1740         }
1741         return result;
1742     }
1743 
1744     /***
1745      * <code>logical-emphasis</code>- replace i by em and b by strong.
1746      * @param logicalEmphasis <code>true</code> if tidy should replace i by em and b by strong
1747      * @see Configuration#logicalEmphasis
1748      */
1749     public void setLogicalEmphasis(boolean logicalEmphasis)
1750     {
1751         configuration.logicalEmphasis = logicalEmphasis;
1752     }
1753 
1754     /***
1755      * <code>logical-emphasis</code>- replace i by em and b by strong.
1756      * @return <code>true</code> if tidy will replace i by em and b by strong
1757      * @see Configuration#logicalEmphasis
1758      */
1759     public boolean getLogicalEmphasis()
1760     {
1761         return configuration.logicalEmphasis;
1762     }
1763 
1764     /***
1765      * <code>assume-xml-procins</code> This option specifies if Tidy should change the parsing of processing
1766      * instructions to require ?> as the terminator rather than >. This option is automatically set if the input is in
1767      * XML.
1768      * @param xmlPIs <code>true</code> if tidy should expect a ?> at the end of processing instructions
1769      * @see Configuration#xmlPIs
1770      */
1771     public void setXmlPIs(boolean xmlPIs)
1772     {
1773         configuration.xmlPIs = xmlPIs;
1774     }
1775 
1776     /***
1777      * <code>assume-xml-procins</code> This option specifies if Tidy should change the parsing of processing
1778      * instructions to require ?> as the terminator rather than >. This option is automatically set if the input is in
1779      * XML.
1780      * @return <code>true</code> if tidy will expect a ?> at the end of processing instructions
1781      * @see Configuration#xmlPIs
1782      */
1783     public boolean getXmlPIs()
1784     {
1785         return configuration.xmlPIs;
1786     }
1787 
1788     /***
1789      * <code>enclose-text</code>- if true text at body is wrapped in &lt;p&gt;'s.
1790      * @param encloseText <code>true</code> if tidy should wrap text at body in &lt;p&gt;'s.
1791      * @see Configuration#encloseBodyText
1792      */
1793     public void setEncloseText(boolean encloseText)
1794     {
1795         configuration.encloseBodyText = encloseText;
1796     }
1797 
1798     /***
1799      * <code>enclose-text</code>- if true text at body is wrapped in &lt;p&gt;'s.
1800      * @return <code>true</code> if tidy will wrap text at body in &lt;p&gt;'s.
1801      * @see Configuration#encloseBodyText
1802      */
1803     public boolean getEncloseText()
1804     {
1805         return configuration.encloseBodyText;
1806     }
1807 
1808     /***
1809      * <code>enclose-block-text</code>- if true text in blocks is wrapped in &lt;p&gt;'s.
1810      * @param encloseBlockText <code>true</code> if tidy should wrap text text in blocks in &lt;p&gt;'s.
1811      * @see Configuration#encloseBlockText
1812      */
1813     public void setEncloseBlockText(boolean encloseBlockText)
1814     {
1815         configuration.encloseBlockText = encloseBlockText;
1816     }
1817 
1818     /***
1819      * <code>enclose-block-text</code>- if true text in blocks is wrapped in &lt;p&gt;'s. return <code>true</code>
1820      * if tidy should will text text in blocks in &lt;p&gt;'s.
1821      * @see Configuration#encloseBlockText
1822      */
1823     public boolean getEncloseBlockText()
1824     {
1825         return configuration.encloseBlockText;
1826     }
1827 
1828     /***
1829      * <code>word-2000</code>- draconian cleaning for Word2000.
1830      * @param word2000 <code>true</code> if tidy should clean word2000 documents
1831      * @see Configuration#word2000
1832      */
1833     public void setWord2000(boolean word2000)
1834     {
1835         configuration.word2000 = word2000;
1836     }
1837 
1838     /***
1839      * <code>word-2000</code>- draconian cleaning for Word2000.
1840      * @return <code>true</code> if tidy will clean word2000 documents
1841      * @see Configuration#word2000
1842      */
1843     public boolean getWord2000()
1844     {
1845         return configuration.word2000;
1846     }
1847 
1848     /***
1849      * <code>tidy-mark</code>- add meta element indicating tidied doc.
1850      * @param tidyMark <code>true</code> if tidy should add meta element indicating tidied doc
1851      * @see Configuration#tidyMark
1852      */
1853     public void setTidyMark(boolean tidyMark)
1854     {
1855         configuration.tidyMark = tidyMark;
1856     }
1857 
1858     /***
1859      * <code>tidy-mark</code>- add meta element indicating tidied doc.
1860      * @return <code>true</code> if tidy will add meta element indicating tidied doc
1861      * @see Configuration#tidyMark
1862      */
1863     public boolean getTidyMark()
1864     {
1865         return configuration.tidyMark;
1866     }
1867 
1868     /***
1869      * <code>add-xml-space</code>- if set to yes adds xml:space attr as needed.
1870      * @param xmlSpace <code>true</code> if tidy should add xml:space attr as needed
1871      * @see Configuration#xmlSpace
1872      */
1873     public void setXmlSpace(boolean xmlSpace)
1874     {
1875         configuration.xmlSpace = xmlSpace;
1876     }
1877 
1878     /***
1879      * <code>add-xml-space</code>- if set to yes adds xml:space attr as needed.
1880      * @return <code>true</code> if tidy will add xml:space attr as needed
1881      * @see Configuration#xmlSpace
1882      */
1883     public boolean getXmlSpace()
1884     {
1885         return configuration.xmlSpace;
1886     }
1887 
1888     /***
1889      * <code>gnu-emacs</code>- if true format error output for GNU Emacs.
1890      * @param emacs <code>true</code> if tidy should format error output for GNU Emacs
1891      * @see Configuration#emacs
1892      */
1893     public void setEmacs(boolean emacs)
1894     {
1895         configuration.emacs = emacs;
1896     }
1897 
1898     /***
1899      * <code>gnu-emacs</code>- if true format error output for GNU Emacs.
1900      * @return <code>true</code> if tidy will format error output for GNU Emacs
1901      * @see Configuration#emacs
1902      */
1903     public boolean getEmacs()
1904     {
1905         return configuration.emacs;
1906     }
1907 
1908     /***
1909      * <code>literal-attributes</code>- if true attributes may use newlines.
1910      * @param literalAttribs <code>true</code> if attributes may use newlines
1911      * @see Configuration#literalAttribs
1912      */
1913     public void setLiteralAttribs(boolean literalAttribs)
1914     {
1915         configuration.literalAttribs = literalAttribs;
1916     }
1917 
1918     /***
1919      * <code>literal-attributes</code>- if true attributes may use newlines.
1920      * @return <code>true</code> if attributes may use newlines
1921      * @see Configuration#literalAttribs
1922      */
1923     public boolean getLiteralAttribs()
1924     {
1925         return configuration.literalAttribs;
1926     }
1927 
1928     /***
1929      * <code>print-body-only</code>- output BODY content only.
1930      * @param bodyOnly true = print only the document body
1931      * @see Configuration#bodyOnly
1932      */
1933     public void setPrintBodyOnly(boolean bodyOnly)
1934     {
1935         configuration.bodyOnly = bodyOnly;
1936     }
1937 
1938     /***
1939      * <code>print-body-only</code>- output BODY content only.
1940      * @return true if tidy will print only the document body
1941      */
1942     public boolean getPrintBodyOnly()
1943     {
1944         return configuration.bodyOnly;
1945     }
1946 
1947     /***
1948      * <code>fix-uri</code>- fix uri references applying URI encoding if necessary.
1949      * @param fixUri true = fix uri references
1950      * @see Configuration#fixUri
1951      */
1952     public void setFixUri(boolean fixUri)
1953     {
1954         configuration.fixUri = fixUri;
1955     }
1956 
1957     /***
1958      * <code>fix-uri</code>- output BODY content only.
1959      * @return true if tidy will fix uri references
1960      */
1961     public boolean getFixUri()
1962     {
1963         return configuration.fixUri;
1964     }
1965 
1966     /***
1967      * <code>lower-literals</code>- folds known attribute values to lower case.
1968      * @param lowerLiterals true = folds known attribute values to lower case
1969      * @see Configuration#lowerLiterals
1970      */
1971     public void setLowerLiterals(boolean lowerLiterals)
1972     {
1973         configuration.lowerLiterals = lowerLiterals;
1974     }
1975 
1976     /***
1977      * <code>lower-literals</code>- folds known attribute values to lower case.
1978      * @return true if tidy will folds known attribute values to lower case
1979      */
1980     public boolean getLowerLiterals()
1981     {
1982         return configuration.lowerLiterals;
1983     }
1984 
1985     /***
1986      * <code>hide-comments</code>- hides all (real) comments in output.
1987      * @param hideComments true = hides all comments in output
1988      * @see Configuration#hideComments
1989      */
1990     public void setHideComments(boolean hideComments)
1991     {
1992         configuration.hideComments = hideComments;
1993     }
1994 
1995     /***
1996      * <code>hide-comments</code>- hides all (real) comments in output.
1997      * @return true if tidy will hide all comments in output
1998      */
1999     public boolean getHideComments()
2000     {
2001         return configuration.hideComments;
2002     }
2003 
2004     /***
2005      * <code>indent-cdata</code>- indent CDATA sections.
2006      * @param indentCdata true = indent CDATA sections
2007      * @see Configuration#indentCdata
2008      */
2009     public void setIndentCdata(boolean indentCdata)
2010     {
2011         configuration.indentCdata = indentCdata;
2012     }
2013 
2014     /***
2015      * <code>indent-cdata</code>- indent CDATA sections.
2016      * @return true if tidy will indent CDATA sections
2017      */
2018     public boolean getIndentCdata()
2019     {
2020         return configuration.indentCdata;
2021     }
2022 
2023     /***
2024      * <code>force-output</code>- output document even if errors were found.
2025      * @param forceOutput true = output document even if errors were found
2026      * @see Configuration#forceOutput
2027      */
2028     public void setForceOutput(boolean forceOutput)
2029     {
2030         configuration.forceOutput = forceOutput;
2031     }
2032 
2033     /***
2034      * <code>force-output</code>- output document even if errors were found.
2035      * @return true if tidy will output document even if errors were found
2036      */
2037     public boolean getForceOutput()
2038     {
2039         return configuration.forceOutput;
2040     }
2041 
2042     /***
2043      * <code>show-errors</code>- set the number of errors to put out.
2044      * @param showErrors number of errors to put out
2045      * @see Configuration#showErrors
2046      */
2047     public void setShowErrors(int showErrors)
2048     {
2049         configuration.showErrors = showErrors;
2050     }
2051 
2052     /***
2053      * <code>show-errors</code>- number of errors to put out.
2054      * @return the number of errors tidy will put out
2055      */
2056     public int getShowErrors()
2057     {
2058         return configuration.showErrors;
2059     }
2060 
2061     /***
2062      * <code>ascii-chars</code>- convert quotes and dashes to nearest ASCII char.
2063      * @param asciiChars true = convert quotes and dashes to nearest ASCII char
2064      * @see Configuration#asciiChars
2065      */
2066     public void setAsciiChars(boolean asciiChars)
2067     {
2068         configuration.asciiChars = asciiChars;
2069     }
2070 
2071     /***
2072      * <code>ascii-chars</code>- convert quotes and dashes to nearest ASCII char.
2073      * @return true if tidy will convert quotes and dashes to nearest ASCII char
2074      */
2075     public boolean getAsciiChars()
2076     {
2077         return configuration.asciiChars;
2078     }
2079 
2080     /***
2081      * <code>join-classes</code>- join multiple class attributes.
2082      * @param joinClasses true = join multiple class attributes
2083      * @see Configuration#joinClasses
2084      */
2085     public void setJoinClasses(boolean joinClasses)
2086     {
2087         configuration.joinClasses = joinClasses;
2088     }
2089 
2090     /***
2091      * <code>join-classes</code>- join multiple class attributes.
2092      * @return true if tidy will join multiple class attributes
2093      */
2094     public boolean getJoinClasses()
2095     {
2096         return configuration.joinClasses;
2097     }
2098 
2099     /***
2100      * <code>join-styles</code>- join multiple style attributes.
2101      * @param joinStyles true = join multiple style attributes
2102      * @see Configuration#joinStyles
2103      */
2104     public void setJoinStyles(boolean joinStyles)
2105     {
2106         configuration.joinStyles = joinStyles;
2107     }
2108 
2109     /***
2110      * <code>join-styles</code>- join multiple style attributes.
2111      * @return true if tidy will join multiple style attributes
2112      */
2113     public boolean getJoinStyles()
2114     {
2115         return configuration.joinStyles;
2116     }
2117 
2118     /***
2119      * <code>trim-empty-elements</code>- trim empty elements.
2120      * @param trim-empty-elements true = trim empty elements
2121      * @see Configuration#trimEmpty
2122      */
2123     public void setTrimEmptyElements(boolean trimEmpty)
2124     {
2125         configuration.trimEmpty = trimEmpty;
2126     }
2127 
2128     /***
2129      * <code>trim-empty-elements</code>- trim empty elements.
2130      * @return true if tidy will trim empty elements
2131      */
2132     public boolean getTrimEmptyElements()
2133     {
2134         return configuration.trimEmpty;
2135     }
2136 
2137     /***
2138      * <code>replace-color</code>- replace hex color attribute values with names.
2139      * @param replaceColor true = replace hex color attribute values with names
2140      * @see Configuration#replaceColor
2141      */
2142     public void setReplaceColor(boolean replaceColor)
2143     {
2144         configuration.replaceColor = replaceColor;
2145     }
2146 
2147     /***
2148      * <code>replace-color</code>- replace hex color attribute values with names.
2149      * @return true if tidy will replace hex color attribute values with names
2150      */
2151     public boolean getReplaceColor()
2152     {
2153         return configuration.replaceColor;
2154     }
2155 
2156     /***
2157      * <code>escape-cdata</code>- replace CDATA sections with escaped text.
2158      * @param escapeCdata true = replace CDATA sections with escaped text
2159      * @see Configuration#escapeCdata
2160      */
2161     public void setEscapeCdata(boolean escapeCdata)
2162     {
2163         configuration.escapeCdata = escapeCdata;
2164     }
2165 
2166     /***
2167      * <code>escape-cdata</code> -replace CDATA sections with escaped text.
2168      * @return true if tidy will replace CDATA sections with escaped text
2169      */
2170     public boolean getEscapeCdata()
2171     {
2172         return configuration.escapeCdata;
2173     }
2174 
2175     /***
2176      * <code>repeated-attributes</code>- keep first or last duplicate attribute.
2177      * @param repeatedAttributes <code>Configuration.KEEP_FIRST | Configuration.KEEP_LAST</code>
2178      * @see Configuration#duplicateAttrs
2179      */
2180     public void setRepeatedAttributes(int repeatedAttributes)
2181     {
2182         configuration.duplicateAttrs = repeatedAttributes;
2183     }
2184 
2185     /***
2186      * <code>repeated-attributes</code>- keep first or last duplicate attribute.
2187      * @return <code>Configuration.KEEP_FIRST | Configuration.KEEP_LAST</code>
2188      */
2189     public int getRepeatedAttributes()
2190     {
2191         return configuration.duplicateAttrs;
2192     }
2193 
2194     /***
2195      * <code>keep-time</code>- if true last modified time is preserved.
2196      * @param keepFileTimes <code>true</code> if tidy should preserved last modified time in input file.
2197      * @todo <strong>this is NOT supported at this time. </strong>
2198      * @see Configuration#keepFileTimes
2199      */
2200     public void setKeepFileTimes(boolean keepFileTimes)
2201     {
2202         configuration.keepFileTimes = keepFileTimes;
2203     }
2204 
2205     /***
2206      * <code>keep-time</code>- if true last modified time is preserved.
2207      * @return <code>true</code> if tidy will preserved last modified time in input file.
2208      * @todo <strong>this is NOT supported at this time. </strong>
2209      * @see Configuration#keepFileTimes
2210      */
2211     public boolean getKeepFileTimes()
2212     {
2213         return configuration.keepFileTimes;
2214     }
2215 
2216     /***
2217      * Sets the character encoding used both for input and for output.
2218      * @param charencoding encoding constant
2219      * @deprecated set input/output encoding using java encoding names
2220      */
2221     public void setCharEncoding(int charencoding)
2222     {
2223         String ceName = configuration.convertCharEncoding(charencoding);
2224         if (ceName != null)
2225         {
2226             configuration.setInCharEncodingName(ceName);
2227             configuration.setOutCharEncodingName(ceName);
2228         }
2229     }
2230 
2231     /***
2232      * Returns the configured character encoding.
2233      * @return character encoding constant
2234      * @deprecated from r8 tidy can use different encoding for input and output. This method will only return the
2235      * <strong>input </strong> character encoding.
2236      */
2237     public int getCharEncoding()
2238     {
2239         return configuration.getInCharEncoding();
2240     }
2241 
2242     /***
2243      * @param slidestyle N/A
2244      * @deprecated does nothing
2245      */
2246     public void setSlidestyle(String slidestyle)
2247     {
2248         configuration.slidestyle = slidestyle;
2249     }
2250 
2251     /***
2252      * @deprecated does nothing
2253      * @return <code>null</code>
2254      */
2255     public String getSlidestyle()
2256     {
2257         return null;
2258     }
2259 
2260     /***
2261      * <code>output-raw</code>- avoid mapping values > 127 to entities. This has the same effect of specifying a
2262      * "raw" encoding in the original version of tidy.
2263      * @param rawOut avoid mapping values > 127 to entities
2264      * @see Configuration#rawOut
2265      */
2266     public void setRawOut(boolean rawOut)
2267     {
2268         configuration.rawOut = rawOut;
2269     }
2270 
2271     /***
2272      * <code>output-raw</code>- avoid mapping values > 127 to entities.
2273      * @return <code>true</code> if tidy will not map values > 127 to entities
2274      * @see Configuration#rawOut
2275      */
2276     public boolean getRawOut()
2277     {
2278         return configuration.rawOut;
2279     }
2280 
2281     /***
2282      * <code>input-encoding</code> the character encoding used for input.
2283      * @param encoding a valid java encoding name
2284      */
2285     public void setInputEncoding(String encoding)
2286     {
2287         configuration.setInCharEncodingName(encoding);
2288     }
2289 
2290     /***
2291      * <code>input-encoding</code> the character encoding used for input.
2292      * @return the java name of the encoding currently used for input
2293      */
2294     public String getInputEncoding()
2295     {
2296         return configuration.getInCharEncodingName();
2297     }
2298 
2299     /***
2300      * <code>output-encoding</code> the character encoding used for output.
2301      * @param encoding a valid java encoding name
2302      */
2303     public void setOutputEncoding(String encoding)
2304     {
2305         configuration.setOutCharEncodingName(encoding);
2306     }
2307 
2308     /***
2309      * <code>output-encoding</code> the character encoding used for output.
2310      * @return the java name of the encoding currently used for output
2311      */
2312     public String getOutputEncoding()
2313     {
2314         return configuration.getOutCharEncodingName();
2315     }
2316 
2317 }