mirror of
https://github.com/golang/go
synced 2024-11-25 11:07:59 -07:00
go/doc: switch ToHTML from []byte to string argument
- this removes extra conversions from strings to bytes and vice versa for each comment - minor cleanups R=golang-dev, rsc CC=golang-dev https://golang.org/cl/5434096
This commit is contained in:
parent
158ca3c47e
commit
e281576b9a
@ -456,7 +456,7 @@ func comment_htmlFunc(comment string) string {
|
|||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
// TODO(gri) Provide list of words (e.g. function parameters)
|
// TODO(gri) Provide list of words (e.g. function parameters)
|
||||||
// to be emphasized by ToHTML.
|
// to be emphasized by ToHTML.
|
||||||
doc.ToHTML(&buf, []byte(comment), nil) // does html-escaping
|
doc.ToHTML(&buf, comment, nil) // does html-escaping
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
package doc
|
package doc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -85,39 +84,6 @@ func CommentText(comment *ast.CommentGroup) string {
|
|||||||
return strings.Join(lines, "\n")
|
return strings.Join(lines, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split bytes into lines.
|
|
||||||
func split(text []byte) [][]byte {
|
|
||||||
// count lines
|
|
||||||
n := 0
|
|
||||||
last := 0
|
|
||||||
for i, c := range text {
|
|
||||||
if c == '\n' {
|
|
||||||
last = i + 1
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if last < len(text) {
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
|
|
||||||
// split
|
|
||||||
out := make([][]byte, n)
|
|
||||||
last = 0
|
|
||||||
n = 0
|
|
||||||
for i, c := range text {
|
|
||||||
if c == '\n' {
|
|
||||||
out[n] = text[last : i+1]
|
|
||||||
last = i + 1
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if last < len(text) {
|
|
||||||
out[n] = text[last:]
|
|
||||||
}
|
|
||||||
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ldquo = []byte("“")
|
ldquo = []byte("“")
|
||||||
rdquo = []byte("”")
|
rdquo = []byte("”")
|
||||||
@ -125,13 +91,13 @@ var (
|
|||||||
|
|
||||||
// Escape comment text for HTML. If nice is set,
|
// Escape comment text for HTML. If nice is set,
|
||||||
// also turn `` into “ and '' into ”.
|
// also turn `` into “ and '' into ”.
|
||||||
func commentEscape(w io.Writer, s []byte, nice bool) {
|
func commentEscape(w io.Writer, text string, nice bool) {
|
||||||
last := 0
|
last := 0
|
||||||
if nice {
|
if nice {
|
||||||
for i := 0; i < len(s)-1; i++ {
|
for i := 0; i < len(text)-1; i++ {
|
||||||
ch := s[i]
|
ch := text[i]
|
||||||
if ch == s[i+1] && (ch == '`' || ch == '\'') {
|
if ch == text[i+1] && (ch == '`' || ch == '\'') {
|
||||||
template.HTMLEscape(w, s[last:i])
|
template.HTMLEscape(w, []byte(text[last:i]))
|
||||||
last = i + 2
|
last = i + 2
|
||||||
switch ch {
|
switch ch {
|
||||||
case '`':
|
case '`':
|
||||||
@ -143,7 +109,7 @@ func commentEscape(w io.Writer, s []byte, nice bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template.HTMLEscape(w, s[last:])
|
template.HTMLEscape(w, []byte(text[last:]))
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -183,9 +149,9 @@ var (
|
|||||||
// and the word is converted into a link. If nice is set, the remaining text's
|
// 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 “
|
// appearance is improved where it makes sense (e.g., `` is turned into “
|
||||||
// and '' into ”).
|
// and '' into ”).
|
||||||
func emphasize(w io.Writer, line []byte, words map[string]string, nice bool) {
|
func emphasize(w io.Writer, line string, words map[string]string, nice bool) {
|
||||||
for {
|
for {
|
||||||
m := matchRx.FindSubmatchIndex(line)
|
m := matchRx.FindStringSubmatchIndex(line)
|
||||||
if m == nil {
|
if m == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -233,7 +199,7 @@ func emphasize(w io.Writer, line []byte, words map[string]string, nice bool) {
|
|||||||
commentEscape(w, line, nice)
|
commentEscape(w, line, nice)
|
||||||
}
|
}
|
||||||
|
|
||||||
func indentLen(s []byte) int {
|
func indentLen(s string) int {
|
||||||
i := 0
|
i := 0
|
||||||
for i < len(s) && (s[i] == ' ' || s[i] == '\t') {
|
for i < len(s) && (s[i] == ' ' || s[i] == '\t') {
|
||||||
i++
|
i++
|
||||||
@ -241,9 +207,11 @@ func indentLen(s []byte) int {
|
|||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
func isBlank(s []byte) bool { return len(s) == 0 || (len(s) == 1 && s[0] == '\n') }
|
func isBlank(s string) bool {
|
||||||
|
return len(s) == 0 || (len(s) == 1 && s[0] == '\n')
|
||||||
|
}
|
||||||
|
|
||||||
func commonPrefix(a, b []byte) []byte {
|
func commonPrefix(a, b string) string {
|
||||||
i := 0
|
i := 0
|
||||||
for i < len(a) && i < len(b) && a[i] == b[i] {
|
for i < len(a) && i < len(b) && a[i] == b[i] {
|
||||||
i++
|
i++
|
||||||
@ -251,7 +219,7 @@ func commonPrefix(a, b []byte) []byte {
|
|||||||
return a[0:i]
|
return a[0:i]
|
||||||
}
|
}
|
||||||
|
|
||||||
func unindent(block [][]byte) {
|
func unindent(block []string) {
|
||||||
if len(block) == 0 {
|
if len(block) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -274,23 +242,23 @@ func unindent(block [][]byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// heading returns the (possibly trimmed) line if it passes as a valid section
|
// heading returns the (possibly trimmed) line if it passes as a valid section
|
||||||
// heading; otherwise it returns nil.
|
// heading; otherwise it returns the empty string.
|
||||||
func heading(line []byte) []byte {
|
func heading(line string) string {
|
||||||
line = bytes.TrimSpace(line)
|
line = strings.TrimSpace(line)
|
||||||
if len(line) == 0 {
|
if len(line) == 0 {
|
||||||
return nil
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// a heading must start with an uppercase letter
|
// a heading must start with an uppercase letter
|
||||||
r, _ := utf8.DecodeRune(line)
|
r, _ := utf8.DecodeRuneInString(line)
|
||||||
if !unicode.IsLetter(r) || !unicode.IsUpper(r) {
|
if !unicode.IsLetter(r) || !unicode.IsUpper(r) {
|
||||||
return nil
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// it must end in a letter, digit or ':'
|
// it must end in a letter, digit or ':'
|
||||||
r, _ = utf8.DecodeLastRune(line)
|
r, _ = utf8.DecodeLastRuneInString(line)
|
||||||
if !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != ':' {
|
if !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != ':' {
|
||||||
return nil
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// strip trailing ':', if any
|
// strip trailing ':', if any
|
||||||
@ -299,18 +267,18 @@ func heading(line []byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// exclude lines with illegal characters
|
// exclude lines with illegal characters
|
||||||
if bytes.IndexAny(line, ",.;:!?+*/=()[]{}_^°&§~%#@<\">\\") >= 0 {
|
if strings.IndexAny(line, ",.;:!?+*/=()[]{}_^°&§~%#@<\">\\") >= 0 {
|
||||||
return nil
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// allow "'" for possessive "'s" only
|
// allow "'" for possessive "'s" only
|
||||||
for b := line; ; {
|
for b := line; ; {
|
||||||
i := bytes.IndexRune(b, '\'')
|
i := strings.IndexRune(b, '\'')
|
||||||
if i < 0 {
|
if i < 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if i+1 >= len(b) || b[i+1] != 's' || (i+2 < len(b) && b[i+2] != ' ') {
|
if i+1 >= len(b) || b[i+1] != 's' || (i+2 < len(b) && b[i+2] != ' ') {
|
||||||
return nil // not followed by "s "
|
return "" // not followed by "s "
|
||||||
}
|
}
|
||||||
b = b[i+2:]
|
b = b[i+2:]
|
||||||
}
|
}
|
||||||
@ -335,7 +303,7 @@ func heading(line []byte) []byte {
|
|||||||
// Go identifiers that appear in the words map are italicized; if the corresponding
|
// 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
|
// map value is not the empty string, it is considered a URL and the word is converted
|
||||||
// into a link.
|
// into a link.
|
||||||
func ToHTML(w io.Writer, s []byte, words map[string]string) {
|
func ToHTML(w io.Writer, text string, words map[string]string) {
|
||||||
inpara := false
|
inpara := false
|
||||||
lastWasBlank := false
|
lastWasBlank := false
|
||||||
lastWasHeading := false
|
lastWasHeading := false
|
||||||
@ -353,7 +321,7 @@ func ToHTML(w io.Writer, s []byte, words map[string]string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lines := split(s)
|
lines := strings.SplitAfter(text, "\n")
|
||||||
unindent(lines)
|
unindent(lines)
|
||||||
for i := 0; i < len(lines); {
|
for i := 0; i < len(lines); {
|
||||||
line := lines[i]
|
line := lines[i]
|
||||||
@ -397,10 +365,10 @@ func ToHTML(w io.Writer, s []byte, words map[string]string) {
|
|||||||
// current line is non-blank, sourounded by blank lines
|
// current line is non-blank, sourounded by blank lines
|
||||||
// and the next non-blank line is not indented: this
|
// and the next non-blank line is not indented: this
|
||||||
// might be a heading.
|
// might be a heading.
|
||||||
if head := heading(line); head != nil {
|
if head := heading(line); head != "" {
|
||||||
close()
|
close()
|
||||||
w.Write(html_h)
|
w.Write(html_h)
|
||||||
template.HTMLEscape(w, head)
|
commentEscape(w, head, true) // nice text formatting
|
||||||
w.Write(html_endh)
|
w.Write(html_endh)
|
||||||
i += 2
|
i += 2
|
||||||
lastWasHeading = true
|
lastWasHeading = true
|
||||||
|
@ -32,7 +32,7 @@ var headingTests = []struct {
|
|||||||
|
|
||||||
func TestIsHeading(t *testing.T) {
|
func TestIsHeading(t *testing.T) {
|
||||||
for _, tt := range headingTests {
|
for _, tt := range headingTests {
|
||||||
if h := heading([]byte(tt.line)); (h != nil) != tt.ok {
|
if h := heading(tt.line); (len(h) > 0) != tt.ok {
|
||||||
t.Errorf("isHeading(%q) = %v, want %v", tt.line, h, tt.ok)
|
t.Errorf("isHeading(%q) = %v, want %v", tt.line, h, tt.ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ func isGoFile(fi os.FileInfo) bool {
|
|||||||
|
|
||||||
func appendHeadings(list []string, comment string) []string {
|
func appendHeadings(list []string, comment string) []string {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
doc.ToHTML(&buf, []byte(comment), nil)
|
doc.ToHTML(&buf, comment, nil)
|
||||||
for s := buf.String(); ; {
|
for s := buf.String(); ; {
|
||||||
i := strings.Index(s, html_h)
|
i := strings.Index(s, html_h)
|
||||||
if i < 0 {
|
if i < 0 {
|
||||||
|
Loading…
Reference in New Issue
Block a user