KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > output > HTMLEmitter


1 package com.icl.saxon.output;
2 import com.icl.saxon.*;
3 import com.icl.saxon.om.NamePool;
4 import com.icl.saxon.sort.HashMap;
5 import org.xml.sax.Locator JavaDoc;
6 import org.xml.sax.Attributes JavaDoc;
7 import com.icl.saxon.tree.AttributeCollection;
8 import java.io.*;
9
10 import javax.xml.transform.OutputKeys JavaDoc;
11 import javax.xml.transform.TransformerException JavaDoc;
12
13 /**
14   * This class generates HTML output
15   * @author <A HREF="mailto:mhkay@iclway.co.uk>Michael H. Kay</A>
16   */

17
18 public class HTMLEmitter extends XMLEmitter {
19     
20     /**
21     * Preferred character representations
22     */

23     
24     private final static int REP_NATIVE = 0;
25     private final static int REP_ENTITY = 1;
26     private final static int REP_DECIMAL = 2;
27     private final static int REP_HEX = 3;
28     
29     private int nonASCIIRepresentation = REP_ENTITY;
30     private int excludedRepresentation = REP_DECIMAL;
31     private String JavaDoc mediaType = "text/html";
32     private int inScript;
33     private boolean started = false;
34     
35     /**
36     * Decode preferred representation
37     */

38     
39     private static int representationCode(String JavaDoc rep) {
40         if (rep.equalsIgnoreCase("native")) return REP_NATIVE;
41         if (rep.equalsIgnoreCase("entity")) return REP_ENTITY;
42         if (rep.equalsIgnoreCase("decimal")) return REP_DECIMAL;
43         if (rep.equalsIgnoreCase("hex")) return REP_HEX;
44         return REP_ENTITY;
45     }
46
47     /**
48     * Table of HTML tags that have no closing tag
49     */

50
51     static HashMap emptyTags = new HashMap(101);
52
53     static {
54         setEmptyTag("area");
55         setEmptyTag("base");
56         setEmptyTag("basefont");
57         setEmptyTag("br");
58         setEmptyTag("col");
59         setEmptyTag("frame");
60         setEmptyTag("hr");
61         setEmptyTag("img");
62         setEmptyTag("input");
63         setEmptyTag("isindex");
64         setEmptyTag("link");
65         setEmptyTag("meta");
66         setEmptyTag("param");
67     }
68
69     private static void setEmptyTag(String JavaDoc tag) {
70         emptyTags.set(tag);
71     }
72
73     protected static boolean isEmptyTag(String JavaDoc tag) {
74         return emptyTags.get(tag);
75     }
76
77     /**
78     * Table of boolean attributes
79     */

80
81     // we use two HashMaps to avoid unnecessary string concatenations
82

83     private static HashMap booleanAttributes = new HashMap(101);
84     private static HashMap booleanCombinations = new HashMap(203);
85
86     static {
87         setBooleanAttribute("area", "nohref");
88         setBooleanAttribute("button", "disabled");
89         setBooleanAttribute("dir", "compact");
90         setBooleanAttribute("dl", "compact");
91         setBooleanAttribute("frame", "noresize");
92         setBooleanAttribute("hr", "noshade");
93         setBooleanAttribute("img", "ismap");
94         setBooleanAttribute("input", "checked");
95         setBooleanAttribute("input", "disabled");
96         setBooleanAttribute("input", "readonly");
97         setBooleanAttribute("menu", "compact");
98         setBooleanAttribute("object", "declare");
99         setBooleanAttribute("ol", "compact");
100         setBooleanAttribute("optgroup", "disabled");
101         setBooleanAttribute("option", "selected");
102         setBooleanAttribute("option", "disabled");
103         setBooleanAttribute("script", "defer");
104         setBooleanAttribute("select", "multiple");
105         setBooleanAttribute("select", "disabled");
106         setBooleanAttribute("td", "nowrap");
107         setBooleanAttribute("textarea", "disabled");
108         setBooleanAttribute("textarea", "readonly");
109         setBooleanAttribute("th", "nowrap");
110         setBooleanAttribute("ul", "compact");
111     }
112
113     private static void setBooleanAttribute(String JavaDoc element, String JavaDoc attribute) {
114         booleanAttributes.set(attribute);
115         booleanCombinations.set(element + "+" + attribute);
116     }
117
118     private static boolean isBooleanAttribute(String JavaDoc element, String JavaDoc attribute, String JavaDoc value) {
119         if (!attribute.equalsIgnoreCase(value)) return false;
120         if (!booleanAttributes.get(attribute)) return false;
121         return booleanCombinations.get(element + "+" + attribute);
122     }
123
124     /**
125     * Table of attributes whose value is a URL
126     */

127
128     // we use two HashMaps to avoid unnecessary string concatenations
129

130     private static HashMap urlAttributes = new HashMap(101);
131     private static HashMap urlCombinations = new HashMap(203);
132
133     static {
134         setUrlAttribute("form", "action");
135         setUrlAttribute("body", "background");
136         setUrlAttribute("q", "cite");
137         setUrlAttribute("blockquote", "cite");
138         setUrlAttribute("del", "cite");
139         setUrlAttribute("ins", "cite");
140         setUrlAttribute("object", "classid");
141         setUrlAttribute("object", "codebase");
142         setUrlAttribute("applet", "codebase");
143         setUrlAttribute("object", "data");
144         setUrlAttribute("a", "href");
145         setUrlAttribute("a", "name"); // see second note in section B.2.1 of HTML 4 specification
146
setUrlAttribute("area", "href");
147         setUrlAttribute("link", "href");
148         setUrlAttribute("base", "href");
149         setUrlAttribute("img", "longdesc");
150         setUrlAttribute("frame", "longdesc");
151         setUrlAttribute("iframe", "longdesc");
152         setUrlAttribute("head", "profile");
153         setUrlAttribute("script", "src");
154         setUrlAttribute("input", "src");
155         setUrlAttribute("frame", "src");
156         setUrlAttribute("iframe", "src");
157         setUrlAttribute("img", "src");
158         setUrlAttribute("img", "usemap");
159         setUrlAttribute("input", "usemap");
160         setUrlAttribute("object", "usemap");
161     }
162
163     private static void setUrlAttribute(String JavaDoc element, String JavaDoc attribute) {
164         urlAttributes.set(attribute);
165         urlCombinations.set(element + "+" + attribute);
166     }
167
168     public static boolean isUrlAttribute(String JavaDoc element, String JavaDoc attribute) {
169         if (!urlAttributes.get(attribute)) return false;
170         return urlCombinations.get(element + "+" + attribute);
171     }
172
173     /**
174     * Constructor
175     */

176
177     public HTMLEmitter() {
178
179     }
180
181     /**
182     * Output start of document
183     */

184
185     public void startDocument() throws TransformerException JavaDoc {
186         if (started) return;
187         started = true; // avoid multiple DOCTYPE declarations
188

189         String JavaDoc mime = outputProperties.getProperty(OutputKeys.MEDIA_TYPE);
190         if (mime!=null) {
191             mediaType = mime;
192         }
193
194         String JavaDoc systemId = outputProperties.getProperty(OutputKeys.DOCTYPE_SYSTEM);
195         String JavaDoc publicId = outputProperties.getProperty(OutputKeys.DOCTYPE_PUBLIC);
196
197         if (systemId!=null || publicId!=null) {
198             writeDocType("html", systemId, publicId);
199         }
200         
201         empty = false;
202         inScript = -1000000;
203         
204         String JavaDoc representation = outputProperties.getProperty(
205                                     SaxonOutputKeys.CHARACTER_REPRESENTATION);
206         if (representation!=null) {
207             String JavaDoc nonASCIIrep;
208             String JavaDoc excludedRep;
209             int semi = representation.indexOf(';');
210             if (semi < 0) {
211                 nonASCIIrep = representation;
212                 excludedRep = representation;
213             } else {
214                 nonASCIIrep = representation.substring(0, semi).trim();
215                 excludedRep = representation.substring(semi+1).trim();
216             }
217             nonASCIIRepresentation = representationCode(nonASCIIrep);
218             excludedRepresentation = representationCode(excludedRep);
219             if (excludedRepresentation==REP_NATIVE) {
220                 excludedRepresentation = REP_ENTITY;
221             }
222         }
223                     
224     }
225
226     /**
227     * Output element start tag
228     */

229
230     public void startElement(int nameCode, Attributes JavaDoc atts,
231                              int[] namespaces, int nscount) throws TransformerException JavaDoc {
232         String JavaDoc name = namePool.getLocalName(nameCode);
233         short uriCode = namePool.getURICode(nameCode);
234         if (uriCode==0 && (name.equalsIgnoreCase("script") ||
235                 name.equalsIgnoreCase("style"))) {
236             inScript = 0;
237         }
238         inScript++;
239         super.startElement(nameCode, atts, namespaces, nscount);
240         closeStartTag(-1, false); // prevent <xxx/> syntax
241

242         // add a META tag after the HEAD tag if there is one.
243
if (uriCode==0 && name.equalsIgnoreCase("head")) {
244             String JavaDoc omitMeta = outputProperties.getProperty(
245                                     SaxonOutputKeys.OMIT_META_TAG);
246             if (!("yes".equals(omitMeta))) {
247             
248                 String JavaDoc encoding = outputProperties.getProperty(OutputKeys.ENCODING);
249                 if (encoding==null) encoding = "utf-8";
250             
251                 AttributeCollection metaatts = new AttributeCollection(namePool);
252                 metaatts.addAttribute("", "", "http-equiv", "CDATA", "Content-Type");
253                 metaatts.addAttribute("", "", "content", "CDATA", mediaType + "; charset=" + encoding);
254
255                 try {writer.write("\n ");} catch (java.io.IOException JavaDoc err){}
256                 int meta = namePool.allocate("", "", "meta");
257                 startElement(meta, metaatts, new int[0], 0);
258                 endElement(meta); // for form's sake
259
try {writer.write("\n ");} catch (java.io.IOException JavaDoc err){}
260             }
261         }
262     }
263
264     /**
265     * Write attribute name=value pair. Overrides the XML behaviour if the name and value
266     * are the same (we assume this is a boolean attribute to be minimised), or if the value is
267     * a URL.
268     */

269
270     protected void writeAttribute(int elCode, String JavaDoc attname, String JavaDoc type, String JavaDoc value) throws TransformerException JavaDoc {
271         try {
272             String JavaDoc elname = namePool.getDisplayName(elCode);
273             short uriCode = namePool.getURICode(elCode);
274             if (uriCode==0 && isBooleanAttribute(elname, attname, value)) {
275                 testCharacters(attname);
276                 writer.write(attname);
277             } else if (uriCode==0 && isUrlAttribute(elname, attname) && !type.equals("NO-ESC")) {
278                 String JavaDoc esc = escapeURL(value);
279                 super.writeAttribute(elCode, attname, type, esc);
280             } else {
281                 super.writeAttribute(elCode, attname, type, value);
282             }
283         } catch (java.io.IOException JavaDoc err) {
284             throw new TransformerException JavaDoc(err);
285         }
286     }
287
288
289     /**
290     * Escape characters. Overrides the XML behaviour
291     */

292
293     protected void writeEscape(char ch[], int start, int length, boolean inAttribute)
294     throws java.io.IOException JavaDoc {
295
296         int segstart = start;
297         boolean[] specialChars = (inAttribute ? specialInAtt : specialInText);
298
299         while (segstart < start+length) {
300             int i = segstart;
301             
302             // find a maximal sequence of "ordinary" characters
303

304             while (i < start+length &&
305                      (ch[i]<128 ?
306                          !specialChars[ch[i]] :
307                          (characterSet.inCharset(ch[i]) ?
308                             nonASCIIRepresentation == REP_NATIVE && ch[i]!=160 :
309                             false)
310                      )
311                   ) {
312                 i++;
313             }
314
315             // output this sequence
316

317             writer.write(ch, segstart, i-segstart);
318
319             // if this was the whole string, quit
320

321             if (i == start+length) return;
322
323             if (ch[i]<127) {
324
325                 // handle a special ASCII character
326

327                 if (inAttribute) {
328                     if (ch[i]=='<') {
329                         writer.write('<'); // not escaped
330
} else if (ch[i]=='>') {
331                         writer.write("&gt;"); // recommended for older browsers
332
} else if (ch[i]=='&') {
333                         if (i+1<start+length && ch[i+1]=='{') {
334                             writer.write('&'); // not escaped if followed by '{'
335
} else {
336                             writer.write("&amp;");
337                         }
338                     } else if (ch[i]=='\"') {
339                         writer.write("&#34;");
340                     } else if (ch[i]=='\n') {
341                         writer.write("&#xA;");
342                     }
343                 } else {
344                     if (ch[i]=='<') {
345                         writer.write("&lt;");
346                     } else if (ch[i]=='>') {
347                         writer.write("&gt;"); // changed to allow for "]]>"
348
} else if (ch[i]=='&') {
349                         writer.write("&amp;");
350                     }
351                 }
352             
353             } else if (ch[i]==160) {
354                 // always output NBSP as an entity reference
355
writer.write("&nbsp;");
356
357             } else if (ch[i]>=55296 && ch[i]<=56319) { //handle surrogate pair
358

359                 //A surrogate pair is two consecutive Unicode characters. The first
360
//is in the range D800 to DBFF, the second is in the range DC00 to DFFF.
361
//To compute the numeric value of the character corresponding to a surrogate
362
//pair, use this formula (all numbers are hex):
363
//(FirstChar - D800) * 400 + (SecondChar - DC00) + 10000
364

365                     // we'll trust the data to be sound
366
int charval = (((int)ch[i] - 55296) * 1024) + ((int)ch[i+1] - 56320) + 65536;
367                 outputCharacterReference(charval);
368                 i++;
369
370             
371             } else if (characterSet.inCharset(ch[i])) {
372                 switch(nonASCIIRepresentation) {
373                     case REP_NATIVE:
374                         writer.write(ch[i]);
375                         break;
376                     case REP_ENTITY:
377                         if (ch[i]>160 && ch[i]<=255) {
378                 
379                             // if chararacter in iso-8859-1, use an entity reference
380

381                             writer.write('&');
382                             writer.write(latin1Entities[(int)ch[i]-160]);
383                             writer.write(';');
384                             break;
385                         }
386                         // else fall through
387
case REP_DECIMAL:
388                         preferHex = false;
389                         outputCharacterReference(ch[i]);
390                         break;
391                     case REP_HEX:
392                         preferHex = true;
393                         // fall through
394
default:
395                         outputCharacterReference(ch[i]);
396                         break;
397                 }
398
399             } else { // output numeric character reference
400
preferHex = (excludedRepresentation==REP_HEX);
401                 outputCharacterReference((int)ch[i]);
402             }
403
404             segstart = ++i;
405         }
406
407     }
408
409     /**
410     * Output an element end tag.<br>
411     * @param name The element name (tag)
412     */

413
414     public void endElement(int nameCode) throws TransformerException JavaDoc {
415         String JavaDoc name = namePool.getLocalName(nameCode);
416         short uriCode = namePool.getURICode(nameCode);
417         inScript--;
418         if (inScript==0) {
419             inScript = -1000000;
420         }
421
422         if (uriCode!=0 || !isEmptyTag(name)) {
423             super.endElement(nameCode);
424         }
425
426     }
427
428     /**
429     * Character data.
430     */

431
432     public void characters (char[] ch, int start, int length)
433     throws TransformerException JavaDoc {
434         if (inScript>0 && escaping) {
435             setEscaping(false);
436             super.characters(ch, start, length);
437             setEscaping(true);
438         } else {
439             super.characters(ch, start, length);
440         }
441     }
442
443     /**
444     * Handle a processing instruction.
445     */

446     
447     public void processingInstruction (String JavaDoc target, String JavaDoc data)
448         throws TransformerException JavaDoc
449     {
450         try {
451             writer.write("<?");
452             writer.write(target);
453             writer.write(' ');
454             writer.write(data);
455             writer.write('>');
456         } catch (java.io.IOException JavaDoc err) {
457             throw new TransformerException JavaDoc(err);
458         }
459     }
460
461
462     private static String JavaDoc escapeURL(String JavaDoc url) throws TransformerException JavaDoc {
463         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
464         String JavaDoc hex = "0123456789ABCDEF";
465         for (int i=0; i<url.length(); i++) {
466             char ch = url.charAt(i);
467             if (ch<32 || ch>126) {
468                 ByteArrayOutputStream baw = new ByteArrayOutputStream();
469                 try {
470                     OutputStreamWriter osw = new OutputStreamWriter(baw, "UTF8");
471                     osw.write(ch);
472                     osw.close();
473                 } catch (UnsupportedEncodingException err1) {
474                     throw new TransformerException JavaDoc(err1);
475                 } catch (java.io.IOException JavaDoc err) {
476                     throw new TransformerException JavaDoc(err);
477                 }
478                 byte[] array = baw.toByteArray();
479                 for (int b=0; b<array.length; b++) {
480                     int v = (array[b]>=0 ? array[b] : 256 + array[b]);
481                     sb.append('%');
482                     sb.append(hex.charAt(v/16));
483                     sb.append(hex.charAt(v%16));
484                 }
485
486             } else {
487                 sb.append(ch);
488             }
489         }
490         return sb.toString();
491     }
492
493     private static String JavaDoc[] latin1Entities = {
494
495         "nbsp", // "&#160;" -- no-break space = non-breaking space,
496
// U+00A0 ISOnum -->
497
"iexcl", // "&#161;" -- inverted exclamation mark, U+00A1 ISOnum -->
498
"cent", // "&#162;" -- cent sign, U+00A2 ISOnum -->
499
"pound", // "&#163;" -- pound sign, U+00A3 ISOnum -->
500
"curren", // "&#164;" -- currency sign, U+00A4 ISOnum -->
501
"yen", // "&#165;" -- yen sign = yuan sign, U+00A5 ISOnum -->
502
"brvbar", // "&#166;" -- broken bar = broken vertical bar,
503
// U+00A6 ISOnum -->
504
"sect", // "&#167;" -- section sign, U+00A7 ISOnum -->
505
"uml", // "&#168;" -- diaeresis = spacing diaeresis,
506
// U+00A8 ISOdia -->
507
"copy", // "&#169;" -- copyright sign, U+00A9 ISOnum -->
508
"ordf", // "&#170;" -- feminine ordinal indicator, U+00AA ISOnum -->
509
"laquo", // "&#171;" -- left-pointing double angle quotation mark
510
// = left pointing guillemet, U+00AB ISOnum -->
511
"not", // "&#172;" -- not sign, U+00AC ISOnum -->
512
"shy", // "&#173;" -- soft hyphen = discretionary hyphen,
513
// U+00AD ISOnum -->
514
"reg", // "&#174;" -- registered sign = registered trade mark sign,
515
// U+00AE ISOnum -->
516
"macr", // "&#175;" -- macron = spacing macron = overline
517
// = APL overbar, U+00AF ISOdia -->
518
"deg", // "&#176;" -- degree sign, U+00B0 ISOnum -->
519
"plusmn", // "&#177;" -- plus-minus sign = plus-or-minus sign,
520
// U+00B1 ISOnum -->
521
"sup2", // "&#178;" -- superscript two = superscript digit two
522
// = squared, U+00B2 ISOnum -->
523
"sup3", // "&#179;" -- superscript three = superscript digit three
524
// = cubed, U+00B3 ISOnum -->
525
"acute", // "&#180;" -- acute accent = spacing acute,
526
// U+00B4 ISOdia -->
527
"micro", // "&#181;" -- micro sign, U+00B5 ISOnum -->
528
"para", // "&#182;" -- pilcrow sign = paragraph sign,
529
// U+00B6 ISOnum -->
530
"middot", // "&#183;" -- middle dot = Georgian comma
531
// = Greek middle dot, U+00B7 ISOnum -->
532
"cedil", // "&#184;" -- cedilla = spacing cedilla, U+00B8 ISOdia -->
533
"sup1", // "&#185;" -- superscript one = superscript digit one,
534
// U+00B9 ISOnum -->
535
"ordm", // "&#186;" -- masculine ordinal indicator,
536
// U+00BA ISOnum -->
537
"raquo", // "&#187;" -- right-pointing double angle quotation mark
538
// = right pointing guillemet, U+00BB ISOnum -->
539
"frac14", // "&#188;" -- vulgar fraction one quarter
540
// = fraction one quarter, U+00BC ISOnum -->
541
"frac12", // "&#189;" -- vulgar fraction one half
542
// = fraction one half, U+00BD ISOnum -->
543
"frac34", // "&#190;" -- vulgar fraction three quarters
544
// = fraction three quarters, U+00BE ISOnum -->
545
"iquest", // "&#191;" -- inverted question mark
546
// = turned question mark, U+00BF ISOnum -->
547
"Agrave", // "&#192;" -- latin capital letter A with grave
548
// = latin capital letter A grave,
549
// U+00C0 ISOlat1 -->
550
"Aacute", // "&#193;" -- latin capital letter A with acute,
551
// U+00C1 ISOlat1 -->
552
"Acirc", // "&#194;" -- latin capital letter A with circumflex,
553
// U+00C2 ISOlat1 -->
554
"Atilde", // "&#195;" -- latin capital letter A with tilde,
555
// U+00C3 ISOlat1 -->
556
"Auml", // "&#196;" -- latin capital letter A with diaeresis,
557
// U+00C4 ISOlat1 -->
558
"Aring", // "&#197;" -- latin capital letter A with ring above
559
// = latin capital letter A ring,
560
// U+00C5 ISOlat1 -->
561
"AElig", // "&#198;" -- latin capital letter AE
562
// = latin capital ligature AE,
563
// U+00C6 ISOlat1 -->
564
"Ccedil", // "&#199;" -- latin capital letter C with cedilla,
565
// U+00C7 ISOlat1 -->
566
"Egrave", // "&#200;" -- latin capital letter E with grave,
567
// U+00C8 ISOlat1 -->
568
"Eacute", // "&#201;" -- latin capital letter E with acute,
569
// U+00C9 ISOlat1 -->
570
"Ecirc", // "&#202;" -- latin capital letter E with circumflex,
571
// U+00CA ISOlat1 -->
572
"Euml", // "&#203;" -- latin capital letter E with diaeresis,
573
// U+00CB ISOlat1 -->
574
"Igrave", // "&#204;" -- latin capital letter I with grave,
575
// U+00CC ISOlat1 -->
576
"Iacute", // "&#205;" -- latin capital letter I with acute,
577
// U+00CD ISOlat1 -->
578
"Icirc", // "&#206;" -- latin capital letter I with circumflex,
579
// U+00CE ISOlat1 -->
580
"Iuml", // "&#207;" -- latin capital letter I with diaeresis,
581
// U+00CF ISOlat1 -->
582
"ETH", // "&#208;" -- latin capital letter ETH, U+00D0 ISOlat1 -->
583
"Ntilde", // "&#209;" -- latin capital letter N with tilde,
584
// U+00D1 ISOlat1 -->
585
"Ograve", // "&#210;" -- latin capital letter O with grave,
586
// U+00D2 ISOlat1 -->
587
"Oacute", // "&#211;" -- latin capital letter O with acute,
588
// U+00D3 ISOlat1 -->
589
"Ocirc", // "&#212;" -- latin capital letter O with circumflex,
590
// U+00D4 ISOlat1 -->
591
"Otilde", // "&#213;" -- latin capital letter O with tilde,
592
// U+00D5 ISOlat1 -->
593
"Ouml", // "&#214;" -- latin capital letter O with diaeresis,
594
// U+00D6 ISOlat1 -->
595
"times", // "&#215;" -- multiplication sign, U+00D7 ISOnum -->
596
"Oslash", // "&#216;" -- latin capital letter O with stroke
597
// = latin capital letter O slash,
598
// U+00D8 ISOlat1 -->
599
"Ugrave", // "&#217;" -- latin capital letter U with grave,
600
// U+00D9 ISOlat1 -->
601
"Uacute", // "&#218;" -- latin capital letter U with acute,
602
// U+00DA ISOlat1 -->
603
"Ucirc", // "&#219;" -- latin capital letter U with circumflex,
604
// U+00DB ISOlat1 -->
605
"Uuml", // "&#220;" -- latin capital letter U with diaeresis,
606
// U+00DC ISOlat1 -->
607
"Yacute", // "&#221;" -- latin capital letter Y with acute,
608
// U+00DD ISOlat1 -->
609
"THORN", // "&#222;" -- latin capital letter THORN,
610
// U+00DE ISOlat1 -->
611
"szlig", // "&#223;" -- latin small letter sharp s = ess-zed,
612
// U+00DF ISOlat1 -->
613
"agrave", // "&#224;" -- latin small letter a with grave
614
// = latin small letter a grave,
615
// U+00E0 ISOlat1 -->
616
"aacute", // "&#225;" -- latin small letter a with acute,
617
// U+00E1 ISOlat1 -->
618
"acirc", // "&#226;" -- latin small letter a with circumflex,
619
// U+00E2 ISOlat1 -->
620
"atilde", // "&#227;" -- latin small letter a with tilde,
621
// U+00E3 ISOlat1 -->
622
"auml", // "&#228;" -- latin small letter a with diaeresis,
623
// U+00E4 ISOlat1 -->
624
"aring", // "&#229;" -- latin small letter a with ring above
625
// = latin small letter a ring,
626
// U+00E5 ISOlat1 -->
627
"aelig", // "&#230;" -- latin small letter ae
628
// = latin small ligature ae, U+00E6 ISOlat1 -->
629
"ccedil", // "&#231;" -- latin small letter c with cedilla,
630
// U+00E7 ISOlat1 -->
631
"egrave", // "&#232;" -- latin small letter e with grave,
632
// U+00E8 ISOlat1 -->
633
"eacute", // "&#233;" -- latin small letter e with acute,
634
// U+00E9 ISOlat1 -->
635
"ecirc", // "&#234;" -- latin small letter e with circumflex,
636
// U+00EA ISOlat1 -->
637
"euml", // "&#235;" -- latin small letter e with diaeresis,
638
// U+00EB ISOlat1 -->
639
"igrave", // "&#236;" -- latin small letter i with grave,
640
// U+00EC ISOlat1 -->
641
"iacute", // "&#237;" -- latin small letter i with acute,
642
// U+00ED ISOlat1 -->
643
"icirc", // "&#238;" -- latin small letter i with circumflex,
644
// U+00EE ISOlat1 -->
645
"iuml", // "&#239;" -- latin small letter i with diaeresis,
646
// U+00EF ISOlat1 -->
647
"eth", // "&#240;" -- latin small letter eth, U+00F0 ISOlat1 -->
648
"ntilde", // "&#241;" -- latin small letter n with tilde,
649
// U+00F1 ISOlat1 -->
650
"ograve", // "&#242;" -- latin small letter o with grave,
651
// U+00F2 ISOlat1 -->
652
"oacute", // "&#243;" -- latin small letter o with acute,
653
// U+00F3 ISOlat1 -->
654
"ocirc", // "&#244;" -- latin small letter o with circumflex,
655
// U+00F4 ISOlat1 -->
656
"otilde", // "&#245;" -- latin small letter o with tilde,
657
// U+00F5 ISOlat1 -->
658
"ouml", // "&#246;" -- latin small letter o with diaeresis,
659
// U+00F6 ISOlat1 -->
660
"divide", // "&#247;" -- division sign, U+00F7 ISOnum -->
661
"oslash", // "&#248;" -- latin small letter o with stroke,
662
// = latin small letter o slash,
663
// U+00F8 ISOlat1 -->
664
"ugrave", // "&#249;" -- latin small letter u with grave,
665
// U+00F9 ISOlat1 -->
666
"uacute", // "&#250;" -- latin small letter u with acute,
667
// U+00FA ISOlat1 -->
668
"ucirc", // "&#251;" -- latin small letter u with circumflex,
669
// U+00FB ISOlat1 -->
670
"uuml", // "&#252;" -- latin small letter u with diaeresis,
671
// U+00FC ISOlat1 -->
672
"yacute", // "&#253;" -- latin small letter y with acute,
673
// U+00FD ISOlat1 -->
674
"thorn", // "&#254;" -- latin small letter thorn,
675
// U+00FE ISOlat1 -->
676
"yuml" // "&#255;" -- latin small letter y with diaeresis,
677
// U+00FF ISOlat1 -->
678
};
679
680
681 }
682
683 //
684
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
685
// you may not use this file except in compliance with the License. You may obtain a copy of the
686
// License at http://www.mozilla.org/MPL/
687
//
688
// Software distributed under the License is distributed on an "AS IS" basis,
689
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
690
// See the License for the specific language governing rights and limitations under the License.
691
//
692
// The Original Code is: all this file.
693
//
694
// The Initial Developer of the Original Code is
695
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
696
//
697
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
698
//
699
// Contributor(s): none.
700
//
701
Popular Tags