HTMLTarget.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 
035 public class HTMLTarget 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 HTMLTarget(){
076     this(new BufferedWriter(new OutputStreamWriter(System.out)));
077   }
078   public HTMLTarget(Writer out){
079     this.out = out;
080   }
081   public String getTargetLanguage(){
082     return Tool.HTML;
083   }
084   
085   
086   protected void write(String s){
087     try{
088       if(inContents) {
089         fileContents.append(s);
090       }
091       else {
092         out.write(s);
093               //System.out.println("\n \n FILE CONTENTS:\n" + fileContents);
094       }
095       String c = extractLastCommand(s);
096       // System.out.println("extracted "+c);
097       if(c != null){
098         lastCommand = c;
099       }
100     }catch(IOException ioe){
101       System.err.println("Problem writing output");
102       ioe.printStackTrace(System.err);
103     }
104   }
105   
106   
107   /** insert head.html if found */
108   public void begin(){
109     writeln("<!-- AUTOGENERATED FILE: ALL EDITS WILL BE LOST!!! -->");
110     writeln("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
111     writeln("<html>");
112     writeln("<head>");
113     writeln("<meta charset=\"UTF-8\">");
114   }
115   /** insert tail.html if found */
116   public void end(){
117     writeln("</body>");
118     writeln("</html>");
119     if(inContents){
120       inContents = false;
121       write(tableOfContents.toString());
122       write(fileContents.toString());
123     }
124     resetContents();
125     try{
126       out.flush();
127     }catch(IOException ioe){
128       System.err.println("Problem writing HTML output");
129       ioe.printStackTrace(System.err);
130     }
131   }
132   protected String extractLastCommand(String text){
133     if(text == null){ return null}
134     int i = text.lastIndexOf("<");
135     if(i < 0){ return null}
136     int begin = i;
137     i++;
138     int end = 0;
139     while(i < text.length() && text.charAt(i!= '>'){
140       i++;
141     }
142     if(i >= text.length()){ return null// <... not terminated
143     }
144     end = i;
145     return text.substring(begin, end);
146   }
147   public void text(String t){
148     write(angleBracketsEscape(t));
149   }
150   public void bold(String t){
151     write("<b>" + angleBracketsEscape(t"</b>");
152   }
153   public void italic(String t){
154     write("<em>" + angleBracketsEscape(t"</em>");
155   }
156   public void tt(String t){
157     write("<tt>" + angleBracketsEscape(t"</tt>");
158   }
159   public void beginListItem(int level){
160     write("<li>\n");
161   }
162   public void endListItem(int level){
163     writeln("</li>");
164   }
165   public void begin_ul(int level){
166     write("<ul>\n");
167   }
168   public void end_ul(int level){
169     write("</ul>\n");
170   }
171   public void begin_ol(int level){
172     write("<ol>\n");
173   }
174   public void end_ol(int level){
175     write("</ol>\n");
176   }
177   public void paragraph(){
178     write("\n<p>\n");
179   }
180   public void linebreak(){
181     write("<br>\n");
182   }
183   public void blankline(){
184     write("<br>\n<br>\n");
185   }
186   public void code(String c){
187     write("\n<pre>");
188     write(angleBracketsEscape(c));
189     write("</pre>\n\n");
190   }
191   public void verbatim(String rawOutput){
192     write(rawOutput);
193   }
194   public void blockquote(String q){
195     write("<blockquote>\n");
196     write("" + angleBracketsEscape(q"");
197     write("\n</blockquote>\n\n");
198   }
199   public void link(String url, String title){
200     if(title == null){
201       title = url;
202     }
203     title = angleBracketsEscape(title);
204     write("<a href=\"" + url + "\">" + title + "</a>");
205   }
206   public void anchor(String name){
207     write("<a name=" + name + "></a>");
208   }
209   public void title(String title){
210     title = angleBracketsEscape(title);
211     writeln("<title>" + strip(title"</title>");
212     writeln("<style type=\"text/css\">");
213     writeln("<!--");
214     writeln("html, body {");
215     writeln("  background: #fff;");
216     writeln("  color: #000;");
217     writeln("  font-family: sans-serif;");
218     writeln("}");
219     writeln("h1,h2,h3,h4,h5,p,ul,ol { font-family: sans-serif; }");
220     writeln("pre { font-family: monospace; }");
221     writeln("h3.navhead {");
222     writeln("  font-size: 100%;");
223     writeln("}");
224     writeln("div.banner {");
225     writeln("  border: none;");
226     writeln("  margin-right: 0px;");
227     writeln("  margin-left: 0px;");
228     writeln("  padding: 0.09em;");
229     writeln("  text-align: center;");
230     writeln("  font-weight: bold; ");
231     writeln("}");
232     writeln("div.banner a:link, div.banner {");
233     writeln("  background: #A0D0F0;");
234     writeln("  color: #000000;");
235     writeln("}");
236     writeln("div.banner a:active {");
237     writeln("  background: #000000;");
238     writeln("  color: #FFFFFF;");
239     writeln("}");
240     writeln("div.banner a:hover {");
241     writeln("  background: #000000;");
242     writeln("  color: #FFFFFF;");
243     writeln("-->");
244     writeln("</style>");
245     writeln("</head>");
246     writeln("<body bgcolor=\"#FFFFFF\" text=\"#000000\">");
247     writeln("<h1>" + title + "</h1>");
248     headingCount[11;
249   }
250   public void beginSection(String title, int level){
251     String hC = "";
252     String indent = "";
253     ++ level;
254     headingCount[level+= 1;
255     // headingCount[0] empty for simlicity reasons
256     // headingLevel[1] for the title
257     for(int i = 2; i < HEADING_DEPTH; ++i) {
258       if(i <= level) {
259         hC += Integer.toString(headingCount[i]) ".";
260         indent += "&nbsp;&nbsp;&nbsp;&nbsp;";
261       }
262       else {  
263         headingCount[i0;
264       }  
265     }
266     if(inContents) {
267       tableOfContents.append(indent);
268       tableOfContents.append("<a href=\"#"+hC+"\">"+ hC + " "+ title +"</a><br>");
269       write("<a name=\""+hC+"\"><h" (level">");
270       title = angleBracketsEscape(title);
271       write(hC + " "+title);
272       write("</h" (level"></a>\n");
273     }
274     else {
275       write("<h" (level">");
276       title = angleBracketsEscape(title);
277       write(hC + " "+title);
278       write("</h" (level">\n");
279     }
280     
281   }
282   public void begin_table(){
283     write("\n<table cellspacing=\"0\" border=\"1\">\n");
284     write("<tr><td>");
285   }
286   public void end_table(){
287     write("</td></tr>\n");
288     write("</table>\n");
289   }
290   public void col(){
291     write("</td><td>");
292   }
293   public void row(){
294     write("</td>\n</tr>\n<tr>\n<td>");
295   }
296   protected String strip(String s) {
297     s = s.replaceAll("</.*>""")
298     s = s.replaceAll("<.*>""");
299     return s;
300   }
301   protected String angleBracketsEscape(String q){
302     //        q = q.replaceAll("<","&lt;");
303     //        q = q.replaceAll(">","&gt;");
304     return q;
305   }
306   public void hr(){
307     write("\n<hr>");
308   }
309 //public void beginTitle(int level){
310 //write("<h" + (level + 1) + ">");
311 //}
312 //public void endTitle(String title, int level){
313 //title = angleBracketsEscape(title);
314 //write(title);
315 //write("</h" + (level + 1) + ">\n");
316 //}
317   public String beginEM() {
318     return("<em>");
319   }
320   public String endEM() {
321     return("</em>");
322   }
323   public String beginTT() {
324     return("<tt>");
325   }
326   public String endTT() {
327     return("</tt>");
328   }
329   public String beginBF() {
330     return("<b>");
331   }
332   public String endBF() {
333     return("</b>");
334   }
335   public void longdash() {
336     write("&#151;");
337   }
338   public void contents() {
339     inContents = true;
340   }
341 
342   /** Former plugins were turned into methods */
343 
344 
345   public void image(YAMContext context, Vector args) {
346     // The call to super is necessary beacause the test of the arguments is done there
347     super.image(context, args);
348 
349     String imageName = (Stringargs.elementAt(0);
350     String width = "";
351     String height = "";
352 
353     if args.size()>) {
354       width = (String)args.elementAt(1);
355       if args.size()>) {
356         height = (String)args.elementAt(2);
357       }
358     }// fi
359     if(width!= "") {
360       String [] w = Pattern.compile("([a-z]+)").split(width, 3);
361       width = w[0];
362       //  the 5 compensates for the difference in sizes between
363       //  latex cm or pt and pixels
364       //  if the input is 10cm then the image will be 510
365       //  this is a temporary solution it should account for
366       //  type of measurment that is passed in as well
367       width = "width = \"" + width + "%\"";
368     }
369     if(height!= "") {
370       String [] w = Pattern.compile("([a-z]+)").split(height, 3);
371       height = w[0];
372       height = "height = \"" + height + "%\"";
373     }
374     write(
375       "<img align=\"center\" src=\""+imageName+"\" "+ width + " "+ height + ">"
376     );
377 
378   }// End of image()
379 
380 
381   public void cite(YAMContext context, Vector args) {
382     // The call to super is necessary beacause the test of the arguments is done there
383     super.cite(context, args);
384 
385     StringBuffer result = new StringBuffer("\n");
386     for(int i = 0; i < args.size(); i++){
387       result.append("<a href=http://gate.ac.uk/sale/bib/main.html#X");
388       result.append(args.get(i));
389       result.append(">");
390       result.append(args.get(i));
391       result.append("</a>");
392       // Separates multiple citations with comma.
393       // The following code doesn't append a comma for the last citation
394       if(i < (args.size() 1)) result.append(", ");
395     }
396 
397     write(result.toString());
398   }// End of cite()
399 
400   public void box(YAMContext context, Vector args) {
401     // The call to super is necessary beacause the test of the arguments is done there
402     super.box(context, args);
403     String tml = (String)args.elementAt(0);
404     write("\n<table border=1><tr><td>"+tml.toString()+"</td></tr></table>\n\n");
405   }// End of box()
406 
407   public void c(YAMContext context, Vector args) {
408     // The call to super is necessary beacause the test of the arguments is done there
409     super.c(context, args);
410 
411     String charName = (String)args.elementAt(0);
412     String html = (String)HTML_map.get(charName);
413     if html==null ) {
414       write(charName);
415     }
416     write("<<"+html+">>");
417   }// End of c()
418 
419   public void date(YAMContext context, Vector args) {
420     // The implementation in base class is common for all languages
421     super.date(context, args);
422   }// End of date()
423 
424   public void delete(YAMContext context, Vector args) {
425     // The implementation in base class is common for all languages
426     super.delete(context, args);
427   }// End of delete()
428 
429   public void eps(YAMContext context, Vector args) {
430     // The call to super is necessary beacause the test of the arguments is done there
431     super.eps(context, args);
432 
433     String imageName = (String)args.elementAt(0);
434     String scalex = "1.0";
435     String scaley = "1.0";
436     if args.size()>) {
437         if args.size()!=) {
438             System.err.println("Missing EPS arg(s); line "+context.getLine());
439             return;
440         }
441         scalex = (String)args.elementAt(1);
442         scaley = (String)args.elementAt(2);
443     }
444 
445     write("\n[Image "+imageName+"]\n");
446 
447   }// End of eps()
448 
449 
450   public void footnote(YAMContext context, Vector args) {
451     // The call to super is necessary beacause the test of the arguments is done there
452     super.footnote(context, args);
453 
454     String tml = (String)args.elementAt(0);
455     String ret ="";
456     ret = "<em>"+tml.toString()+"</em>";
457 
458     write(ret);
459   }// End of footnote()
460 
461 
462   public void notes(YAMContext context, Vector args) {
463     // The call to super is necessary beacause the test of the arguments is done there
464     super.notes(context, args);
465 
466     String notes = (Stringargs.elementAt(0);
467     write("<!-- "+notes+" -->\n");
468   }// End of notes()
469 
470   public void syndiag(YAMContext context, Vector args) {
471     super.syndiag(context, args);
472 
473     String grammarSpec = (String)args.elementAt(0);
474     // just return grammar spec for anything but lout for now
475     write("\n<<\n"+grammarSpec+">>\n");
476 
477   }// End of syndiag()
478 
479   public void tree(YAMContext context, Vector args) {
480     // The call to super is necessary beacause the test of the arguments is done there
481     super.tree(context, args);
482 
483     String treeSpec = (String)args.elementAt(0);
484     // just return tree spec for anything but lout for now
485     write(treeSpec);
486 
487   }// End of tree()
488 
489 
490   /**
491    * This function NEEDS to be here. If Tool.run is invoked from
492    * the same class more than once in a row all the static variables 
493    * retain their values, so they need to be reset
494    *
495    */
496   protected void resetContents(){
497     fileContents = null;
498     fileContents = new StringBuffer("");
499     headingCount = null;
500     headingCount = new int[HEADING_DEPTH];
501     tableOfContents = null;
502     tableOfContents = new StringBuffer("<h2>Contents</h2>\n");
503 
504   }// End of resetContents()
505 
506 }//End of HTMLTarget