Add a munger for header lines
This commit is contained in:
71
cmd/mungedocs/headers.go
Normal file
71
cmd/mungedocs/headers.go
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var headerRegex = regexp.MustCompile(`^(#+)\s*(.*)$`)
|
||||||
|
var whitespaceRegex = regexp.MustCompile(`^\s*$`)
|
||||||
|
|
||||||
|
func fixHeaderLines(fileBytes []byte) []byte {
|
||||||
|
lines := splitLines(fileBytes)
|
||||||
|
out := []string{}
|
||||||
|
for i := range lines {
|
||||||
|
matches := headerRegex.FindStringSubmatch(lines[i])
|
||||||
|
if matches == nil {
|
||||||
|
out = append(out, lines[i])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if i > 0 && !whitespaceRegex.Match([]byte(out[len(out)-1])) {
|
||||||
|
out = append(out, "")
|
||||||
|
}
|
||||||
|
out = append(out, fmt.Sprintf("%s %s", matches[1], matches[2]))
|
||||||
|
if i+1 < len(lines) && !whitespaceRegex.Match([]byte(lines[i+1])) {
|
||||||
|
out = append(out, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final := strings.Join(out, "\n")
|
||||||
|
// Preserve the end of the file.
|
||||||
|
if len(fileBytes) > 0 && fileBytes[len(fileBytes)-1] == '\n' {
|
||||||
|
final += "\n"
|
||||||
|
}
|
||||||
|
return []byte(final)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Header lines need whitespace around them and after the #s.
|
||||||
|
func checkHeaderLines(filePath string, fileBytes []byte) ([]byte, error) {
|
||||||
|
fbs := splitByPreformatted(fileBytes)
|
||||||
|
fbs = append([]fileBlock{{false, []byte{}}}, fbs...)
|
||||||
|
fbs = append(fbs, fileBlock{false, []byte{}})
|
||||||
|
|
||||||
|
for i := range fbs {
|
||||||
|
block := &fbs[i]
|
||||||
|
if block.preformatted {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
block.data = fixHeaderLines(block.data)
|
||||||
|
}
|
||||||
|
output := []byte{}
|
||||||
|
for _, block := range fbs {
|
||||||
|
output = append(output, block.data...)
|
||||||
|
}
|
||||||
|
return output, nil
|
||||||
|
}
|
||||||
71
cmd/mungedocs/headers_test.go
Normal file
71
cmd/mungedocs/headers_test.go
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHeaderLines(t *testing.T) {
|
||||||
|
var cases = []struct {
|
||||||
|
in string
|
||||||
|
out string
|
||||||
|
}{
|
||||||
|
{"", ""},
|
||||||
|
{
|
||||||
|
"# ok",
|
||||||
|
"# ok",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"## ok",
|
||||||
|
"## ok",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"##### ok",
|
||||||
|
"##### ok",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"##fix",
|
||||||
|
"## fix",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"foo\n\n##fix\n\nbar",
|
||||||
|
"foo\n\n## fix\n\nbar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"foo\n##fix\nbar",
|
||||||
|
"foo\n\n## fix\n\nbar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"foo\n```\n##fix\n```\nbar",
|
||||||
|
"foo\n```\n##fix\n```\nbar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"foo\n#fix1\n##fix2\nbar",
|
||||||
|
"foo\n\n# fix1\n\n## fix2\n\nbar",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i, c := range cases {
|
||||||
|
actual, err := checkHeaderLines("filename.md", []byte(c.in))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if string(actual) != c.out {
|
||||||
|
t.Errorf("case[%d]: expected %q got %q", i, c.out, string(actual))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,6 +48,7 @@ Examples:
|
|||||||
{"table-of-contents", updateTOC},
|
{"table-of-contents", updateTOC},
|
||||||
{"check-links", checkLinks},
|
{"check-links", checkLinks},
|
||||||
{"blank-lines-surround-preformatted", checkPreformatted},
|
{"blank-lines-surround-preformatted", checkPreformatted},
|
||||||
|
{"header-lines", checkHeaderLines},
|
||||||
{"unversioned-warning", updateUnversionedWarning},
|
{"unversioned-warning", updateUnversionedWarning},
|
||||||
{"analytics", checkAnalytics},
|
{"analytics", checkAnalytics},
|
||||||
{"kubectl-dash-f", checkKubectlFileTargets},
|
{"kubectl-dash-f", checkKubectlFileTargets},
|
||||||
|
|||||||
Reference in New Issue
Block a user