Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(147)

Unified Diff: doc/htmlgen.go

Issue 4699041: code review 4699041: go_tutorial: change the way it's generated. (Closed)
Patch Set: diff -r 2131931a8b68 https://go.googlecode.com/hg/ Created 13 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « doc/go_tutorial.txt ('k') | doc/makehtml » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: doc/htmlgen.go
===================================================================
deleted file mode 100644
--- a/doc/htmlgen.go
+++ /dev/null
@@ -1,312 +0,0 @@
-// 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.
-
-// If --html is set, process plain text into HTML.
-// - h2's are made from lines followed by a line "----\n"
-// - tab-indented blocks become <pre> blocks with the first tab deleted
-// - blank lines become <p> marks (except inside <pre> tags)
-// - "quoted strings" become <code>quoted strings</code>
-
-// Lines beginning !src define pieces of program source to be
-// extracted from other files and injected as <pre> blocks.
-// The syntax is simple: 1, 2, or 3 space-separated arguments:
-//
-// Whole file:
-// !src foo.go
-// One line (here the signature of main):
-// !src foo.go /^func.main/
-// Block of text, determined by start and end (here the body of main):
-// !src foo.go /^func.main/ /^}/
-//
-// Patterns can be /regular.expression/, a decimal number, or $
-// to signify the end of the file.
-// TODO: the regular expression cannot contain spaces; does this matter?
-
-package main
-
-import (
- "bufio"
- "bytes"
- "flag"
- "fmt"
- "io/ioutil"
- "log"
- "os"
- "regexp"
- "strconv"
- "strings"
- "template"
-)
-
-var (
- html = flag.Bool("html", true, "process text into HTML")
-)
-
-var (
- // lines holds the input and is reworked in place during processing.
- lines = make([][]byte, 0, 20000)
-
- empty = []byte("")
- newline = []byte("\n")
- tab = []byte("\t")
- quote = []byte(`"`)
- indent = []byte(" ")
-
- sectionMarker = []byte("----\n")
- preStart = []byte("<pre>")
- preEnd = []byte("</pre>\n")
- pp = []byte("<p>\n")
-
- srcPrefix = []byte("!src")
-)
-
-func main() {
- flag.Parse()
- read()
- programs()
- if *html {
- headings()
- coalesce(preStart, foldPre)
- coalesce(tab, foldTabs)
- paragraphs()
- quotes()
- }
- write()
-}
-
-// read turns standard input into a slice of lines.
-func read() {
- b := bufio.NewReader(os.Stdin)
- for {
- line, err := b.ReadBytes('\n')
- if err == os.EOF {
- break
- }
- if err != nil {
- log.Fatal(err)
- }
- lines = append(lines, line)
- }
-}
-
-// write puts the result on standard output.
-func write() {
- b := bufio.NewWriter(os.Stdout)
- for _, line := range lines {
- b.Write(expandTabs(line))
- }
- b.Flush()
-}
-
-// programs injects source code from !src invocations.
-func programs() {
- nlines := make([][]byte, 0, len(lines)*3/2)
- for _, line := range lines {
- if bytes.HasPrefix(line, srcPrefix) {
- line = trim(line)[len(srcPrefix):]
- prog := srcCommand(string(line))
- if *html {
- nlines = append(nlines, []byte(fmt.Sprintf("<pre><!--%s\n-->", line)))
- }
- for _, l := range prog {
- nlines = append(nlines, htmlEscape(l))
- }
- if *html {
- nlines = append(nlines, preEnd)
- }
- } else {
- nlines = append(nlines, line)
- }
- }
- lines = nlines
-}
-
-// srcCommand processes one !src invocation.
-func srcCommand(command string) [][]byte {
- // TODO: quoted args so we can have 'a b'?
- args := strings.Fields(command)
- if len(args) == 0 || len(args) > 3 {
- log.Fatal("bad syntax for src command: %s", command)
- }
- file := args[0]
- lines := bytes.SplitAfter(readFile(file), newline)
- // File plus zero args: whole file:
- // !src file.go
- if len(args) == 1 {
- return lines
- }
- start := match(file, 0, lines, string(args[1]))
- // File plus one arg: one line:
- // !src file.go /foo/
- if len(args) == 2 {
- return [][]byte{lines[start]}
- }
- // File plus two args: range:
- // !src file.go /foo/ /^}/
- end := match(file, start, lines, string(args[2]))
- return lines[start : end+1] // +1 to include matched line.
-}
-
-// htmlEscape makes sure input is HTML clean, if necessary.
-func htmlEscape(input []byte) []byte {
- if !*html || bytes.IndexAny(input, `&"<>`) < 0 {
- return input
- }
- var b bytes.Buffer
- template.HTMLEscape(&b, input)
- return b.Bytes()
-}
-
-// readFile reads and returns a file as part of !src processing.
-func readFile(name string) []byte {
- file, err := ioutil.ReadFile(name)
- if err != nil {
- log.Fatal(err)
- }
- return file
-}
-
-// match identifies the input line that matches the pattern in a !src invocation.
-// If start>0, match lines starting there rather than at the beginning.
-func match(file string, start int, lines [][]byte, pattern string) int {
- // $ matches the end of the file.
- if pattern == "$" {
- return len(lines) - 1
- }
- // Number matches the line.
- if i, err := strconv.Atoi(pattern); err == nil {
- return i - 1 // Lines are 1-indexed.
- }
- // /regexp/ matches the line that matches the regexp.
- if len(pattern) > 2 && pattern[0] == '/' && pattern[len(pattern)-1] == '/' {
- re, err := regexp.Compile(pattern[1 : len(pattern)-1])
- if err != nil {
- log.Fatal(err)
- }
- for i := start; i < len(lines); i++ {
- if re.Match(lines[i]) {
- return i
- }
- }
- log.Fatalf("%s: no match for %s", file, pattern)
- }
- log.Fatalf("unrecognized pattern: %s", pattern)
- return 0
-}
-
-// coalesce combines lines. Each time prefix is found on a line,
-// it calls fold and replaces the line with return value from fold.
-func coalesce(prefix []byte, fold func(i int) (n int, line []byte)) {
- j := 0 // output line number goes up by one each loop
- for i := 0; i < len(lines); {
- if bytes.HasPrefix(lines[i], prefix) {
- nlines, block := fold(i)
- lines[j] = block
- i += nlines
- } else {
- lines[j] = lines[i]
- i++
- }
- j++
- }
- lines = lines[0:j]
-}
-
-// foldPre returns the <pre> block as a single slice.
-func foldPre(i int) (n int, line []byte) {
- buf := new(bytes.Buffer)
- for i < len(lines) {
- buf.Write(lines[i])
- n++
- if bytes.Equal(lines[i], preEnd) {
- break
- }
- i++
- }
- return n, buf.Bytes()
-}
-
-// foldTabs returns the tab-indented block as a single <pre>-bounded slice.
-func foldTabs(i int) (n int, line []byte) {
- buf := new(bytes.Buffer)
- buf.WriteString("<pre>\n")
- for i < len(lines) {
- if !bytes.HasPrefix(lines[i], tab) {
- break
- }
- buf.Write(lines[i][1:]) // delete leading tab.
- n++
- i++
- }
- buf.WriteString("</pre>\n")
- return n, buf.Bytes()
-}
-
-// headings turns sections into HTML sections.
-func headings() {
- b := bufio.NewWriter(os.Stdout)
- for i, l := range lines {
- if i > 0 && bytes.Equal(l, sectionMarker) {
- lines[i-1] = []byte("<h2>" + string(trim(lines[i-1])) + "</h2>\n")
- lines[i] = empty
- }
- }
- b.Flush()
-}
-
-// paragraphs turns blank lines into paragraph marks.
-func paragraphs() {
- for i, l := range lines {
- if bytes.Equal(l, newline) {
- lines[i] = pp
- }
- }
-}
-
-// quotes turns "x" in the file into <code>x</code>.
-func quotes() {
- for i, l := range lines {
- lines[i] = codeQuotes(l)
- }
-}
-
-// quotes turns "x" in the line into <code>x</code>.
-func codeQuotes(l []byte) []byte {
- if bytes.HasPrefix(l, preStart) {
- return l
- }
- n := bytes.Index(l, quote)
- if n < 0 {
- return l
- }
- buf := new(bytes.Buffer)
- inQuote := false
- for _, c := range l {
- if c == '"' {
- if inQuote {
- buf.WriteString("</code>")
- } else {
- buf.WriteString("<code>")
- }
- inQuote = !inQuote
- } else {
- buf.WriteByte(c)
- }
- }
- return buf.Bytes()
-}
-
-// trim drops the trailing newline, if present.
-func trim(l []byte) []byte {
- n := len(l)
- if n > 0 && l[n-1] == '\n' {
- return l[0 : n-1]
- }
- return l
-}
-
-// expandTabs expands tabs to spaces. It doesn't worry about columns.
-func expandTabs(l []byte) []byte {
- return bytes.Replace(l, tab, indent, -1)
-}
« no previous file with comments | « doc/go_tutorial.txt ('k') | doc/makehtml » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b