Ejemplo n.º 1
0
func formatCode(src []byte, annotations []doc.TypeAnnotation) string {

	// Collect comment positions in type annotation with Name = ""
	var (
		comments []doc.TypeAnnotation
		s        scanner.Scanner
	)
	fset := token.NewFileSet()
	file := fset.AddFile("", fset.Base(), len(src))
	s.Init(file, src, nil, scanner.ScanComments)
commentLoop:
	for {
		pos, tok, lit := s.Scan()
		switch tok {
		case token.EOF:
			break commentLoop
		case token.COMMENT:
			p := file.Offset(pos)
			comments = append(comments, doc.TypeAnnotation{Pos: p, End: p + len(lit)})
		}
	}

	// Merge type annotations and comments without modifying the caller's slice
	// of annoations.
	switch {
	case len(comments) == 0:
		// nothing to do
	case len(annotations) == 0:
		annotations = comments
	default:
		annotations = append(comments, annotations...)
		sort.Sort(sortByPos(annotations))
	}

	var buf bytes.Buffer
	last := 0
	for _, a := range annotations {
		template.HTMLEscape(&buf, src[last:a.Pos])
		if a.Name != "" {
			p := a.ImportPath
			if p != "" {
				p = "/" + p
			}
			buf.WriteString(`<a href="`)
			buf.WriteString(urlFn(p))
			buf.WriteByte('#')
			buf.WriteString(urlFn(a.Name))
			buf.WriteString(`">`)
			template.HTMLEscape(&buf, src[a.Pos:a.End])
			buf.WriteString(`</a>`)
		} else {
			buf.WriteString(`<span class="com">`)
			template.HTMLEscape(&buf, src[a.Pos:a.End])
			buf.WriteString(`</span>`)
		}
		last = a.End
	}
	template.HTMLEscape(&buf, src[last:])
	return buf.String()
}
Ejemplo n.º 2
0
func selectionTag(w io.Writer, text []byte, selections int) {
	if selections < len(startTags) {
		if tag := startTags[selections]; len(tag) > 0 {
			w.Write(tag)
			template.HTMLEscape(w, text)
			w.Write(endTag)
			return
		}
	}
	template.HTMLEscape(w, text)
}
Ejemplo n.º 3
0
func pathEscFmt(w io.Writer, format string, x ...interface{}) {
	switch v := x[0].(type) {
	case []byte:
		template.HTMLEscape(w, v)
	case string:
		template.HTMLEscape(w, []byte(filepath.ToSlash(v)))
	default:
		var buf bytes.Buffer
		fmt.Fprint(&buf, x)
		template.HTMLEscape(w, buf.Bytes())
	}
}
Ejemplo n.º 4
0
func htmlEscFmt(w io.Writer, format string, x ...interface{}) {
	switch v := x[0].(type) {
	case int:
		template.HTMLEscape(w, []byte(strconv.Itoa(v)))
	case []byte:
		template.HTMLEscape(w, v)
	case string:
		template.HTMLEscape(w, []byte(v))
	default:
		var buf bytes.Buffer
		fmt.Fprint(&buf, x)
		template.HTMLEscape(w, buf.Bytes())
	}
}
Ejemplo n.º 5
0
func (p HTMLPrinter) Print(w io.Writer, kind syntaxhighlight.Kind, tokText string) error {
	class := HTMLConfig(p)[kind]
	if class != "" {
		_, err := w.Write([]byte(`<span class="`))
		if err != nil {
			return err
		}
		_, err = io.WriteString(w, class)
		if err != nil {
			return err
		}
		io.WriteString(w, " input-block") // For "display: block;" style.
		_, err = w.Write([]byte(`">`))
		if err != nil {
			return err
		}
	}
	template.HTMLEscape(w, []byte(tokText))
	if class != "" {
		_, err := w.Write([]byte(`</span>`))
		if err != nil {
			return err
		}
	}
	return nil
}
Ejemplo n.º 6
0
func (p HTMLPrinter) Print(w io.Writer, kind Kind, tokText string) error {
	class := ((HTMLConfig)(p)).class(kind)
	if class != "" {
		_, err := w.Write([]byte(`<span class="`))
		if err != nil {
			return err
		}
		_, err = io.WriteString(w, class)
		if err != nil {
			return err
		}
		_, err = w.Write([]byte(`">`))
		if err != nil {
			return err
		}
	}
	template.HTMLEscape(w, []byte(tokText))
	if class != "" {
		_, err := w.Write([]byte(`</span>`))
		if err != nil {
			return err
		}
	}
	return nil
}
Ejemplo n.º 7
0
func login(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method) //获取请求的方法
	if r.Method == "GET" {
		crutime := time.Now().Unix()
		h := md5.New()
		io.WriteString(h, strconv.FormatInt(crutime, 10))
		token := fmt.Sprintf("%x", h.Sum(nil))

		t, _ := template.ParseFiles("login.gtpl")
		t.Execute(w, token)
	} else {
		//请求的是登陆数据,那么执行登陆的逻辑判断
		r.ParseForm()
		token := r.Form.Get("token")
		fmt.Println(token)
		if token != "" {

			fmt.Println("***************************")
			//验证token的合法性
		} else {
			fmt.Println("============================")
			//不存在token报错
		}
		fmt.Println("username length:", len(r.Form["username"][0]))
		fmt.Println("username:"******"username"))) //输出到服务器端
		fmt.Println("password:"******"password")))
		template.HTMLEscape(w, []byte(r.Form.Get("username"))) //输出到客户端
	}
}
Ejemplo n.º 8
0
func posLink_urlFunc(node ast.Node, fset *token.FileSet) string {
	var relpath string
	var line int
	var low, high int // selection

	if p := node.Pos(); p.IsValid() {
		pos := fset.Position(p)
		relpath = pos.Filename
		line = pos.Line
		low = pos.Offset
	}
	if p := node.End(); p.IsValid() {
		high = fset.Position(p).Offset
	}

	var buf bytes.Buffer
	template.HTMLEscape(&buf, []byte(relpath))
	// selection ranges are of form "s=low:high"
	if low < high {
		fmt.Fprintf(&buf, "?s=%d:%d", low, high) // no need for URL escaping
		// if we have a selection, position the page
		// such that the selection is a bit below the top
		line -= 10
		if line < 1 {
			line = 1
		}
	}
	// line id's in html-printed source are of the
	// form "L%d" where %d stands for the line number
	if line > 0 {
		fmt.Fprintf(&buf, "#L%d", line) // no need for URL escaping
	}

	return buf.String()
}
Ejemplo n.º 9
0
func login(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method) //get request method
	if r.Method == "GET" {
		crutime := time.Now().Unix()
		h := md5.New()
		io.WriteString(h, strconv.FormatInt(crutime, 10))
		token := fmt.Sprintf("%x", h.Sum(nil))

		t, _ := template.ParseFiles("login.gtpl")
		t.Execute(w, token)
	} else {
		// log in request
		r.ParseForm()
		token := r.Form.Get("token")
		if token != "" {
			fmt.Println("Token: ", token)
			// check token validity
		} else {
			// give error if no token
		}
		fmt.Println("username length:", len(r.Form["username"][0]))
		fmt.Println("username:"******"username"))) // print in server side
		fmt.Println("password:"******"password")))
		template.HTMLEscape(w, []byte(r.Form.Get("username"))) // respond to client
	}
}
Ejemplo n.º 10
0
func prettySource(filename string, source string, limit int) (code string, err error) {
	prettyCode, ok := Print(filename, source)
	if ok != nil { // If it fails to parse, just serve it raw.
		coll := new(bytes.Buffer)
		template.HTMLEscape(coll, []byte(source))
		prettyCode = coll.String()
	}

	linesPre := Pre().Attrs(As{"class": "line-numbers"})
	codePre := Pre().Attrs(As{"class": "code-lines"})

	stopped := false
	for i, code := range strings.SplitN(prettyCode, "\n", -1) {
		line := i + 1
		linesPre.Append(
			fmt.Sprintf(
				A("%d").Attrs(As{
					"rel":  "#L%d",
					"href": "#LC%d",
					"id":   "LID%d",
				}).Out()+"\n",
				line, line, line, line))
		codePre.Append(
			Div(code).Attrs(As{
				"class": "line",
				"id":    "LC" + fmt.Sprint(line),
			}).Out())

		if limit != 0 && i == limit {
			stopped = true
			break
		}
	}

	if stopped {
		linesPre.Append("\n")
		codePre.Append(
			Div(
				"\n",
				A("...").Attrs(As{
					"href":  fmt.Sprintf("/view/%s", filename),
					"class": "go-comment",
				})).Attrs(As{
				"class": "line",
			}).Out())
	}

	code = Table(
		Tbody(
			Tr(
				Td(linesPre).Attrs(As{"width": "1%", "valign": "top"}),
				Td(codePre).Attrs(As{"valign": "top"})))).Attrs(As{
		"class":       "code",
		"cellspacing": "0",
		"cellpadding": "0",
	}).Out()

	return
}
Ejemplo n.º 11
0
// Emphasize and escape a line of text for HTML. URLs are converted into links;
// if the URL also appears in the words map, the link is taken from the map (if
// the corresponding map value is the empty string, the URL is not converted
// into a link). Go identifiers that appear in the words map are italicized; if
// the corresponding map value is not the empty string, it is considered a URL
// and the word is converted into a link. If nice is set, the remaining text's
// appearance is improved where it makes sense (e.g., `` is turned into &ldquo;
// and '' into &rdquo;).
func emphasize(w io.Writer, line string, words map[string]string, nice bool) {
	for {
		m := matchRx.FindStringSubmatchIndex(line)
		if m == nil {
			break
		}
		// m >= 6 (two parenthesized sub-regexps in matchRx, 1st one is urlRx)

		// write text before match
		commentEscape(w, line[0:m[0]], nice)

		// adjust match if necessary
		match := line[m[0]:m[1]]
		if n := pairedParensPrefixLen(match); n < len(match) {
			// match contains unpaired parentheses (rare);
			// redo matching with shortened line for correct indices
			m = matchRx.FindStringSubmatchIndex(line[:m[0]+n])
			match = match[:n]
		}

		// analyze match
		url := ""
		italics := false
		if words != nil {
			url, italics = words[match]
		}
		if m[2] >= 0 {
			// match against first parenthesized sub-regexp; must be match against urlRx
			if !italics {
				// no alternative URL in words list, use match instead
				url = match
			}
			italics = false // don't italicize URLs
		}

		// write match
		if len(url) > 0 {
			w.Write(html_a)
			template.HTMLEscape(w, []byte(url))
			w.Write(html_aq)
		}
		if italics {
			w.Write(html_i)
		}
		commentEscape(w, match, nice)
		if italics {
			w.Write(html_endi)
		}
		if len(url) > 0 {
			w.Write(html_enda)
		}

		// advance
		line = line[m[1]:]
	}
	commentEscape(w, line, nice)
}
Ejemplo n.º 12
0
Archivo: comment.go Proyecto: Lao16/gcc
// Escape comment text for HTML. If nice is set,
// also turn `` into &ldquo; and '' into &rdquo;.
func commentEscape(w io.Writer, text string, nice bool) {
	last := 0
	if nice {
		for i := 0; i < len(text)-1; i++ {
			ch := text[i]
			if ch == text[i+1] && (ch == '`' || ch == '\'') {
				template.HTMLEscape(w, []byte(text[last:i]))
				last = i + 2
				switch ch {
				case '`':
					w.Write(ldquo)
				case '\'':
					w.Write(rdquo)
				}
				i++ // loop will add one more
			}
		}
	}
	template.HTMLEscape(w, []byte(text[last:]))
}
Ejemplo n.º 13
0
// codewalkFileprint serves requests with ?fileprint=f&lo=lo&hi=hi.
// The filename f has already been retrieved and is passed as an argument.
// Lo and hi are the numbers of the first and last line to highlight
// in the response.  This format is used for the middle window pane
// of the codewalk pages.  It is a separate iframe and does not get
// the usual godoc HTML wrapper.
func codewalkFileprint(w http.ResponseWriter, r *http.Request, f string) {
	abspath := f
	data, err := vfs.ReadFile(fs, abspath)
	if err != nil {
		log.Print(err)
		pres.ServeError(w, r, f, err)
		return
	}
	lo, _ := strconv.Atoi(r.FormValue("lo"))
	hi, _ := strconv.Atoi(r.FormValue("hi"))
	if hi < lo {
		hi = lo
	}
	lo = lineToByte(data, lo)
	hi = lineToByte(data, hi+1)

	// Put the mark 4 lines before lo, so that the iframe
	// shows a few lines of context before the highlighted
	// section.
	n := 4
	mark := lo
	for ; mark > 0 && n > 0; mark-- {
		if data[mark-1] == '\n' {
			if n--; n == 0 {
				break
			}
		}
	}

	io.WriteString(w, `<style type="text/css">@import "/doc/codewalk/codewalk.css";</style><pre>`)
	template.HTMLEscape(w, data[0:mark])
	io.WriteString(w, "<a name='mark'></a>")
	template.HTMLEscape(w, data[mark:lo])
	if lo < hi {
		io.WriteString(w, "<div class='codewalkhighlight'>")
		template.HTMLEscape(w, data[lo:hi])
		io.WriteString(w, "</div>")
	}
	template.HTMLEscape(w, data[hi:])
	io.WriteString(w, "</pre>")
}
Ejemplo n.º 14
0
func ExampleAnnotate() {
	src := []byte(`package main

import "fmt"

func main() {
	fmt.Println("Hey there, Go.")
}
`)

	// debugAnnotator implements syntaxhighlight.Annotator and prints the parameters it's given.
	p := debugAnnotator{Annotator: syntaxhighlight.HTMLAnnotator(syntaxhighlight.DefaultHTMLConfig)}

	anns, err := highlight_go.Annotate(src, p)
	if err != nil {
		log.Fatalln(err)
	}

	sort.Sort(anns)

	b, err := annotate.Annotate(src, anns, func(w io.Writer, b []byte) { template.HTMLEscape(w, b) })
	if err != nil {
		log.Fatalln(err)
	}

	fmt.Println(string(b))

	// Output:
	// Annotate(0, syntaxhighlight.Keyword, "package")
	// Annotate(8, syntaxhighlight.Plaintext, "main")
	// Annotate(14, syntaxhighlight.Keyword, "import")
	// Annotate(21, syntaxhighlight.String, "\"fmt\"")
	// Annotate(28, syntaxhighlight.Keyword, "func")
	// Annotate(33, syntaxhighlight.Plaintext, "main")
	// Annotate(37, syntaxhighlight.Plaintext, "(")
	// Annotate(38, syntaxhighlight.Plaintext, ")")
	// Annotate(40, syntaxhighlight.Plaintext, "{")
	// Annotate(43, syntaxhighlight.Plaintext, "fmt")
	// Annotate(46, syntaxhighlight.Plaintext, ".")
	// Annotate(47, syntaxhighlight.Plaintext, "Println")
	// Annotate(54, syntaxhighlight.Plaintext, "(")
	// Annotate(55, syntaxhighlight.String, "\"Hey there, Go.\"")
	// Annotate(71, syntaxhighlight.Plaintext, ")")
	// Annotate(73, syntaxhighlight.Plaintext, "}")
	// <span class="kwd">package</span> <span class="pln">main</span>
	//
	// <span class="kwd">import</span> <span class="str">&#34;fmt&#34;</span>
	//
	// <span class="kwd">func</span> <span class="pln">main</span><span class="pln">(</span><span class="pln">)</span> <span class="pln">{</span>
	// 	<span class="pln">fmt</span><span class="pln">.</span><span class="pln">Println</span><span class="pln">(</span><span class="str">&#34;Hey there, Go.&#34;</span><span class="pln">)</span>
	// <span class="pln">}</span>
}
Ejemplo n.º 15
0
// declFmt formats a Decl as HTML.
func declFmt(decl doc.Decl) string {
	var buf bytes.Buffer
	last := 0
	t := []byte(decl.Text)
	for _, a := range decl.Annotations {
		p := a.ImportPath
		if p != "" {
			p = "/" + p
		}
		template.HTMLEscape(&buf, t[last:a.Pos])
		//buf.WriteString(`<a href="`)
		//buf.WriteString(urlFmt(p))
		//buf.WriteByte('#')
		//buf.WriteString(urlFmt(a.Name))
		//buf.WriteString(`">`)
		template.HTMLEscape(&buf, t[a.Pos:a.End])
		//buf.WriteString(`</a>`)
		last = a.End
	}
	template.HTMLEscape(&buf, t[last:])
	return buf.String()
}
Ejemplo n.º 16
0
func main() {
	// handle input
	flag.Parse()
	if *srcFn == "" || *getName == "" {
		flag.Usage()
		os.Exit(2)
	}
	// load file
	fs := token.NewFileSet()
	file, err := parser.ParseFile(fs, *srcFn, nil, 0)
	if err != nil {
		log.Fatal(err)
	}
	// create filter
	filter := func(name string) bool {
		return name == *getName
	}
	// filter
	if !ast.FilterFile(file, filter) {
		os.Exit(1)
	}
	// print the AST
	var b bytes.Buffer
	printer.Fprint(&b, fs, file)
	// drop package declaration
	if !*showPkg {
		for {
			c, err := b.ReadByte()
			if c == '\n' || err != nil {
				break
			}
		}
	}
	// drop leading newlines
	for {
		b, err := b.ReadByte()
		if err != nil {
			break
		}
		if b != '\n' {
			os.Stdout.Write([]byte{b})
			break
		}
	}
	// output
	if *html {
		template.HTMLEscape(os.Stdout, b.Bytes())
	} else {
		b.WriteTo(os.Stdout)
	}
}
Ejemplo n.º 17
0
Archivo: comment.go Proyecto: Lao16/gcc
// Emphasize and escape a line of text for HTML. URLs are converted into links;
// if the URL also appears in the words map, the link is taken from the map (if
// the corresponding map value is the empty string, the URL is not converted
// into a link). Go identifiers that appear in the words map are italicized; if
// the corresponding map value is not the empty string, it is considered a URL
// and the word is converted into a link. If nice is set, the remaining text's
// appearance is improved where it makes sense (e.g., `` is turned into &ldquo;
// and '' into &rdquo;).
func emphasize(w io.Writer, line string, words map[string]string, nice bool) {
	for {
		m := matchRx.FindStringSubmatchIndex(line)
		if m == nil {
			break
		}
		// m >= 6 (two parenthesized sub-regexps in matchRx, 1st one is urlRx)

		// write text before match
		commentEscape(w, line[0:m[0]], nice)

		// analyze match
		match := line[m[0]:m[1]]
		url := ""
		italics := false
		if words != nil {
			url, italics = words[string(match)]
		}
		if m[2] >= 0 {
			// match against first parenthesized sub-regexp; must be match against urlRx
			if !italics {
				// no alternative URL in words list, use match instead
				url = string(match)
			}
			italics = false // don't italicize URLs
		}

		// write match
		if len(url) > 0 {
			w.Write(html_a)
			template.HTMLEscape(w, []byte(url))
			w.Write(html_aq)
		}
		if italics {
			w.Write(html_i)
		}
		commentEscape(w, match, nice)
		if italics {
			w.Write(html_endi)
		}
		if len(url) > 0 {
			w.Write(html_enda)
		}

		// advance
		line = line[m[1]:]
	}
	commentEscape(w, line, nice)
}
Ejemplo n.º 18
0
func breadcrumbsFmt(pdoc *doc.Package) string {
	importPath := []byte(pdoc.ImportPath)
	var buf bytes.Buffer
	i := 0
	j := len(pdoc.ProjectRoot)
	switch {
	case j == 0:
		buf.WriteString("<a href=\"/-/go\" title=\"Standard Packages\">☆</a> ")
		j = bytes.IndexByte(importPath, '/')
	case j >= len(importPath):
		j = -1
	}
	for j > 0 {
		buf.WriteString(`<a href="/`)
		buf.WriteString(urlFmt(string(importPath[:i+j])))
		buf.WriteString(`">`)
		template.HTMLEscape(&buf, importPath[i:i+j])
		buf.WriteString(`</a>/`)
		i = i + j + 1
		j = bytes.IndexByte(importPath[i:], '/')
	}
	template.HTMLEscape(&buf, importPath[i:])
	return buf.String()
}
Ejemplo n.º 19
0
// n must be an ast.Node or a *doc.Note
func posLink_urlFunc(info *PageInfo, n interface{}) string {
	var pos, end token.Pos

	switch n := n.(type) {
	case ast.Node:
		pos = n.Pos()
		end = n.End()
	case *doc.Note:
		pos = n.Pos
		end = n.End
	default:
		panic(fmt.Sprintf("wrong type for posLink_url template formatter: %T", n))
	}

	var relpath string
	var line int
	var low, high int // selection offset range

	if pos.IsValid() {
		p := info.FSet.Position(pos)
		relpath = p.Filename
		line = p.Line
		low = p.Offset
	}
	if end.IsValid() {
		high = info.FSet.Position(end).Offset
	}

	var buf bytes.Buffer
	template.HTMLEscape(&buf, []byte(relpath))
	// selection ranges are of form "s=low:high"
	if low < high {
		fmt.Fprintf(&buf, "?s=%d:%d", low, high) // no need for URL escaping
		// if we have a selection, position the page
		// such that the selection is a bit below the top
		line -= 10
		if line < 1 {
			line = 1
		}
	}
	// line id's in html-printed source are of the
	// form "L%d" where %d stands for the line number
	if line > 0 {
		fmt.Fprintf(&buf, "#L%d", line) // no need for URL escaping
	}

	return buf.String()
}
Ejemplo n.º 20
0
func (s *state) evalPrint(node *ast.PrintNode) {
	s.walk(node.Arg)
	if _, ok := s.val.(data.Undefined); ok {
		s.errorf("In 'print' tag, expression %q evaluates to undefined.", node.Arg.String())
	}
	var escapeHtml = s.autoescape != ast.AutoescapeOff
	var result = s.val
	for _, directiveNode := range node.Directives {
		var directive, ok = PrintDirectives[directiveNode.Name]
		if !ok {
			s.errorf("Print directive %q does not exist", directiveNode.Name)
		}

		if !checkNumArgs(directive.ValidArgLengths, len(directiveNode.Args)) {
			s.errorf("Print directive %q called with %v args, expected one of: %v",
				directiveNode.Name, len(directiveNode.Args), directive.ValidArgLengths)
		}

		var args []data.Value
		for _, arg := range directiveNode.Args {
			args = append(args, s.eval(arg))
		}
		defer func() {
			if err := recover(); err != nil {
				s.errorf("panic in %v: %v\nexecuted: %v(%q, %v)\n%v",
					directiveNode, err,
					directiveNode.Name, result, args,
					string(debug.Stack()))
			}
		}()
		result = directive.Apply(result, args)
		if directive.CancelAutoescape {
			escapeHtml = false
		}
	}

	if escapeHtml {
		template.HTMLEscape(s.wr, []byte(result.String()))
	} else {
		if _, err := s.wr.Write([]byte(result.String())); err != nil {
			s.errorf("%s", err)
		}
	}
}
Ejemplo n.º 21
0
func (t *TReplaser) replace(tpl parser.Ttpl, v map[string]interface{}, writer io.Writer) {
	for i := range tpl {
		switch tag := tpl[i].(type) {
		case tTagi18nCon:
			writer.Write(t.i18n.P(tag[0], v[tag[1]].([]interface{})...))
		case tTagi18nVar:
			writer.Write(t.i18n.P(v[tag[0]].(string), v[tag[1]].([]interface{})...))
		case tTagText:
			writer.Write(tag)
		case tTagVar:
			fmt.Fprint(writer, v[string(tag)])
		case tTagVarHtmlEsc:
			template.HTMLEscape(writer, []byte(fmt.Sprint(v[string(tag)])))
		case *tTagIncludeCon:
			t.replace(tag.tpl, getVarfromContext(tag.contextVar, v).(map[string]interface{}), writer)
		case tTagIncludeVar:
			t.Replace(tag[0], getVarfromContext(tag[1], v).(map[string]interface{}), writer)
		}
	}
}
Ejemplo n.º 22
0
func srcPosLinkFunc(s string, line, low, high int) string {
	var buf bytes.Buffer
	template.HTMLEscape(&buf, []byte(s))
	// selection ranges are of form "s=low:high"
	if low < high {
		fmt.Fprintf(&buf, "?s=%d:%d", low, high) // no need for URL escaping
		// if we have a selection, position the page
		// such that the selection is a bit below the top
		line -= 10
		if line < 1 {
			line = 1
		}
	}
	// line id's in html-printed source are of the
	// form "L%d" where %d stands for the line number
	if line > 0 {
		fmt.Fprintf(&buf, "#L%d", line) // no need for URL escaping
	}
	return buf.String()
}
Ejemplo n.º 23
0
// FormatText HTML-escapes text and writes it to w.
// Consecutive text segments are wrapped in HTML spans (with tags as
// defined by startTags and endTag) as follows:
//
//	- if line >= 0, line number (ln) spans are inserted before each line,
//	  starting with the value of line
//	- if the text is Go source, comments get the "comment" span class
//	- each occurrence of the regular expression pattern gets the "highlight"
//	  span class
//	- text segments covered by selection get the "selection" span class
//
// Comments, highlights, and selections may overlap arbitrarily; the respective
// HTML span classes are specified in the startTags variable.
//
func FormatText(w io.Writer, text []byte, line int, goSource bool, pattern string, selection Selection) {
	var comments, highlights Selection
	if goSource {
		comments = tokenSelection(text, token.COMMENT)
	}
	if pattern != "" {
		highlights = regexpSelection(text, pattern)
	}
	if line >= 0 || comments != nil || highlights != nil || selection != nil {
		var lineTag LinkWriter
		if line >= 0 {
			lineTag = func(w io.Writer, _ int, start bool) {
				if start {
					fmt.Fprintf(w, "<a id=\"L%d\"></a><span class=\"ln\">%6d</span>\t", line, line)
					line++
				}
			}
		}
		FormatSelections(w, text, lineTag, lineSelection(text), selectionTag, comments, highlights, selection)
	} else {
		template.HTMLEscape(w, text)
	}
}
Ejemplo n.º 24
0
func NextBus(w io.Writer, c appengine.Context) {
	item, err := memcache.Get(c, "nextbus")
	if err != nil {
		c.Errorf("%s", err)
		return
	}

	data := struct {
		Predictions []struct {
			RouteTag  string `xml:"routeTag,attr"`
			Direction []struct {
				Title      string       `xml:"title,attr"`
				Prediction []prediction `xml:"prediction"`
			} `xml:"direction"`
			Message []struct {
				Text string `xml:"text,attr"`
			} `xml:"message"`
		} `xml:"predictions"`
	}{}
	if err := xml.Unmarshal(item.Value, &data); err != nil {
		c.Errorf("%s", err)
		return
	}

	// Messages are given per route, but they seem to be used for
	// systemwide messages.  Annoyingly, not every route gets the
	// message, so we can't infer that a message is about a
	// systemwide event.
	seen := make(map[string]bool)
	for _, p := range data.Predictions {
		for _, m := range p.Message {
			if BoringMuniMessages[m.Text] || seen[m.Text] {
				continue
			}
			seen[m.Text] = true
			io.WriteString(w, `<div class=munimessage>`)
			template.HTMLEscape(w, []byte(m.Text))
			io.WriteString(w, `</div>`)
		}
	}

	for _, p := range data.Predictions {
		for _, d := range p.Direction {
			io.WriteString(w, `<div class=bus><div class=route>`)
			template.HTMLEscape(w, []byte(p.RouteTag))
			io.WriteString(w, ` <span class=smaller>`)
			title := d.Title
			title = strings.Replace(title, "Inbound", "inbound", -1)
			title = strings.Replace(title, "Outbound", "outbound", -1)
			title = strings.Replace(title, "Downtown", "downtown", -1)
			title = strings.Replace(title, " District", "", -1)
			title = strings.Replace(title, " Disrict", "", -1)
			template.HTMLEscape(w, []byte(title))
			io.WriteString(w, `</span></div><div>`)
			for i, pp := range d.Prediction {
				if pp.Departure && i == 0 {
					io.WriteString(w, "departs ")
				}
				s := pp.String()
				io.WriteString(w, s)
				if i == len(d.Prediction)-1 {
					if s == "1" {
						io.WriteString(w, ` minute`)
					} else {
						io.WriteString(w, ` minutes`)
					}
				} else {
					io.WriteString(w, `, `)
				}
			}
			io.WriteString(w, `</div>`)
		}
	}
}
Ejemplo n.º 25
0
func TestWithHTML(t *testing.T) {
	annsByFile := map[string][]*Annotation{
		"hello_world.txt": []*Annotation{
			{0, 5, []byte("<b>"), []byte("</b>"), 0},
			{7, 12, []byte("<i>"), []byte("</i>"), 0},
		},
		"adjacent.txt": []*Annotation{
			{0, 3, []byte("<b>"), []byte("</b>"), 0},
			{3, 6, []byte("<i>"), []byte("</i>"), 0},
		},
		"empties.txt": []*Annotation{
			{0, 0, []byte("<b>"), []byte("</b>"), 0},
			{0, 0, []byte("<i>"), []byte("</i>"), 0},
			{2, 2, []byte("<i>"), []byte("</i>"), 0},
		},
		"nested_0.txt": []*Annotation{
			{0, 4, []byte("<1>"), []byte("</1>"), 0},
			{1, 3, []byte("<2>"), []byte("</2>"), 0},
		},
		"nested_1.txt": []*Annotation{
			{0, 4, []byte("<1>"), []byte("</1>"), 0},
			{1, 3, []byte("<2>"), []byte("</2>"), 0},
			{2, 2, []byte("<3>"), []byte("</3>"), 0},
		},
		"nested_2.txt": []*Annotation{
			{0, 2, []byte("<1>"), []byte("</1>"), 0},
			{2, 4, []byte("<2>"), []byte("</2>"), 0},
			{4, 6, []byte("<3>"), []byte("</3>"), 0},
			{7, 8, []byte("<4>"), []byte("</4>"), 0},
		},
		"html.txt": []*Annotation{
			{193, 203, []byte("<1>"), []byte("</1>"), 0},
			{336, 339, []byte("<WOOF>"), []byte("</WOOF>"), 0},
		},
	}

	dir := "testdata"
	tests, err := ioutil.ReadDir(dir)
	if err != nil {
		t.Fatal(err)
	}

	for _, test := range tests {
		name := test.Name()
		if !strings.Contains(name, *match) {
			continue
		}
		if strings.HasSuffix(name, ".html") {
			continue
		}
		path := filepath.Join(dir, name)
		input, err := ioutil.ReadFile(path)
		if err != nil {
			t.Fatal(err)
			continue
		}

		anns := annsByFile[name]
		var buf bytes.Buffer
		err = WithHTML(input, anns, func(w io.Writer, b []byte) {
			template.HTMLEscape(w, b)
		}, &buf)
		if err != nil {
			t.Errorf("%s: WithHTML: %s", name, err)
			continue
		}
		got := buf.Bytes()

		expPath := path + ".html"
		if *saveExp {
			err = ioutil.WriteFile(expPath, got, 0700)
			if err != nil {
				t.Fatal(err)
			}
			continue
		}

		want, err := ioutil.ReadFile(expPath)
		if err != nil {
			t.Fatal(err)
		}

		want = bytes.TrimSpace(want)
		got = bytes.TrimSpace(got)

		if !bytes.Equal(want, got) {
			t.Errorf("%s: want %q, got %q", name, want, got)
			continue
		}
	}

	if *saveExp {
		t.Fatal("overwrote all expected output files with actual output (run tests again without -exp)")
	}
}
Ejemplo n.º 26
0
func main() {
	b, _ := ioutil.ReadAll(os.Stdin)
	template.HTMLEscape(os.Stdout, b)
}
Ejemplo n.º 27
0
func Forecast(w io.Writer, c appengine.Context) {
	item, err := memcache.Get(c, "forecast")
	if err != nil {
		c.Errorf("%s", err)
		return
	}

	data := struct {
		Data []struct {
			Type       string `xml:"type,attr"`
			TimeLayout []struct {
				LayoutKey      string `xml:"layout-key"`
				StartValidTime []struct {
					PeriodName string `xml:"period-name,attr"`
				} `xml:"start-valid-time"`
			} `xml:"time-layout"`
			Parameters struct {
				WordedForecast struct {
					TimeLayout string   `xml:"time-layout,attr"`
					Text       []string `xml:"text"`
				} `xml:"wordedForecast"`
			} `xml:"parameters"`
		} `xml:"data"`
	}{}
	p := xml.NewDecoder(strings.NewReader(string(item.Value)))
	// NWS serves XML in ISO-8859-1 for no reason; the data is really ASCII.
	p.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) {
		return input, nil
	}
	if err = p.DecodeElement(&data, nil); err != nil {
		c.Errorf("%s", err)
		return
	}

	io.WriteString(w, `<div class=smaller style="text-align: left">`)
	for _, d := range data.Data {
		if d.Type != "forecast" {
			continue
		}
		var periods []string
		for _, tl := range d.TimeLayout {
			if tl.LayoutKey != d.Parameters.WordedForecast.TimeLayout {
				continue
			}
			for _, svt := range tl.StartValidTime {
				pn := svt.PeriodName
				pn = strings.Replace(pn, " Morning", " morning", -1)
				pn = strings.Replace(pn, " Afternoon", " afternoon", -1)
				pn = strings.Replace(pn, " Night", " night", -1)
				periods = append(periods, pn)
			}
		}
		texts := d.Parameters.WordedForecast.Text
		if len(texts) != len(periods) {
			c.Errorf("weather: len(texts) = %d, len(periods) = %d",
				len(texts), len(periods))
			continue
		}
		if len(texts) > 4 {
			texts = texts[:4]
		}
		for i, text := range texts {
			io.WriteString(w, `<div style="margin-bottom: 8px"><span class=header>`)
			template.HTMLEscape(w, []byte(periods[i]))
			io.WriteString(w, `:</span> `)

			text = strings.Replace(text, "km/h", "km/\u2060h", -1)
			spaceSubs := make(map[int]string)
			matches := nbspRegexp.FindAllStringIndex(text, -1)
			if len(matches) > 0 {
				for i := 0; i < len(matches[0]); i += 2 {
					spaceSubs[matches[0][i]] = "&nbsp;"
				}
			}
			matches = thinspRegexp.FindAllStringIndex(text, -1)
			if len(matches) > 0 {
				for i := 0; i < len(matches[0]); i += 2 {
					spaceSubs[matches[0][i]+1] = `<span style="white-space: nowrap">&thinsp;</span>`
				}
			}
			for i, ch := range text {
				sub, ok := spaceSubs[i]
				if ok {
					io.WriteString(w, sub)
				} else {
					io.WriteString(w, string(ch))
				}
			}

			io.WriteString(w, `</div>`)
		}
	}
	io.WriteString(w, `</div>`)
}
Ejemplo n.º 28
0
func textFmt(w io.Writer, format string, x ...interface{}) {
	var buf bytes.Buffer
	fmt.Fprint(&buf, x)
	template.HTMLEscape(w, buf.Bytes())
}
Ejemplo n.º 29
0
// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
func HTMLEscape(w io.Writer, b []byte) {
	template.HTMLEscape(w, b)
}
Ejemplo n.º 30
0
// Template formatter for "time" format.
func timeFmt(w io.Writer, format string, x ...interface{}) {
	template.HTMLEscape(w, []byte(time.Unix(x[0].(int64)/1e9, 0).String()))
}