--- /dev/null
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package htmlwriter
+
+import (
+ "os";
+ "io";
+ "array";
+ "utf8";
+)
+
+// Writer is a filter implementing the io.Write interface.
+// It provides facilities to generate HTML tags and does
+// proper HTML-escaping for text written through it.
+
+export type Writer struct {
+ // TODO should not export any of the fields
+ writer io.Write;
+}
+
+
+func (b *Writer) Init(writer io.Write) *Writer {
+ b.writer = writer;
+ return b;
+}
+
+
+/* export */ func (b *Writer) Flush() *os.Error {
+ return nil;
+}
+
+
+/* export */ func (b *Writer) Write(buf *[]byte) (written int, err *os.Error) {
+ written, err = b.writer.Write(buf); // BUG 6g - should just have return
+ return written, err;
+}
+
+
+export func New(writer io.Write) *Writer {
+ return new(Writer).Init(writer);
+}
"tabwriter";
"flag";
"fmt";
+ "htmlwriter";
Scanner "scanner";
AST "ast";
)
maxnewlines = flag.Int("maxnewlines", 3, nil, "max. number of consecutive newlines");
// formatting control
+ html = flag.Bool("html", false, nil, "generate html");
comments = flag.Bool("comments", true, nil, "print comments");
optsemicolons = flag.Bool("optsemicolons", false, nil, "print optional semicolons");
)
type Printer struct {
// output
- writer *tabwriter.Writer;
+ writer *htmlwriter.Writer;
// comments
comments *array.Array; // the list of all comments
}
-func (P *Printer) Init(writer *tabwriter.Writer, comments *array.Array) {
+func (P *Printer) Init(writer *htmlwriter.Writer, comments *array.Array) {
// writer
- padchar := byte(' ');
- if usetabs.BVal() {
- padchar = '\t';
- }
- P.writer = tabwriter.New(os.Stdout, int(tabwidth.IVal()), 1, padchar, true);
-
+ P.writer = writer;
+
// comments
P.comments = comments;
P.cindex = -1;
}
-func (P *Printer) Separator(separator int) {
- P.separator = separator;
- P.String(0, "");
-}
-
-
func (P *Printer) Token(pos int, tok int) {
P.String(pos, Scanner.TokenString(tok));
}
}
+// ----------------------------------------------------------------------------
+// HTML support
+// TODO Move this to html writer
+
+func (P *Printer) HtmlPrologue(title string) {
+ if html.BVal() {
+ P.String(0,
+ "<html>\n"
+ "<head>\n"
+ " <META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n"
+ " <title>" + title + "</title>\n"
+ " <style type=\"text/css\">\n"
+ " </style>\n"
+ "</head>\n"
+ "<body>\n"
+ "<pre>\n"
+ )
+ }
+}
+
+
+func (P *Printer) HtmlEpilogue() {
+ if html.BVal() {
+ P.String(0,
+ "</pre>\n"
+ "</body>\n"
+ "<html>\n"
+ )
+ }
+}
+
+
+func (P *Printer) HtmlIdentifier(pos int, ident string) {
+ if html.BVal() {
+ P.String(pos, `<a href="#` + ident + `">` + ident + `</a>`);
+ } else {
+ P.String(pos, ident);
+ }
+}
+
+
// ----------------------------------------------------------------------------
// Types
x := list.At(i).(*AST.Expr);
if i > 0 {
if prev == x.tok || prev == Scanner.TYPE {
- P.Separator(comma);
+ P.separator = comma;
} else {
- P.Separator(blank);
+ P.separator = blank;
}
}
P.Expr(x);
// type expr
P.Type(x.t);
- case Scanner.IDENT, Scanner.INT, Scanner.STRING, Scanner.FLOAT:
+ case Scanner.IDENT:
+ P.HtmlIdentifier(x.pos, x.s);
+
+ case Scanner.INT, Scanner.STRING, Scanner.FLOAT:
// literal
P.String(x.pos, x.s);
if usetabs.BVal() {
padchar = '\t';
}
- writer := tabwriter.New(os.Stdout, int(tabwidth.IVal()), 1, padchar, true);
+ twriter := tabwriter.New(os.Stdout, int(tabwidth.IVal()), 1, padchar, true);
+ hwriter := htmlwriter.New(twriter);
var P Printer;
- P.Init(writer, prog.comments);
+ P.Init(hwriter, prog.comments);
+ P.HtmlPrologue("<the source>");
P.Program(prog);
+ P.HtmlEpilogue();
- // flush
P.String(0, ""); // flush pending separator/newlines
- err := P.writer.Flush();
- if err != nil {
- panic("print error - exiting");
- }
+ hwriter.Flush(); // ignore errors
+ twriter.Flush(); // ignore errors
}