summaryrefslogblamecommitdiff
path: root/sources/ch/epfl/lamp/util/HTMLPrinter.java
blob: 04662bb9101d9c3bc4fa8cce8175ef4a5bb7410a (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                                                                          
                      


                                  




                                                      


                          

                                                                
                                                                              








                                                                              







                                      

                                                                              
 

                                                      



                                                                              






                              
                                                                                        

                                                     
                                             

     






                                                                                     


                                                                      
                                                                                         

     





                                                                              
                                                     
                                           




                                                                              


                                           



                                         


                                    



                              
                                                                              























                                                                              

                                  


                                              























                                                                              
                                                                     





































































                                                                      
                                                                        















                                                                 





                                                                      


                                                              
                                  

     






                                                                                
       
                                                                                    

                                
                                  

     


                                                        








                                                  






                                                                   
                                                                        







                                                                 





                                                                 
                                                               
                                                                             
                    
                                

     






                                                                               
                                                                              


                                                 
                    
                                

     





                                                                 
                                                                 
                                                                             
                    
                                

     




                                                                    
                                                 
                                     

     





                                                                                        
                                                                    



                                                                  

     




                                                                             



                                                    


                    




















                                                                              



                                                          




                                                                            






                                                                              






























































                                                                       
                                                                      















                                                                 





                                                                              


                                                            
                                


                                                                                   
                                                                                  















                                                             
                                                                             
                    
                              



                                                                            


                                                 
                    
                              



                                                               
                                                                               
                    
                              

     

                                             
      

                  
                                               
                                   

     

                                                                 
      


                   
                                                                  


                                                                                              

                                                      
      
                  




                                                  


                    

                                               
      

                                                             








                                         


                                           
                                     
                               

     

                                                                              
      

                   

                                                         




                                                                              


                                                         





                                                                              

                                                    

                                    
                                                        
                                                                                    



                                   
                                                                

                       
       





                                                                                    

     

                                     
      
                       
       
                                                            
                                       
                                                           


                                                                                     
                                           

                                                                  


         

                                                     
      









                                                             

     

                                                      
      


                         
       
                                                                                               

                                     
                                   
                                    
                                 
                                 
                                            

     

                                  
      


                               
       

                                                                                            

     

                                  
      


                               

                                                                         

     

                                                     
      

                               

                                                       

     

                                                 





                                     
                                                  









                                                                              

                             


                                
       

                                                    
               


                                             
       
                                                              
                                                                        
      




                            
















                                                                                                          
       

                                 



                     




                                                                                  

                 





                                                    
 
 
/*     ____ ____  ____ ____  ______                                     *\
**    / __// __ \/ __// __ \/ ____/    SOcos COmpiles Scala             **
**  __\_ \/ /_/ / /__/ /_/ /\_ \       (c) 2002, LAMP/EPFL              **
** /_____/\____/\___/\____/____/                                        **
\*                                                                      */

// $Id$

package ch.epfl.lamp.util;

import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * This class provides methods to print HTML document.
 *
 *  @author     Stephane Micheloud
 *  @version    1.1
 */
public class HTMLPrinter {

    public static final String DEFAULT_STYLESHEET = "style.css";

    //########################################################################
    // Private Constants

    /*
     * The characters which must be HTML encoded
     */
    private static final Character LT = new Character('<');
    private static final Character GT = new Character('>');

    //########################################################################
    // Private Fields

    /** The underlying code printer */
    private final CodePrinter printer;

    /** The document title */
    private final String title;

    //########################################################################
    // Protected Fields

    /** The document representation */
    protected final HTMLRepresentation representation;

    //########################################################################
    // Public Constructors

    /**
     * Creates a new instance.
     *
     * @param writer
     * @param title
     * @param representation
     */
    public HTMLPrinter(Writer writer, String title, HTMLRepresentation representation) {
        this.printer = new CodePrinter(writer, "  ");
        this.title = title;
        this.representation = representation;
    }

    /**
     * Creates a new instance with "HTML 4.01 Transitional" as default document type.
     *
     * @param writer
     * @param title
     * @param encoding
     */
    public HTMLPrinter(Writer writer, String title, String encoding) {
        this.printer = new CodePrinter(writer, "  ");
        this.title = title;
        this.representation = new HTMLRepresentation("HTML 4.01 Transitional", encoding);
    }

    /**
     * Creates a new instance with "iso-8859-1" as default character encoding.
     *
     * @param writer
     * @param title
     */
    public HTMLPrinter(Writer writer, String title) {
        this(writer, title,  "iso-8859-1");
    }

    //########################################################################
    // Public Methods - Getting & Setting

    /**
     * Returns the underlying code printer.
     */
    public CodePrinter getCodePrinter() {
        return printer;
    }

    /**
     * Returns the underlying title.
     */
    public String getTitle() {
        return title;
    }

    //########################################################################
    // Public Methods - Character encoding

    /**
     * Encodes the special character <code>ch</code> to its
     * corresponding HTML encoding.
     *
     * @param ch
     */
    public static String encode(Character ch) {
	if      (LT.compareTo(ch) == 0) return "&lt;";
        else if (GT.compareTo(ch) == 0) return "&gt;";
        else return ch.toString();
    }

    /**
     * Encodes the special characters to their corresponding HTML encodings.
     *
     * @param text
     */
    public static String encode(String text) {
	return text;
    }

    //########################################################################
    // Public Methods - Formatting

    /**
     * Increases the indentation level by one.
     */
    public HTMLPrinter indent() {
        printer.indent();
        return this;
    }

    /** Decreases the indentation level by one. */
    public HTMLPrinter undent() {
        printer.undent();
        return this;
    }

    /** Inserts a new line. */
    public HTMLPrinter line() {
        printer.line();
        return this;
    }

    /** Inserts a white space. */
    public HTMLPrinter space() {
        printer.space();
        return this;
    }

    //########################################################################
    // Public Methods - Printing simple values followed by a new line

    /** Prints a new line. */
    public HTMLPrinter println() {
        printer.println();
        return this;
    }

    /** Prints the boolean value followed by a new line. */
    public HTMLPrinter println(boolean value) {
        printer.println(value);
        return this;
    }

    /** Prints the byte value followed by a new line. */
    public HTMLPrinter println(byte value) {
        printer.println(value);
        return this;
    }

    /** Prints the short value followed by a new line. */
    public HTMLPrinter println(short value) {
        printer.println(value);
        return this;
    }

    /** Prints the char value followed by a new line. */
    public HTMLPrinter println(char value) {
        printer.println(value);
        return this;
    }

    /** Prints the int value followed by a new line. */
    public HTMLPrinter println(int value) {
        printer.println(value);
        return this;
    }

    /** Prints the long value followed by a new line. */
    public HTMLPrinter println(long value) {
        printer.println(value);
        return this;
    }

    /** Prints the float value followed by a new line. */
    public HTMLPrinter println(float value) {
        printer.println(value);
        return this;
    }

    /** Prints the double value followed by a new line. */
    public HTMLPrinter println(double value) {
        printer.println(value);
        return this;
    }

    /** Prints the string followed by a new line. */
    public HTMLPrinter println(String value) {
        printer.println(value);
        return this;
    }

    /** Prints the opening HTML tag followed by a new line. */
    public HTMLPrinter printlnOTag(String label) {
        printer.print("<");
        printer.print(label);
        printer.println(">");
        return this;
    }

    /** Prints the HTML tag with attributes followed by a new line. */
    public HTMLPrinter printlnOTag(String label, XMLAttribute[] attrs) {
        printer.print("<");
        printer.print(label);
        printer.print(" ");
        printer.print(StringOf.object.array(attrs, "", " ", ""));
        printer.println(">");
        return this;
    }

    /** Prints the closing HTML tag followed by a new line. */
    public HTMLPrinter printlnCTag(String label) {
        printer.print("</");
        printer.print(label);
        printer.println(">");
        return this;
    }

    /**
     * Prints HTML tag with label and contents followed by a new line.
     *
     * @param label
     * @param text
     */
    public HTMLPrinter printlnTag(String label, String text) {
        printOTag(label);
        print(text);
        return printlnCTag(label);
    }

    /**
     * Prints the HTML tag <code>label</code> with attributes <code>attrs</code>
     * and contents <code>text</code> followed by a new line.
     *
     * @param label
     * @param attrs
     * @param text
     */
    public HTMLPrinter printlnTag(String label, XMLAttribute[] attrs, String text) {
        printOTag(label, attrs);
        print(text);
        return printlnCTag(label);
    }

    /**
     * Prints the short HTML tag followed by a new line.
     *
     *  @param label
     */
    public HTMLPrinter printlnSTag(String label) {
        printer.print("<");
        printer.print(label);
        printer.println("/>");
        return this;
    }

    /**
     * Prints the short HTML tag with attributes <code>attrs</code>
     * followed by a new line.
     *
     * @param label
     * @param attrs
     */
    public HTMLPrinter printlnSTag(String label, XMLAttribute[] attrs) {
        printer.print("<");
        printer.print(label);
        printer.print(" ");
        printer.print(StringOf.object.array(attrs, "", " ", ""));
        printer.println("/>");
        return this;
    }

    /**
     * Prints <A HREF=link> text </a> tag followed by a new line.
     *
     * @param dest
     * @param text
     */
    public HTMLPrinter printlnAhref(String dest, String text) {
	printOTag("a", new XMLAttribute[]{ new XMLAttribute("href", dest) });
        print(text);
        return printlnCTag("a");
    }

    /**
     * Prints <A HREF=dest TARGET=target> text </a> tag followed by a new line.
     *
     * @param dest
     * @param target
     * @param text
     */
    public HTMLPrinter printlnAhref(String dest, String target, String text) {
        printOTag("a", new XMLAttribute[]{
            new XMLAttribute("href", dest),
            new XMLAttribute("target", target)});
        print(text);
        return printlnCTag("a");
    }

    /**
     * Prints <A NAME=name> text </a> tag followed by a new line.
     *
     * @param anchor
     * @param text
     */
    public HTMLPrinter printlnAname(String anchor, String text) {
        printOTag("a", new XMLAttribute[]{new XMLAttribute("name", anchor)});
        print(text);
        return printlnCTag("a");
    }

    /**
     * Prints text <code>text</code> in bold followed by a new line.
     *
     * @param text
     */
    public HTMLPrinter printlnBold(String text) {
        return printlnTag("b", text);
    }

    /**
     * Prints text <code>text</code> in color <code>color</code> followed by a new line.
     *
     * @param color
     * @param text
     */
    public HTMLPrinter printlnFontColor(String color, String text) {
	return printlnTag(
            "font",
            new XMLAttribute[]{ new XMLAttribute("color", color)},
            text);
    }

    /**
     * Prints comment with contents <code>text</code> followed by a new line.
     *
     * @param text
     */
    public HTMLPrinter printlnComment(String text) {
	printer.print("<!--");
        printer.print(text);
        printer.println("-->");
        return this;
    }

    /**
     * Prints an horizontal line separator followed by a new line.
     */
    public HTMLPrinter printlnHLine() {
        return printlnOTag("hr");
    }

    /**
     * Prints an horizontal line separator with attributes <code>attrs</code>.
     *
     * @param attrs
     */
    public HTMLPrinter printlnHLine(XMLAttribute[] attrs) {
        return printlnOTag("hr", attrs);
    }

    /**
     * Prints the <meta> tag with attributes 'attrs' followed by a new line.
     *
     * @param attrs
     */
    public HTMLPrinter printlnMeta(XMLAttribute[] attrs) {
	return printlnOTag("meta", attrs);
    }

    /**
     * Prints the <link> tag with attributes 'attrs' followed by a new line.
     *
     * @param attrs
     */
    public HTMLPrinter printlnLink(XMLAttribute[] attrs) {
	return printlnOTag("link", attrs);
    }

    //########################################################################
    // Public Methods - Printing simple values

    /** Prints the boolean value. */
    public HTMLPrinter print(boolean value) {
        printer.print(value);
        return this;
    }

    /** Prints the byte value. */
    public HTMLPrinter print(byte value) {
        printer.print(value);
        return this;
    }

    /** Prints the short value. */
    public HTMLPrinter print(short value) {
        printer.print(value);
        return this;
    }

    /** Prints the char value. */
    public HTMLPrinter print(char value) {
        printer.print(value);
        return this;
    }

    /** Prints the int value. */
    public HTMLPrinter print(int value) {
        printer.print(value);
        return this;
    }

    /** Prints the long value. */
    public HTMLPrinter print(long value) {
        printer.print(value);
        return this;
    }

    /** Prints the float value. */
    public HTMLPrinter print(float value) {
        printer.print(value);
        return this;
    }

    /** Prints the long value. */
    public HTMLPrinter print(double value) {
        printer.print(value);
        return this;
    }

    /** Prints the string. */
    public HTMLPrinter print(String value) {
        printer.print(value);
        return this;
    }

    /** Prints the opening HTML tag. */
    public HTMLPrinter printOTag(String label) {
        printer.print("<");
        printer.print(label);
        printer.print(">");
        return this;
    }

    /** Prints the opening HTML tag 'label' with attributes 'attrs'. */
    public HTMLPrinter printOTag(String label, XMLAttribute[] attrs) {
        printer.print("<");
        printer.print(label);
        printer.print(" ");
        printer.print(StringOf.object.array(attrs, "", " ", ""));
        printer.print(">");
        return this;
    }

    /** Prints the closing HTML tag 'label'. */
    public HTMLPrinter printCTag(String label) {
        printer.print("</");
        printer.print(label);
        printer.print(">");
        return this;
    }

    /**
     * Prints the HTML tag <code>label</code> with contents <code>text</code>.
     *
     * @param label
     * @param text
     */
    public HTMLPrinter printTag(String label, String text) {
        printOTag(label);
        print(text);
        return printCTag(label);
    }

    /** Prints the HTML tag 'label' with attributes 'attrs' and contents 'text'. */
    public HTMLPrinter printTag(String label, XMLAttribute[] attrs, String text) {
        printOTag(label, attrs);
        print(text);
        printCTag(label);
        return this;
    }

    /** Prints the short HTML tag 'label'. */
    public HTMLPrinter printSTag(String label) {
        printer.print("<");
        printer.print(label);
        printer.print("/>");
        return this;
    }

    /** Prints <A HREF=link> text </a> tag. */
    public HTMLPrinter printAhref(String dest, String text) {
        printOTag("a", new XMLAttribute[]{ new XMLAttribute("href", dest) });
        print(text);
        return printCTag("a");
    }

    /** Prints <A HREF=dest TARGET=target> text </a> tag. */
    public HTMLPrinter printAhref(String dest, String target, String text) {
        printOTag("a", new XMLAttribute[]{
            new XMLAttribute("href", dest),
            new XMLAttribute("target", target)});
        print(text);
        return printCTag("a");
    }

    /** Prints <A NAME=name> text </a> tag. */
    public HTMLPrinter printAname(String anchor, String text) {
        printOTag("a", new XMLAttribute[]{ new XMLAttribute("name", anchor) });
        print(text);
        return printCTag("a");
    }

    /**
     * Prints text <code>text</code> in bold.
     *
     * @param text
     */
    public HTMLPrinter printBold(String text) {
        return printTag("b", text);
    }

    /**
     * Prints text <code>text</code> in color <code>color</code>.
     *
     * @param color
     * @param text
     */
    public HTMLPrinter printFontColor(String color, String text) {
	return printTag("font", new XMLAttribute[]{ new XMLAttribute("color", color) }, text);
    }

    /**
     * Prints comment with contents <code>text</code>.
     *
     * @param text
     */
    public HTMLPrinter printComment(String text) {
	printer.print("<!-- ");
        printer.print(text);
        printer.print(" -->");
        return this;
    }

    /**
     * Prints <code>n</code> HTML blank spaces.
     *
     * @param n The parameter <code>n</code> gives the number
     *          of printed blank spaces
     */
    public HTMLPrinter printNbsp(int n) {
	while (n > 0) {
            print("&nbsp;");
            n--;
        }
        return this;
    }

    /**
     * Prints an horizontal line separator.
     */
    public HTMLPrinter printHLine() {
        return printOTag("hr");
    }

    /**
     * Prints an horizontal line separator with attributes <code>attrs</code>.
     *
     * @param attrs
     */
    public HTMLPrinter printHLine(XMLAttribute[] attrs) {
        return printOTag("hr", attrs);
    }

    //########################################################################
    // Public Methods - Converting

    /**
     * Returns the string representation of this printer.
     */
    public String toString() {
        return printer.toString();
    }

    //########################################################################

    /**
     * Prints the HTML preamble of the current page.
     */
    protected void printPreamble() {
	println("<!DOCTYPE html PUBLIC \"-//W3C//DTD " +
            representation.getType() + "//" + representation.getLanguage() + "\">");
	printlnOTag("html").line();
    }

    /**
     * Prints a comment with generator name and generation date.
     *
     * @param generator
     */
    protected void printGeneratedBy(String generator) {
        if (generator != null) {
            SimpleDateFormat df = new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy");
            printlnComment("Generated by " + generator + " on " +
                df.format(new Date()));
        }
    }

    /**
     * Prints HTML meta informations.
     *
     * @param metaAttrs
     */
    protected void printMetaInfo(XMLAttribute[] metaAttrs) {
        printlnMeta(new XMLAttribute[]{
            new XMLAttribute("http-equiv", "content-type"),
            new XMLAttribute("content",
                             "text/html; charset=" + representation.getEncoding())});
        for (int i = 0; i < metaAttrs.length; i++) {
	    printlnMeta(new XMLAttribute[]{
                new XMLAttribute("name", metaAttrs[i].name),
                new XMLAttribute("content", metaAttrs[i].value)});
        }
    }

    /**
     * Prints HTML link information for style sheets.
     *
     *  @param stylesheets A list of stylesheets to be linked
     *                     to the current HTML document
     */
    protected void printStyles(String[] stylesheets) {
        for (int i = 0; i < stylesheets.length; i++) {
	    printlnLink(new XMLAttribute[]{
                new XMLAttribute("rel", "stylesheet"),
                new XMLAttribute("type", "text/css"),
	        new XMLAttribute("href", stylesheets[i])});
        }
    }

    /**
     * Prints HTML header section of the current page.
     *
     * @param metaAttrs
     * @param generator
     * @param stylesheets
     */
    public void printHeader(XMLAttribute[] metaAttrs, String generator, String[] stylesheets) {
        printPreamble();
        printlnOTag("head").indent();
        printlnTag("title", title);
        printGeneratedBy(generator);
        printMetaInfo(metaAttrs);
        printStyles(stylesheets);
        undent().printlnCTag("head").line();
    }

    /**
     * Prints HTML header section.
     *
     * @param metaXMLAttributes
     * @param generator
     * @param stylesheet
     */
    public void printHeader(XMLAttribute[] metaAttrs, String generator, String stylesheet) {
	printHeader(metaAttrs, generator, new String[]{ stylesheet });
    }

    /**
     * Prints HTML header section.
     *
     * @param metaXMLAttributes
     * @param generator
     */
    public void printHeader(XMLAttribute[] metaAttrs, String generator) {
	printHeader(metaAttrs, generator, DEFAULT_STYLESHEET);
    }

    /**
     * Prints the header section of the current page.
     *
     * @param metaXMLAttributes
     */
    public void printHeader(XMLAttribute[] metaAttrs) {
	printHeader(metaAttrs, null);
    }

    /**
     * Open the body section of the current page.
     */
    public void printOpenBody() {
	printlnOTag("body").indent();
    }

    /**
     * Prints the HTML footer of the current page.
     */
    public void printFootpage() {
	undent().printlnCTag("body");
	printlnCTag("html");
    }

    //########################################################################
}


/**
 * Map from Object to String.
 */
public abstract class StringOf {

    /**
     * Gives the string representation of an object.
     *
     * @param o
     */
    public abstract String element(Object o);

    /**
     * Gives the string representation of an array of objects.
     * Return delimiters for empty arrays depending on "delimWhenEmpty".
     *
     * @param objects
     * @param open
     * @param sep
     * @param close
     * @param delimWhenEmpty
     */
    public String array(Object[] objects, String open, String sep, String close, boolean delimWhenEmpty) {
	if ((objects.length == 0) && !delimWhenEmpty)
	    return "";
	else {
	    StringBuffer str = new StringBuffer();
	    str.append(open);
	    if (objects.length > 0) {
		str.append(element(objects[0]));
		for(int i = 1; i < objects.length; i++)
		    str.append(sep + element(objects[i]));
	    }
	    str.append(close);
	    return str.toString();
	}
    }

    /**
     * Returns always delimiters.
     *
     * @param objects
     * @param open
     * @param sep
     * @param close
     */
    public String array(Object[] objects, String open, String sep, String close) {
	return array(objects, open, sep, close, true);
    }

    /**
     * Basic map.
     */
    public static StringOf object = new StringOf() {
        public String element(Object o) {
            return o.toString();
        }
    };

}