diff --git a/util/doc.go b/util/doc.go index 48d65eb3..ce7a3e80 100644 --- a/util/doc.go +++ b/util/doc.go @@ -42,6 +42,8 @@ type HeaderFile struct { // is a separate paragraph. Preamble []string Sections []HeaderSection + // AllDecls maps all decls to their URL fragments. + AllDecls map[string]string } type HeaderSection struct { @@ -282,7 +284,8 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) { lines = lines[2:] header := &HeaderFile{ - Name: filepath.Base(path), + Name: filepath.Base(path), + AllDecls: make(map[string]string), } for i, line := range lines { @@ -391,6 +394,8 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) { // duplicate table-of-contents entries. allAnchors[anchor] = struct{}{} + header.AllDecls[name] = anchor + section.Decls = append(section.Decls, HeaderDecl{ Comment: comment, Name: name, @@ -426,7 +431,7 @@ func firstSentence(paragraphs []string) string { return s } -func markupPipeWords(s string) template.HTML { +func markupPipeWords(allDecls map[string]string, s string) template.HTML { ret := "" for { @@ -442,7 +447,14 @@ func markupPipeWords(s string) template.HTML { j := strings.Index(s, " ") if i > 0 && (j == -1 || j > i) { ret += "" + anchor, isLink := allDecls[s[:i]] + if isLink { + ret += fmt.Sprintf("", template.HTMLEscapeString(anchor)) + } ret += s[:i] + if isLink { + ret += "" + } ret += "" s = s[i+1:] } else { @@ -460,6 +472,11 @@ again: if end > 0 { end += start w := strings.ToLower(string(s[start:end])) + // The first word was already marked up as an HTML tag. Don't + // mark it up further. + if strings.ContainsRune(w, '<') { + return s + } if w == "a" || w == "an" { start = end + 1 goto again @@ -480,10 +497,12 @@ func newlinesToBR(html template.HTML) template.HTML { } func generate(outPath string, config *Config) (map[string]string, error) { + allDecls := make(map[string]string) + headerTmpl := template.New("headerTmpl") headerTmpl.Funcs(template.FuncMap{ "firstSentence": firstSentence, - "markupPipeWords": markupPipeWords, + "markupPipeWords": func(s string) template.HTML { return markupPipeWords(allDecls, s) }, "markupFirstWord": markupFirstWord, "newlinesToBR": newlinesToBR, }) @@ -514,23 +533,19 @@ func generate(outPath string, config *Config) (map[string]string, error) { {{range .Sections}} {{if not .IsPrivate}} -