intial version
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.jtidy / src / net / sourceforge / phpdt / tidy / w3c / Configuration.java
1 /*
2  * @(#)Configuration.java   1.11 2000/08/16
3  *
4  */
5
6 package net.sourceforge.phpdt.tidy.w3c;
7
8 /**
9  *
10  * Read configuration file and manage configuration properties.
11  *
12  * (c) 1998-2000 (W3C) MIT, INRIA, Keio University
13  * See Tidy.java for the copyright notice.
14  * Derived from <a href="http://www.w3.org/People/Raggett/tidy">
15  * HTML Tidy Release 4 Aug 2000</a>
16  *
17  * @author  Dave Raggett <dsr@w3.org>
18  * @author  Andy Quick <ac.quick@sympatico.ca> (translation to Java)
19  * @version 1.0, 1999/05/22
20  * @version 1.0.1, 1999/05/29
21  * @version 1.1, 1999/06/18 Java Bean
22  * @version 1.2, 1999/07/10 Tidy Release 7 Jul 1999
23  * @version 1.3, 1999/07/30 Tidy Release 26 Jul 1999
24  * @version 1.4, 1999/09/04 DOM support
25  * @version 1.5, 1999/10/23 Tidy Release 27 Sep 1999
26  * @version 1.6, 1999/11/01 Tidy Release 22 Oct 1999
27  * @version 1.7, 1999/12/06 Tidy Release 30 Nov 1999
28  * @version 1.8, 2000/01/22 Tidy Release 13 Jan 2000
29  * @version 1.9, 2000/06/03 Tidy Release 30 Apr 2000
30  * @version 1.10, 2000/07/22 Tidy Release 8 Jul 2000
31  * @version 1.11, 2000/08/16 Tidy Release 4 Aug 2000
32  */
33
34 /*
35   Configuration files associate a property name with a value.
36   The format is that of a Java .properties file.
37 */
38
39 import java.io.FileInputStream;
40 import java.io.IOException;
41 import java.util.Enumeration;
42 import java.util.Properties;
43 import java.util.StringTokenizer;
44
45 public class Configuration implements java.io.Serializable {
46
47     /* character encodings */
48     public static final int RAW         = 0;
49     public static final int ASCII       = 1;
50     public static final int LATIN1      = 2;
51     public static final int UTF8        = 3;
52     public static final int ISO2022     = 4;
53     public static final int MACROMAN    = 5;
54
55     /* mode controlling treatment of doctype */
56     public static final int DOCTYPE_OMIT  = 0;
57     public static final int DOCTYPE_AUTO  = 1;
58     public static final int DOCTYPE_STRICT= 2;
59     public static final int DOCTYPE_LOOSE = 3;
60     public static final int DOCTYPE_USER  = 4;
61
62     protected int spaces =  2;           /* default indentation */
63     protected int wraplen = 68;          /* default wrap margin */
64     protected int CharEncoding = ASCII;
65     protected int tabsize = 4;
66
67     protected int     docTypeMode = DOCTYPE_AUTO; /* see doctype property */
68     public String  altText = null;      /* default text for alt attribute */
69     protected String  slidestyle = null;    /* style sheet for slides */
70     protected String  docTypeStr = null;    /* user specified doctype */
71     protected String  errfile = null;       /* file name to write errors to */
72     protected boolean writeback = false;        /* if true then output tidied markup */
73
74     public boolean OnlyErrors = false;       /* if true normal output is suppressed */
75     public boolean ShowWarnings = true;      /* however errors are always shown */
76     public boolean Quiet = false;            /* no 'Parsing X', guessed DTD or summary */
77     public boolean IndentContent = false;    /* indent content of appropriate tags */
78     public boolean SmartIndent = false;      /* does text/block level content effect indentation */
79     public boolean HideEndTags = false;      /* suppress optional end tags */
80     public boolean XmlTags = false;          /* treat input as XML */
81     public boolean XmlOut = false;           /* create output as XML */
82     public boolean xHTML = false;            /* output extensible HTML */
83     public boolean XmlPi = false;            /* add <?xml?> for XML docs */
84     public boolean RawOut = false;           /* avoid mapping values > 127 to entities */
85     public boolean UpperCaseTags = false;    /* output tags in upper not lower case */
86     public boolean UpperCaseAttrs = false;   /* output attributes in upper not lower case */
87     public boolean MakeClean = false;        /* remove presentational clutter */
88     public boolean LogicalEmphasis = false;  /* replace i by em and b by strong */
89     public boolean DropFontTags = false;     /* discard presentation tags */
90     public boolean DropEmptyParas = true;    /* discard empty p elements */
91     public boolean FixComments = true;       /* fix comments with adjacent hyphens */
92     public boolean BreakBeforeBR = false;    /* o/p newline before <br> or not? */
93     public boolean BurstSlides = false;      /* create slides on each h2 element */
94     public boolean NumEntities = false;      /* use numeric entities */
95     public boolean QuoteMarks = false;       /* output " marks as &quot; */
96     public boolean QuoteNbsp = true;         /* output non-breaking space as entity */
97     public boolean QuoteAmpersand = true;    /* output naked ampersand as &amp; */
98     public boolean WrapAttVals = false;      /* wrap within attribute values */
99     public boolean WrapScriptlets = false;   /* wrap within JavaScript string literals */
100     public boolean WrapSection = true;       /* wrap within <![ ... ]> section tags */
101     public boolean WrapAsp = true;           /* wrap within ASP pseudo elements */
102     public boolean WrapJste = true;          /* wrap within JSTE pseudo elements */
103     public boolean WrapPhp = true;           /* wrap within PHP pseudo elements */
104     public boolean FixBackslash = true;      /* fix URLs by replacing \ with / */
105     public boolean IndentAttributes = false; /* newline+indent before each attribute */
106     public boolean XmlPIs = false;           /* if set to yes PIs must end with ?> */
107     public boolean XmlSpace = false;         /* if set to yes adds xml:space attr as needed */
108     public boolean EncloseBodyText = false;  /* if yes text at body is wrapped in <p>'s */
109     public boolean EncloseBlockText = false; /* if yes text in blocks is wrapped in <p>'s */
110     public boolean KeepFileTimes = true;     /* if yes last modied time is preserved */
111     public boolean Word2000 = false;         /* draconian cleaning for Word2000 */
112     public boolean TidyMark = true;          /* add meta element indicating tidied doc */
113     public boolean Emacs = false;            /* if true format error output for GNU Emacs */
114     public boolean LiteralAttribs = false;   /* if true attributes may use newlines */
115
116     // gschadow patch start
117     /** Remove all scripting XML tags (ASP, JSP, PHP,...) */
118     public boolean DropPseudoXMLCrap = false;
119     // gschadow patch end
120     
121     protected TagTable tt;                      /* TagTable associated with this Configuration */
122
123     private transient Properties _properties = new Properties();
124
125     public Configuration()
126     {
127     }
128
129     public void addProps( Properties p )
130     {
131         Enumeration enum = p.propertyNames();
132         while (enum.hasMoreElements())
133         {
134             String key = (String) enum.nextElement();
135             String value = p.getProperty(key);
136             _properties.put(key, value);
137         }
138         parseProps();
139     }
140
141     public void parseFile( String filename )
142     {
143         try
144         {
145             _properties.load( new FileInputStream( filename ) );
146         }
147         catch (IOException e)
148         {
149             System.err.println(filename + e.toString());
150             return;
151         }
152         parseProps();
153     }
154
155     private void parseProps()
156     {
157         String value;
158
159         value = _properties.getProperty("indent-spaces");
160         if (value != null)
161             spaces = parseInt(value, "indent-spaces");
162
163         value = _properties.getProperty("wrap");
164         if (value != null)
165             wraplen = parseInt(value, "wrap");
166
167         value = _properties.getProperty("wrap-attributes");
168         if (value != null)
169             WrapAttVals = parseBool(value, "wrap-attributes");
170
171         value = _properties.getProperty("wrap-script-literals");
172         if (value != null)
173             WrapScriptlets = parseBool(value, "wrap-script-literals");
174
175         value = _properties.getProperty("wrap-sections");
176         if (value != null)
177             WrapSection = parseBool(value, "wrap-sections");
178
179         value = _properties.getProperty("wrap-asp");
180         if (value != null)
181             WrapAsp = parseBool(value, "wrap-asp");
182
183         value = _properties.getProperty("wrap-jste");
184         if (value != null)
185             WrapJste = parseBool(value, "wrap-jste");
186
187         value = _properties.getProperty("wrap-php");
188         if (value != null)
189             WrapPhp = parseBool(value, "wrap-php");
190
191         value = _properties.getProperty("literal-attributes");
192         if (value != null)
193             LiteralAttribs = parseBool(value, "literal-attributes");
194
195         value = _properties.getProperty("tab-size");
196         if (value != null)
197             tabsize = parseInt(value, "tab-size");
198
199         value = _properties.getProperty("markup");
200         if (value != null)
201             OnlyErrors = parseInvBool(value, "markup");
202
203         value = _properties.getProperty("quiet");
204         if (value != null)
205             Quiet = parseBool(value, "quiet");
206
207         value = _properties.getProperty("tidy-mark");
208         if (value != null)
209             TidyMark = parseBool(value, "tidy-mark");
210
211         value = _properties.getProperty("indent");
212         if (value != null)
213             IndentContent = parseIndent(value, "indent");
214
215         value = _properties.getProperty("indent-attributes");
216         if (value != null)
217             IndentAttributes = parseBool(value, "ident-attributes");
218
219         value = _properties.getProperty("hide-endtags");
220         if (value != null)
221             HideEndTags = parseBool(value, "hide-endtags");
222
223         value = _properties.getProperty("input-xml");
224         if (value != null)
225             XmlTags = parseBool(value, "input-xml");
226
227         value = _properties.getProperty("output-xml");
228         if (value != null)
229             XmlOut = parseBool(value, "output-xml");
230
231         value = _properties.getProperty("output-xhtml");
232         if (value != null)
233             xHTML = parseBool(value, "output-xhtml");
234
235         value = _properties.getProperty("add-xml-pi");
236         if (value != null)
237             XmlPi = parseBool(value, "add-xml-pi");
238
239         value = _properties.getProperty("add-xml-decl");
240         if (value != null)
241             XmlPi = parseBool(value, "add-xml-decl");
242
243         value = _properties.getProperty("assume-xml-procins");
244         if (value != null)
245             XmlPIs = parseBool(value, "assume-xml-procins");
246
247         value = _properties.getProperty("raw");
248         if (value != null)
249             RawOut = parseBool(value, "raw");
250
251         value = _properties.getProperty("uppercase-tags");
252         if (value != null)
253             UpperCaseTags = parseBool(value, "uppercase-tags");
254
255         value = _properties.getProperty("uppercase-attributes");
256         if (value != null)
257             UpperCaseAttrs = parseBool(value, "uppercase-attributes");
258
259         value = _properties.getProperty("clean");
260         if (value != null)
261             MakeClean = parseBool(value, "clean");
262
263         value = _properties.getProperty("logical-emphasis");
264         if (value != null)
265             LogicalEmphasis = parseBool(value, "logical-emphasis");
266
267         value = _properties.getProperty("word-2000");
268         if (value != null)
269             Word2000 = parseBool(value, "word-2000");
270
271         value = _properties.getProperty("drop-empty-paras");
272         if (value != null)
273             DropEmptyParas = parseBool(value, "drop-empty-paras");
274
275         value = _properties.getProperty("drop-font-tags");
276         if (value != null)
277             DropFontTags = parseBool(value, "drop-font-tags");
278
279         //gschadow patch start
280         value = _properties.getProperty("drop-pseudo-xml-crap");
281         if (value != null)
282             DropPseudoXMLCrap = parseBool(value, "drop-pseudo-xml-crap");
283         //gschadow patch end
284
285         value = _properties.getProperty("enclose-text");
286         if (value != null)
287             EncloseBodyText = parseBool(value, "enclose-text");
288
289         value = _properties.getProperty("enclose-block-text");
290         if (value != null)
291             EncloseBlockText = parseBool(value, "enclose-block-text");
292
293         value = _properties.getProperty("alt-text");
294         if (value != null)
295             altText = value;
296
297         value = _properties.getProperty("add-xml-space");
298         if (value != null)
299             XmlSpace = parseBool(value, "add-xml-space");
300
301         value = _properties.getProperty("fix-bad-comments");
302         if (value != null)
303             FixComments = parseBool(value, "fix-bad-comments");
304
305         value = _properties.getProperty("split");
306         if (value != null)
307             BurstSlides = parseBool(value, "split");
308
309         value = _properties.getProperty("break-before-br");
310         if (value != null)
311             BreakBeforeBR = parseBool(value, "break-before-br");
312
313         value = _properties.getProperty("numeric-entities");
314         if (value != null)
315             NumEntities = parseBool(value, "numeric-entities");
316
317         value = _properties.getProperty("quote-marks");
318         if (value != null)
319             QuoteMarks = parseBool(value, "quote-marks");
320
321         value = _properties.getProperty("quote-nbsp");
322         if (value != null)
323             QuoteNbsp = parseBool(value, "quote-nbsp");
324
325         value = _properties.getProperty("quote-ampersand");
326         if (value != null)
327             QuoteAmpersand = parseBool(value, "quote-ampersand");
328
329         value = _properties.getProperty("write-back");
330         if (value != null)
331             writeback = parseBool(value, "write-back");
332
333         value = _properties.getProperty("keep-time");
334         if (value != null)
335             KeepFileTimes = parseBool(value, "keep-time");
336
337         value = _properties.getProperty("show-warnings");
338         if (value != null)
339             ShowWarnings = parseBool(value, "show-warnings");
340
341         value = _properties.getProperty("error-file");
342         if (value != null)
343             errfile = parseName(value, "error-file");
344
345         value = _properties.getProperty("slide-style");
346         if (value != null)
347             slidestyle = parseName(value, "slide-style");
348
349         value = _properties.getProperty("new-inline-tags");
350         if (value != null)
351             parseInlineTagNames(value, "new-inline-tags");
352
353         value = _properties.getProperty("new-blocklevel-tags");
354         if (value != null)
355             parseBlockTagNames(value, "new-blocklevel-tags");
356
357         value = _properties.getProperty("new-empty-tags");
358         if (value != null)
359             parseEmptyTagNames(value, "new-empty-tags");
360
361         value = _properties.getProperty("new-pre-tags");
362         if (value != null)
363             parsePreTagNames(value, "new-pre-tags");
364
365         value = _properties.getProperty("char-encoding");
366         if (value != null)
367             CharEncoding = parseCharEncoding(value, "char-encoding");
368
369         value = _properties.getProperty("doctype");
370         if (value != null)
371             docTypeStr = parseDocType(value, "doctype");
372
373         value = _properties.getProperty("fix-backslash");
374         if (value != null)
375             FixBackslash = parseBool(value, "fix-backslash");
376
377         value = _properties.getProperty("gnu-emacs");
378         if (value != null)
379             Emacs = parseBool(value, "gnu-emacs");
380     }
381
382     /* ensure that config is self consistent */
383     public void adjust()
384     {
385         if (EncloseBlockText)
386             EncloseBodyText = true;
387
388         /* avoid the need to set IndentContent when SmartIndent is set */
389
390         if (SmartIndent)
391             IndentContent = true;
392
393         /* disable wrapping */
394         if (wraplen == 0)
395             wraplen = 0x7FFFFFFF;
396
397         /* Word 2000 needs o:p to be declared as inline */
398         if (Word2000)
399         {
400             tt.defineInlineTag("o:p");
401         }
402
403         /* XHTML is written in lower case */
404         if (xHTML)
405         {
406             XmlOut = true;
407             UpperCaseTags = false;
408             UpperCaseAttrs = false;
409         }
410
411         /* if XML in, then XML out */
412         if (XmlTags)
413         {
414             XmlOut = true;
415             XmlPIs = true;
416         }
417
418         /* XML requires end tags */
419         if (XmlOut)
420         {
421             QuoteAmpersand = true;
422             HideEndTags = false;
423         }
424     }
425
426     private static int parseInt( String s, String option )
427     {
428         int i = 0;
429         try {
430             i = Integer.parseInt( s );
431         }
432         catch ( NumberFormatException e ) {
433             Report.badArgument(option);
434             i = -1;
435         }
436         return i;
437     }
438
439     private static boolean parseBool( String s, String option )
440     {
441         boolean b = false;
442         if ( s != null && s.length() > 0 ) {
443             char c = s.charAt(0);
444             if ((c == 't') || (c == 'T') || (c == 'Y') || (c == 'y') || (c == '1'))
445                 b = true;
446             else if ((c == 'f') || (c == 'F') || (c == 'N') || (c == 'n') || (c == '0'))
447                 b = false;
448             else
449                 Report.badArgument(option);
450         }
451         return b;
452     }
453
454     private static boolean parseInvBool( String s, String option )
455     {
456         boolean b = false;
457         if ( s != null && s.length() > 0 ) {
458             char c = s.charAt(0);
459             if ((c == 't') || (c == 'T') || (c == 'Y') || (c == 'y'))
460                 b = true;
461             else if ((c == 'f') || (c == 'F') || (c == 'N') || (c == 'n'))
462                 b = false;
463             else
464                 Report.badArgument(option);
465         }
466         return !b;
467     }
468
469     private static String parseName( String s, String option )
470     {
471         StringTokenizer t = new StringTokenizer( s );
472         String rs = null;
473         if ( t.countTokens() >= 1 )
474             rs = t.nextToken();
475         else
476             Report.badArgument(option);
477         return rs;
478     }
479
480     private static int parseCharEncoding( String s, String option )
481     {
482         int result = ASCII;
483
484         if (Lexer.wstrcasecmp(s, "ascii") == 0)
485             result = ASCII;
486         else if (Lexer.wstrcasecmp(s, "latin1") == 0)
487             result = LATIN1;
488         else if (Lexer.wstrcasecmp(s, "raw") == 0)
489             result = RAW;
490         else if (Lexer.wstrcasecmp(s, "utf8") == 0)
491             result = UTF8;
492         else if (Lexer.wstrcasecmp(s, "iso2022") == 0)
493             result = ISO2022;
494         else if (Lexer.wstrcasecmp(s, "mac") == 0)
495             result = MACROMAN;
496         else
497             Report.badArgument(option);
498
499         return result;
500     }
501
502     /* slight hack to avoid changes to pprint.c */
503     private boolean parseIndent( String s, String option )
504     {
505         boolean b = IndentContent;
506
507         if (Lexer.wstrcasecmp(s, "yes") == 0)
508         {
509             b = true;
510             SmartIndent = false;
511         }
512         else if (Lexer.wstrcasecmp(s, "true") == 0)
513         {
514             b = true;
515             SmartIndent = false;
516         }
517         else if (Lexer.wstrcasecmp(s, "no") == 0)
518         {
519             b = false;
520             SmartIndent = false;
521         }
522         else if (Lexer.wstrcasecmp(s, "false") == 0)
523         {
524             b = false;
525             SmartIndent = false;
526         }
527         else if (Lexer.wstrcasecmp(s, "auto") == 0)
528         {
529             b = true;
530             SmartIndent = true;
531         }
532         else
533             Report.badArgument(option);
534         return b;
535     }
536
537     public void parseInlineTagNames( String s, String option )
538     {
539         StringTokenizer t = new StringTokenizer( s, " \t\n\r," );
540         while ( t.hasMoreTokens() ) {
541             tt.defineInlineTag( t.nextToken() );
542         }
543     }
544
545     public void parseBlockTagNames( String s, String option )
546     {
547         StringTokenizer t = new StringTokenizer( s, " \t\n\r," );
548         while ( t.hasMoreTokens() ) {
549             tt.defineBlockTag( t.nextToken() );
550         }
551     }
552
553     public void parseEmptyTagNames( String s, String option )
554     {
555         StringTokenizer t = new StringTokenizer( s, " \t\n\r," );
556         while ( t.hasMoreTokens() ) {
557             tt.defineEmptyTag( t.nextToken() );
558         }
559     }
560
561     public void parsePreTagNames( String s, String option )
562     {
563         StringTokenizer t = new StringTokenizer( s, " \t\n\r," );
564         while ( t.hasMoreTokens() ) {
565             tt.definePreTag( t.nextToken() );
566         }
567     }
568
569     /*
570        doctype: omit | auto | strict | loose | <fpi>
571
572        where the fpi is a string similar to
573
574           "-//ACME//DTD HTML 3.14159//EN"
575     */
576     protected String parseDocType( String s, String option )
577     {
578         s = s.trim();
579
580         /* "-//ACME//DTD HTML 3.14159//EN" or similar */
581
582         if (s.startsWith("\""))
583         {
584             docTypeMode = DOCTYPE_USER;
585             return s;
586         }
587
588         /* read first word */
589         String word = "";
590         StringTokenizer t = new StringTokenizer( s, " \t\n\r," );
591         if (t.hasMoreTokens())
592             word = t.nextToken();
593
594         if (Lexer.wstrcasecmp(word, "omit") == 0)
595             docTypeMode = DOCTYPE_OMIT;
596         else if (Lexer.wstrcasecmp(word, "strict") == 0)
597             docTypeMode = DOCTYPE_STRICT;
598         else if (Lexer.wstrcasecmp(word, "loose") == 0 ||
599                  Lexer.wstrcasecmp(word, "transitional") == 0)
600             docTypeMode = DOCTYPE_LOOSE;
601         else if (Lexer.wstrcasecmp(word, "auto") == 0)
602             docTypeMode = DOCTYPE_AUTO;
603         else
604         {
605             docTypeMode = DOCTYPE_AUTO;
606             Report.badArgument(option);
607         }
608         return null;
609     }
610
611 }