diff options
author | David Benjamin <davidben@chromium.org> | 2015-10-18 08:08:11 +0300 |
---|---|---|
committer | Adam Langley <alangley@gmail.com> | 2015-10-26 21:46:53 +0300 |
commit | dfa9c4a07474a23fda0288035cf002c4ab26043e (patch) | |
tree | b33f3e33f5590424c7413f9805a942fcf7bfc9b4 /util | |
parent | 5ef619ef2add2183fc2a471e933d0277dc1f59e9 (diff) |
Linkify pipe words.
This required switching anchors from <a name> to id attributes, which
also works. HTML gets unhappy when you nest <a> tags inside each other
and tagging the elements is somewhat tidier.
Change-Id: I64094d35a0e820e37be9e5dc8db013a50774190f
Reviewed-on: https://boringssl-review.googlesource.com/6314
Reviewed-by: Adam Langley <alangley@gmail.com>
Diffstat (limited to 'util')
-rw-r--r-- | util/doc.go | 58 |
1 files changed, 41 insertions, 17 deletions
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 += "<tt>" + anchor, isLink := allDecls[s[:i]] + if isLink { + ret += fmt.Sprintf("<a href=\"%s\">", template.HTMLEscapeString(anchor)) + } ret += s[:i] + if isLink { + ret += "</a>" + } ret += "</tt>" 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}} - <div class="section"> + <div class="section" {{if .Anchor}}id="{{.Anchor}}"{{end}}> {{if .Preamble}} <div class="sectionpreamble"> - <a{{if .Anchor}} name="{{.Anchor}}"{{end}}> {{range .Preamble}}<p>{{. | html | markupPipeWords}}</p>{{end}} - </a> </div> {{end}} {{range .Decls}} - <div class="decl"> - <a{{if .Anchor}} name="{{.Anchor}}"{{end}}> + <div class="decl" {{if .Anchor}}id="{{.Anchor}}"{{end}}> {{range .Comment}} <p>{{. | html | markupPipeWords | newlinesToBR | markupFirstWord}}</p> {{end}} <pre>{{.Decl}}</pre> - </a> </div> {{end}} </div> @@ -544,6 +559,7 @@ func generate(outPath string, config *Config) (map[string]string, error) { } headerDescriptions := make(map[string]string) + var headers []*HeaderFile for _, section := range config.Sections { for _, headerPath := range section.Headers { @@ -552,18 +568,26 @@ func generate(outPath string, config *Config) (map[string]string, error) { return nil, errors.New("while parsing " + headerPath + ": " + err.Error()) } headerDescriptions[header.Name] = firstSentence(header.Preamble) - filename := filepath.Join(outPath, header.Name+".html") - file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) - if err != nil { - panic(err) - } - defer file.Close() - if err := headerTmpl.Execute(file, header); err != nil { - return nil, err + headers = append(headers, header) + + for name, anchor := range header.AllDecls { + allDecls[name] = fmt.Sprintf("%s#%s", header.Name+".html", anchor) } } } + for _, header := range headers { + filename := filepath.Join(outPath, header.Name+".html") + file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) + if err != nil { + panic(err) + } + defer file.Close() + if err := headerTmpl.Execute(file, header); err != nil { + return nil, err + } + } + return headerDescriptions, nil } |