summaryrefslogtreecommitdiff
path: root/src/cmd/godoc/format.go
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-02-14 13:23:51 +0100
committerOndřej Surý <ondrej@sury.org>2011-02-14 13:23:51 +0100
commit758ff64c69e34965f8af5b2d6ffd65e8d7ab2150 (patch)
tree6d6b34f8c678862fe9b56c945a7b63f68502c245 /src/cmd/godoc/format.go
parent3e45412327a2654a77944249962b3652e6142299 (diff)
downloadgolang-758ff64c69e34965f8af5b2d6ffd65e8d7ab2150.tar.gz
Imported Upstream version 2011-02-01.1upstream/2011-02-01.1
Diffstat (limited to 'src/cmd/godoc/format.go')
-rw-r--r--src/cmd/godoc/format.go68
1 files changed, 53 insertions, 15 deletions
diff --git a/src/cmd/godoc/format.go b/src/cmd/godoc/format.go
index f68c67b24..66b01aa64 100644
--- a/src/cmd/godoc/format.go
+++ b/src/cmd/godoc/format.go
@@ -62,12 +62,48 @@ func FormatSelections(w io.Writer, text []byte, lw LinkWriter, links Selection,
if lw != nil {
selections = append(selections, links)
}
+
// compute the sequence of consecutive segment changes
changes := newMerger(selections)
+
// The i'th bit in bitset indicates that the text
// at the current offset is covered by selections[i].
bitset := 0
lastOffs := 0
+
+ // Text segments are written in a delayed fashion
+ // such that consecutive segments belonging to the
+ // same selection can be combined (peephole optimization).
+ // last describes the last segment which has not yet been written.
+ var last struct {
+ begin, end int // valid if begin < end
+ bitset int
+ }
+
+ // flush writes the last delayed text segment
+ flush := func() {
+ if last.begin < last.end {
+ sw(w, text[last.begin:last.end], last.bitset)
+ }
+ last.begin = last.end // invalidate last
+ }
+
+ // segment runs the segment [lastOffs, end) with the selection
+ // indicated by bitset through the segment peephole optimizer.
+ segment := func(end int) {
+ if lastOffs < end { // ignore empty segments
+ if last.end != lastOffs || last.bitset != bitset {
+ // the last segment is not adjacent to or
+ // differs from the new one
+ flush()
+ // start a new segment
+ last.begin = lastOffs
+ }
+ last.end = end
+ last.bitset = bitset
+ }
+ }
+
for {
// get the next segment change
index, offs, start := changes.next()
@@ -81,14 +117,15 @@ func FormatSelections(w io.Writer, text []byte, lw LinkWriter, links Selection,
// we have a link segment change:
// format the previous selection segment, write the
// link tag and start a new selection segment
- sw(w, text[lastOffs:offs], bitset)
+ segment(offs)
+ flush()
lastOffs = offs
lw(w, offs, start)
} else {
// we have a selection change:
// format the previous selection segment, determine
// the new selection bitset and start a new segment
- sw(w, text[lastOffs:offs], bitset)
+ segment(offs)
lastOffs = offs
mask := 1 << uint(index)
if start {
@@ -98,7 +135,8 @@ func FormatSelections(w io.Writer, text []byte, lw LinkWriter, links Selection,
}
}
}
- sw(w, text[lastOffs:], bitset)
+ segment(len(text))
+ flush()
}
@@ -201,7 +239,9 @@ func lineSelection(text []byte) Selection {
//
func commentSelection(src []byte) Selection {
var s scanner.Scanner
- file := s.Init(token.NewFileSet(), "", src, nil, scanner.ScanComments+scanner.InsertSemis)
+ fset := token.NewFileSet()
+ file := fset.AddFile("", fset.Base(), len(src))
+ s.Init(file, src, nil, scanner.ScanComments+scanner.InsertSemis)
return func() (seg []int) {
for {
pos, tok, lit := s.Scan()
@@ -283,17 +323,15 @@ var endTag = []byte(`</span>`)
func selectionTag(w io.Writer, text []byte, selections int) {
- if len(text) > 0 {
- if selections < len(startTags) {
- if tag := startTags[selections]; len(tag) > 0 {
- w.Write(tag)
- template.HTMLEscape(w, text)
- w.Write(endTag)
- return
- }
+ 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)
}
+ template.HTMLEscape(w, text)
}
@@ -322,12 +360,12 @@ func FormatText(text []byte, line int, goSource bool, pattern string, selection
if pattern != "" {
highlights = regexpSelection(text, pattern)
}
- if comments != nil || highlights != nil || selection != nil {
+ 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>%5d\t", line, line)
+ fmt.Fprintf(w, "<a id=\"L%d\"></a><span class=\"ln\">%6d</span>\t", line, line)
line++
}
}