XHTMLTarget.java
001 /*
002  * [Adapted from BSD licence] Copyright (c) 2002 Terence Parr All rights
003  * reserved.
004  
005  * Redistribution and use in source and binary forms, with or without
006  * modification, are permitted provided that the following conditions are met:
007  * 1. Redistributions of source code must retain the above copyright notice,
008  * this list of conditions and the following disclaimer. 2. Redistributions in
009  * binary form must reproduce the above copyright notice, this list of
010  * conditions and the following disclaimer in the documentation and/or other
011  * materials provided with the distribution. 3. The name of the author may not
012  * be used to endorse or promote products derived from this software without
013  * specific prior written permission.
014  
015  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
016  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
017  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
018  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
019  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
020  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
021  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
022  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
023  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
024  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
025  */
026 package gate.wiki.antlr;
027 
028 import java.io.*;
029 import java.util.Vector;
030 import java.util.Hashtable;
031 import java.util.Date;
032 import java.util.regex.Pattern;
033 
034 /** XHTML target */
035 public class XHTMLTarget extends NOPTarget {
036   protected static boolean inContents = false;
037   
038   /**
039    * Collects the contents of the Table of Contents
040    */
041   protected static StringBuffer tableOfContents = new StringBuffer("<h2>Contents</h2>\n");
042   
043   /**
044    * Collects the output from the file so that the table of contents can be added
045    * before the rest of the output.
046    */
047   protected static StringBuffer fileContents = new StringBuffer("");
048   
049   /**
050    *  The depth of titles in an HTML file, for examp1e <h1> ... <h10>
051    */
052   public static int HEADING_DEPTH = 10;
053   
054   /**
055    *  Keeps track of the heading numbering
056    */
057   protected static int[] headingCount = new int[HEADING_DEPTH];
058 
059   /** Used by the c() method*/
060   protected static Hashtable HTML_map = new Hashtable();
061   static {
062     HTML_map.put("rarrow""&rarr;");
063     HTML_map.put("larrow""&larr;");
064     HTML_map.put("element""&#8712;");
065     HTML_map.put("psubset""&#8834;");
066     HTML_map.put("derives""&#8658;");
067     HTML_map.put("union""&#8746;");
068     HTML_map.put("alpha""&alpha;");
069     HTML_map.put("beta""&beta;");
070     HTML_map.put("gamma""&gamma;");
071     HTML_map.put("epsilon""&epsilon;");
072   }
073 
074 
075   public XHTMLTarget(){
076     this(new BufferedWriter(new OutputStreamWriter(System.out)));
077   }
078   public XHTMLTarget(Writer out){
079     this.out = out;
080   }
081   public String getTargetLanguage(){
082     return Tool.XHTML;
083   }
084   
085   
086   protected void write(String s){
087 
088     try{
089       if(inContents) {
090         fileContents.append(s);
091       }
092       else {
093         out.write(s);
094               //System.out.println("\n \n FILE CONTENTS:\n" + fileContents);
095       }
096       String c = extractLastCommand(s);
097       // System.out.println("extracted "+c);
098       if(c != null){
099         lastCommand = c;
100       }
101     }catch(IOException ioe){
102       System.err.println("Problem writing output");
103       ioe.printStackTrace(System.err);
104     }
105   }
106   
107   
108   /** insert head.html if found */
109   public void begin(){
110     writeln("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
111     writeln("<!-- AUTOGENERATED FILE: ALL EDITS WILL BE LOST!!! -->");
112     writeln("<!DOCTYPE html\n" +
113             "  PUBLIC \"//W3C//DTD XHTML 1.0 Transitional//EN\"\n" +
114             "  \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
115     writeln("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
116     writeln("<head>");
117   }
118   /** insert tail.html if found */
119   public void end(){
120     writeln("</body>");
121     writeln("</html>");
122     if(inContents){
123       inContents = false;
124       write(tableOfContents.toString());
125       write(fileContents.toString());
126       resetContents();
127     }
128     try{
129       out.flush();
130     }catch(IOException ioe){
131       System.err.println("Problem writing HTML output");
132       ioe.printStackTrace(System.err);
133     }
134   }
135   protected String extractLastCommand(String text){
136     if(text == null){ return null}
137     int i = text.lastIndexOf("<");
138     if(i < 0){ return null}
139     int begin = i;
140     i++;
141     int end = 0;
142     while(i < text.length() && text.charAt(i!= '>'){
143       i++;
144     }
145     if(i >= text.length()){ return null// <... not terminated
146     }
147     end = i;
148     return text.substring(begin, end);
149   }
150   public void text(String t){
151     write(angleBracketsEscape(t));
152   }
153   public void bold(String t){
154     write("<strong>" + angleBracketsEscape(t"</strong>");
155   }
156   public void italic(String t){
157     write("<em>" + angleBracketsEscape(t"</em>");
158   }
159   public void tt(String t){
160     write("<tt>" + angleBracketsEscape(t"</tt>");
161   }
162   public void beginListItem(int level){
163     write("<li>\n");
164   }
165   public void endListItem(int level){
166     writeln("</li>");
167   }
168   public void begin_ul(int level){
169     write("<ul>\n");
170   }
171   public void end_ul(int level){
172     write("</ul>\n");
173   }
174   public void begin_ol(int level){
175     write("<ol>\n");
176   }
177   public void end_ol(int level){
178     write("</ol>\n");
179   }
180   public void paragraph(){
181     write("\n<p/>\n");
182   }
183   public void linebreak(){
184     write("<br/>\n");
185   }
186   public void blankline(){
187     write("<br/>\n<br/>\n");
188   }
189   public void code(String c){
190     write("\n<pre>");
191     write(angleBracketsEscape(c));
192     write("</pre>\n\n");
193   }
194   public void verbatim(String rawOutput){
195     write("<![CDATA["+ rawOutput + "]]>");
196   }
197   public void blockquote(String q){
198     write("<blockquote>\n");
199     write("" + angleBracketsEscape(q"");
200     write("\n</blockquote>\n\n");
201   }
202   public void link(String url, String title){
203     if(title == null){
204       title = url;
205     }
206     title = angleBracketsEscape(title);
207     write("<a href=\"" + url + "\">" + title + "</a>");
208   }
209   public void anchor(String name){
210     write("<a name=\"" + name + "\"></a>");
211   }
212   public void title(String title){
213     title = angleBracketsEscape(title);
214     writeln("<title>" + strip(title"</title>");
215     writeln("<style type=\"text/css\">");
216     writeln("<!--");
217     writeln("html, body {");
218     writeln("  background: #fff;");
219     writeln("  color: #000;");
220     writeln("  font-family: sans-serif;");
221     writeln("}");
222     writeln("h1,h2,h3,h4,h5,p,ul,ol { font-family: sans-serif; }");
223     writeln("pre { font-family: monospace; }");
224     writeln("h3.navhead {");
225     writeln("  font-size: 100%;");
226     writeln("}");
227     writeln("div.banner {");
228     writeln("  border: none;");
229     writeln("  margin-right: 0px;");
230     writeln("  margin-left: 0px;");
231     writeln("  padding: 0.09em;");
232     writeln("  text-align: center;");
233     writeln("  font-weight: bold; ");
234     writeln("}");
235     writeln("div.banner a:link, div.banner {");
236     writeln("  background: #A0D0F0;");
237     writeln("  color: #000000;");
238     writeln("}");
239     writeln("div.banner a:active {");
240     writeln("  background: #000000;");
241     writeln("  color: #FFFFFF;");
242     writeln("}");
243     writeln("div.banner a:hover {");
244     writeln("  background: #000000;");
245     writeln("  color: #FFFFFF;");
246     writeln("-->");
247     writeln("</style>");
248     writeln("</head>");
249     writeln("<body bgcolor=\"#FFFFFF\" text=\"#000000\">");
250     writeln("<h1>" + title + "</h1>");
251     headingCount[11;
252   }
253   public void beginSection(String title, int level){
254     String hC = "";
255     String indent = "";
256     ++ level;
257     headingCount[level+= 1;
258     // headingCount[0] empty for simlicity reasons
259     // headingLevel[1] for the title
260     for(int i = 2; i < HEADING_DEPTH; ++i) {
261       if(i <= level) {
262         hC += Integer.toString(headingCount[i]) ".";
263         indent += "&#160;&#160;&#160;&#160;";
264       }
265       else {  
266         headingCount[i0;
267       }  
268     }
269     if(inContents) {
270       tableOfContents.append(indent);
271       tableOfContents.append("<a href=\"#"+hC+"\">"+ hC + " "+ title +"</a><br>");
272       write("<a name=\""+hC+"\"><h" (level">");
273       title = angleBracketsEscape(title);
274       write(hC + " "+title);
275       write("</h" (level"></a>\n");
276     }
277     else {
278       write("<h" (level">");
279       title = angleBracketsEscape(title);
280       write(hC + " "+title);
281       write("</h" (level">\n");
282     }
283     
284   }
285   public void begin_table(){
286     write("\n<table cellspacing=\"0\" border=\"1\">\n");
287     write("<tr><td>");
288   }
289   public void end_table(){
290     write("</td></tr>\n");
291     write("</table>\n");
292   }
293   public void col(){
294     write("</td><td>");
295   }
296   public void row(){
297     write("</td>\n</tr>\n<tr>\n<td>");
298   }
299   protected String strip(String s) {
300     s = s.replaceAll("</.*>""")
301     s = s.replaceAll("<.*>""");
302     return s;
303   }
304   protected String angleBracketsEscape(String q){
305             q = q.replaceAll("<","&lt;");
306             q = q.replaceAll(">","&gt;");
307     return q;
308   }
309   public void hr(){
310     write("\n<hr/>");
311   }
312 //public void beginTitle(int level){
313 //write("<h" + (level + 1) + ">");
314 //}
315 //public void endTitle(String title, int level){
316 //title = angleBracketsEscape(title);
317 //write(title);
318 //write("</h" + (level + 1) + ">\n");
319 //}
320   public String beginEM() {
321     return("<em>");
322   }
323   public String endEM() {
324     return("</em>");
325   }
326   public String beginTT() {
327     return("<tt>");
328   }
329   public String endTT() {
330     return("</tt>");
331   }
332   public String beginBF() {
333     return("<b>");
334   }
335   public String endBF() {
336     return("</b>");
337   }
338   public void longdash() {
339     write("&#151;");
340   }
341   public void contents() {
342     inContents = true;
343   }
344 
345   /** Former plugins were turned into methods */
346 
347 
348   public void image(YAMContext context, Vector args) {
349     // The call to super is necessary beacause the test of the arguments is done there
350     super.image(context, args);
351 
352     String imageName = (Stringargs.elementAt(0);
353     String width = "";
354     String height = "";
355 
356     if args.size()>) {
357       width = (String)args.elementAt(1);
358       if args.size()>) {
359         height = (String)args.elementAt(2);
360       }
361     }// fi
362     if(width!= "") {
363       String [] w = Pattern.compile("([a-z]+)").split(width, 3);
364       width = w[0];
365       //  the 5 compensates for the difference in sizes between
366       //  latex cm or pt and pixels
367       //  if the input is 10cm then the image will be 510
368       //  this is a temporary solution it should account for
369       //  type of measurment that is passed in as well
370       width = "width = \"" + width + "%\"";
371     }
372     if(height!= "") {
373       String [] w = Pattern.compile("([a-z]+)").split(height, 3);
374       height = w[0];
375       height = "height = \"" + height + "%\"";
376     }
377     write("<img src=\""+imageName+"\" "+ width + " "+ height + ">");
378 
379   }// End of image()
380 
381 
382   public void cite(YAMContext context, Vector args) {
383     // The call to super is necessary beacause the test of the arguments is done there
384     super.cite(context, args);
385 
386     StringBuffer result = new StringBuffer("\n");
387     for(int i = 0; i < args.size(); i++){
388       result.append("<a href=http://gate.ac.uk/sale/bib/main.html#X");
389       result.append(args.get(i));
390       result.append(">");
391       result.append(args.get(i));
392       result.append("</a>");
393       // Separates multiple citations with comma.
394       // The following code doesn't append a comma for the last citation
395       if(i < (args.size() 1)) result.append(", ");
396     }
397 
398     write(result.toString());
399   }// End of cite()
400 
401   public void box(YAMContext context, Vector args) {
402     // The call to super is necessary beacause the test of the arguments is done there
403     super.box(context, args);
404     String tml = (String)args.elementAt(0);
405     write("\n<table border=\"1\"><tr><td>"+tml.toString()+"</td></tr></table>\n\n");
406   }// End of box()
407 
408   public void c(YAMContext context, Vector args) {
409     // The call to super is necessary beacause the test of the arguments is done there
410     super.c(context, args);
411 
412     String charName = (String)args.elementAt(0);
413     String html = (String)HTML_map.get(charName);
414     if html==null ) {
415       write(charName);
416     }
417     write("<<"+html+">>");
418   }// End of c()
419 
420   public void date(YAMContext context, Vector args) {
421     // The implementation in base class is common for all languages
422     super.date(context, args);
423   }// End of date()
424 
425   public void delete(YAMContext context, Vector args) {
426     // The implementation in base class is common for all languages
427     super.delete(context, args);
428   }// End of delete()
429 
430   public void eps(YAMContext context, Vector args) {
431     // The call to super is necessary beacause the test of the arguments is done there
432     super.eps(context, args);
433 
434     String imageName = (String)args.elementAt(0);
435     String scalex = "1.0";
436     String scaley = "1.0";
437     if args.size()>) {
438         if args.size()!=) {
439             System.err.println("Missing EPS arg(s); line "+context.getLine());
440             return;
441         }
442         scalex = (String)args.elementAt(1);
443         scaley = (String)args.elementAt(2);
444     }
445 
446     write("\n[Image "+imageName+"]\n");
447 
448   }// End of eps()
449 
450 
451   public void footnote(YAMContext context, Vector args) {
452     // The call to super is necessary beacause the test of the arguments is done there
453     super.footnote(context, args);
454 
455     String tml = (String)args.elementAt(0);
456     String ret ="";
457     ret = "<em>"+tml.toString()+"</em>";
458 
459     write(ret);
460   }// End of footnote()
461 
462 
463   public void notes(YAMContext context, Vector args) {
464     // The call to super is necessary beacause the test of the arguments is done there
465     super.notes(context, args);
466 
467     String notes = (Stringargs.elementAt(0);
468     write("<!-- "+notes+" -->\n");
469   }// End of notes()
470 
471   public void syndiag(YAMContext context, Vector args) {
472     super.syndiag(context, args);
473 
474     String grammarSpec = (String)args.elementAt(0);
475     // just return grammar spec for anything but lout for now
476     write("\n<<\n"+grammarSpec+">>\n");
477 
478   }// End of syndiag()
479 
480   public void tree(YAMContext context, Vector args) {
481     // The call to super is necessary beacause the test of the arguments is done there
482     super.tree(context, args);
483 
484     String treeSpec = (String)args.elementAt(0);
485     // just return tree spec for anything but lout for now
486     write(treeSpec);
487 
488   }// End of tree()
489 
490 
491   /**
492    * This function NEEDS to be here. If Tool.run is invoked from
493    * the same class more than once in a row all the static variables 
494    * retain their values, so they need to be reset
495    *
496    */
497   protected void resetContents(){
498     fileContents = null;
499     fileContents = new StringBuffer("");
500     headingCount = null;
501     headingCount = new int[HEADING_DEPTH];
502     tableOfContents = null;
503     tableOfContents = new StringBuffer("<h2>Contents</h2>\n");
504 
505   }// End of resetContents()
506 
507 }//End of HTMLTarget