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>
diff --git a/util/doc.go b/util/doc.go
index 48d65eb..ce7a3e8 100644
--- a/util/doc.go
+++ b/util/doc.go
@@ -42,6 +42,8 @@
// 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 @@
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 @@
// 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 @@
return s
}
-func markupPipeWords(s string) template.HTML {
+func markupPipeWords(allDecls map[string]string, s string) template.HTML {
ret := ""
for {
@@ -442,7 +447,14 @@
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 @@
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 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 @@
{{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 @@
}
headerDescriptions := make(map[string]string)
+ var headers []*HeaderFile
for _, section := range config.Sections {
for _, headerPath := range section.Headers {
@@ -552,15 +568,23 @@
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)
+ headers = append(headers, header)
+
+ for name, anchor := range header.AllDecls {
+ allDecls[name] = fmt.Sprintf("%s#%s", header.Name+".html", anchor)
}
- defer file.Close()
- if err := headerTmpl.Execute(file, header); err != nil {
- return nil, err
- }
+ }
+ }
+
+ 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
}
}