Generate stable URL fragments.
Using numbers is sensitive to moving things around. Instead, use the names and enforce, for sections, that they are unique. Names would be enforced too, but there's a table-of-contents bug around #ifdefs to resolve first. Change-Id: I8822e8ba8da9ed3ee4984365b8a64932d16d5baf Reviewed-on: https://boringssl-review.googlesource.com/5826 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
7e40d4e584
commit
1bfce80b44
48
util/doc.go
48
util/doc.go
@ -48,9 +48,8 @@ type HeaderSection struct {
|
|||||||
// Preamble contains a comment for a group of functions.
|
// Preamble contains a comment for a group of functions.
|
||||||
Preamble []string
|
Preamble []string
|
||||||
Decls []HeaderDecl
|
Decls []HeaderDecl
|
||||||
// Num is just the index of the section. It's included in order to help
|
// Anchor, if non-empty, is the URL fragment to use in anchor tags.
|
||||||
// text/template generate anchors.
|
Anchor string
|
||||||
Num int
|
|
||||||
// IsPrivate is true if the section contains private functions (as
|
// IsPrivate is true if the section contains private functions (as
|
||||||
// indicated by its name).
|
// indicated by its name).
|
||||||
IsPrivate bool
|
IsPrivate bool
|
||||||
@ -65,10 +64,8 @@ type HeaderDecl struct {
|
|||||||
Name string
|
Name string
|
||||||
// Decl contains the preformatted C declaration itself.
|
// Decl contains the preformatted C declaration itself.
|
||||||
Decl string
|
Decl string
|
||||||
// Num is an index for the declaration, but the value is unique for all
|
// Anchor, if non-empty, is the URL fragment to use in anchor tags.
|
||||||
// declarations in a HeaderFile. It's included in order to help
|
Anchor string
|
||||||
// text/template generate anchors.
|
|
||||||
Num int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -243,6 +240,10 @@ func getNameFromDecl(decl string) (string, bool) {
|
|||||||
return decl[j+1 : i], true
|
return decl[j+1 : i], true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sanitizeAnchor(name string) string {
|
||||||
|
return strings.Replace(name, " ", "-", -1)
|
||||||
|
}
|
||||||
|
|
||||||
func (config *Config) parseHeader(path string) (*HeaderFile, error) {
|
func (config *Config) parseHeader(path string) (*HeaderFile, error) {
|
||||||
headerPath := filepath.Join(config.BaseDirectory, path)
|
headerPath := filepath.Join(config.BaseDirectory, path)
|
||||||
|
|
||||||
@ -314,7 +315,7 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var sectionNumber, declNumber int
|
allAnchors := make(map[string]struct{})
|
||||||
|
|
||||||
for {
|
for {
|
||||||
// Start of a section.
|
// Start of a section.
|
||||||
@ -330,10 +331,7 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
|
|||||||
return nil, fmt.Errorf("blank line at start of section on line %d", lineNo)
|
return nil, fmt.Errorf("blank line at start of section on line %d", lineNo)
|
||||||
}
|
}
|
||||||
|
|
||||||
section := HeaderSection{
|
var section HeaderSection
|
||||||
Num: sectionNumber,
|
|
||||||
}
|
|
||||||
sectionNumber++
|
|
||||||
|
|
||||||
if strings.HasPrefix(line, commentStart) {
|
if strings.HasPrefix(line, commentStart) {
|
||||||
comment, rest, restLineNo, err := extractComment(lines, lineNo)
|
comment, rest, restLineNo, err := extractComment(lines, lineNo)
|
||||||
@ -341,8 +339,17 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(rest) > 0 && len(rest[0]) == 0 {
|
if len(rest) > 0 && len(rest[0]) == 0 {
|
||||||
|
anchor := sanitizeAnchor(firstSentence(comment))
|
||||||
|
if len(anchor) > 0 {
|
||||||
|
if _, ok := allAnchors[anchor]; ok {
|
||||||
|
return nil, fmt.Errorf("duplicate anchor: %s", anchor)
|
||||||
|
}
|
||||||
|
allAnchors[anchor] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
section.Preamble = comment
|
section.Preamble = comment
|
||||||
section.IsPrivate = len(comment) > 0 && strings.HasPrefix(comment[0], "Private functions")
|
section.IsPrivate = len(comment) > 0 && strings.HasPrefix(comment[0], "Private functions")
|
||||||
|
section.Anchor = anchor
|
||||||
lines = rest[1:]
|
lines = rest[1:]
|
||||||
lineNo = restLineNo + 1
|
lineNo = restLineNo + 1
|
||||||
}
|
}
|
||||||
@ -381,13 +388,18 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
|
|||||||
if last := len(section.Decls) - 1; len(name) == 0 && len(comment) == 0 && last >= 0 {
|
if last := len(section.Decls) - 1; len(name) == 0 && len(comment) == 0 && last >= 0 {
|
||||||
section.Decls[last].Decl += "\n" + decl
|
section.Decls[last].Decl += "\n" + decl
|
||||||
} else {
|
} else {
|
||||||
|
anchor := sanitizeAnchor(name)
|
||||||
|
// TODO(davidben): Enforce uniqueness. This is
|
||||||
|
// skipped because #ifdefs currently result in
|
||||||
|
// duplicate table-of-contents entries.
|
||||||
|
allAnchors[anchor] = struct{}{}
|
||||||
|
|
||||||
section.Decls = append(section.Decls, HeaderDecl{
|
section.Decls = append(section.Decls, HeaderDecl{
|
||||||
Comment: comment,
|
Comment: comment,
|
||||||
Name: name,
|
Name: name,
|
||||||
Decl: decl,
|
Decl: decl,
|
||||||
Num: declNumber,
|
Anchor: anchor,
|
||||||
})
|
})
|
||||||
declNumber++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(lines) > 0 && len(lines[0]) == 0 {
|
if len(lines) > 0 && len(lines[0]) == 0 {
|
||||||
@ -495,9 +507,9 @@ func generate(outPath string, config *Config) (map[string]string, error) {
|
|||||||
<ol>
|
<ol>
|
||||||
{{range .Sections}}
|
{{range .Sections}}
|
||||||
{{if not .IsPrivate}}
|
{{if not .IsPrivate}}
|
||||||
{{if .Preamble}}<li class="header"><a href="#section-{{.Num}}">{{.Preamble | firstSentence | html | markupPipeWords}}</a></li>{{end}}
|
{{if .Anchor}}<li class="header"><a href="#{{.Anchor}}">{{.Preamble | firstSentence | html | markupPipeWords}}</a></li>{{end}}
|
||||||
{{range .Decls}}
|
{{range .Decls}}
|
||||||
{{if .Name}}<li><a href="#decl-{{.Num}}"><tt>{{.Name}}</tt></a></li>{{end}}
|
{{if .Anchor}}<li><a href="#{{.Anchor}}"><tt>{{.Name}}</tt></a></li>{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
@ -508,7 +520,7 @@ func generate(outPath string, config *Config) (map[string]string, error) {
|
|||||||
<div class="section">
|
<div class="section">
|
||||||
{{if .Preamble}}
|
{{if .Preamble}}
|
||||||
<div class="sectionpreamble">
|
<div class="sectionpreamble">
|
||||||
<a name="section-{{.Num}}">
|
<a{{if .Anchor}} name="{{.Anchor}}"{{end}}>
|
||||||
{{range .Preamble}}<p>{{. | html | markupPipeWords}}</p>{{end}}
|
{{range .Preamble}}<p>{{. | html | markupPipeWords}}</p>{{end}}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -516,7 +528,7 @@ func generate(outPath string, config *Config) (map[string]string, error) {
|
|||||||
|
|
||||||
{{range .Decls}}
|
{{range .Decls}}
|
||||||
<div class="decl">
|
<div class="decl">
|
||||||
<a name="decl-{{.Num}}">
|
<a{{if .Anchor}} name="{{.Anchor}}"{{end}}>
|
||||||
{{range .Comment}}
|
{{range .Comment}}
|
||||||
<p>{{. | html | markupPipeWords | newlinesToBR | markupFirstWord}}</p>
|
<p>{{. | html | markupPipeWords | newlinesToBR | markupFirstWord}}</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
Loading…
Reference in New Issue
Block a user