diff options
Diffstat (limited to 'src/pkg/go/doc/comment.go')
-rw-r--r-- | src/pkg/go/doc/comment.go | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/src/pkg/go/doc/comment.go b/src/pkg/go/doc/comment.go index 5c8c43e0c..f414ca409 100644 --- a/src/pkg/go/doc/comment.go +++ b/src/pkg/go/doc/comment.go @@ -45,13 +45,13 @@ func commentEscape(w io.Writer, text string, nice bool) { const ( // Regexp for Go identifiers - identRx = `[a-zA-Z_][a-zA-Z_0-9]*` // TODO(gri) ASCII only for now - fix this + identRx = `[\pL_][\pL_0-9]*` // Regexp for URLs - protocol = `(https?|ftp|file|gopher|mailto|news|nntp|telnet|wais|prospero):` + protocol = `https?|ftp|file|gopher|mailto|news|nntp|telnet|wais|prospero` hostPart = `[a-zA-Z0-9_@\-]+` - filePart = `[a-zA-Z0-9_?%#~&/\-+=]+` - urlRx = protocol + `//` + // http:// + filePart = `[a-zA-Z0-9_?%#~&/\-+=()]+` // parentheses may not be matching; see pairedParensPrefixLen + urlRx = `(` + protocol + `)://` + // http:// hostPart + `([.:]` + hostPart + `)*/?` + // //www.google.com:8080/ filePart + `([:.,]` + filePart + `)*` ) @@ -73,6 +73,29 @@ var ( html_endh = []byte("</h3>\n") ) +// pairedParensPrefixLen returns the length of the longest prefix of s containing paired parentheses. +func pairedParensPrefixLen(s string) int { + parens := 0 + l := len(s) + for i, ch := range s { + switch ch { + case '(': + if parens == 0 { + l = i + } + parens++ + case ')': + parens-- + if parens == 0 { + l = len(s) + } else if parens < 0 { + return i + } + } + } + return l +} + // 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 @@ -92,18 +115,26 @@ func emphasize(w io.Writer, line string, words map[string]string, nice bool) { // write text before match commentEscape(w, line[0:m[0]], nice) - // analyze match + // 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[string(match)] + 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 = string(match) + url = match } italics = false // don't italicize URLs } @@ -392,7 +423,9 @@ func ToText(w io.Writer, text string, indent, preIndent string, width int) { case opPre: w.Write(nl) for _, line := range b.lines { - if !isBlank(line) { + if isBlank(line) { + w.Write([]byte("\n")) + } else { w.Write([]byte(preIndent)) w.Write([]byte(line)) } |