Skip to content

Commit fdfdde0

Browse files
committed
relnote: remove empty sections when merging
Remove sections that have no content from the merged document. For golang/go#64169. Change-Id: Ic78b1e2dc46d14dcf885cef8ce0e7dd4a257298a Reviewed-on: https://go-review.googlesource.com/c/build/+/556160 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
1 parent a383c72 commit fdfdde0

File tree

3 files changed

+112
-2
lines changed

3 files changed

+112
-2
lines changed

relnote/relnote.go

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,54 @@ func Merge(fsys fs.FS) (*md.Document, error) {
168168
addLines(b, delta)
169169
}
170170
}
171-
doc.Blocks = append(doc.Blocks, fd.Blocks...)
171+
// Append non-empty blocks to the result document.
172+
for _, b := range fd.Blocks {
173+
if _, ok := b.(*md.Empty); !ok {
174+
doc.Blocks = append(doc.Blocks, b)
175+
}
176+
}
172177
// TODO(jba): merge links
173178
// TODO(jba): add headings for package sections under "Minor changes to the library".
174179
}
175-
// TODO(jba): remove headings with empty contents
180+
// Remove headings with empty contents.
181+
doc.Blocks = removeEmptySections(doc.Blocks)
176182
return doc, nil
177183
}
178184

185+
// removeEmptySections removes headings with no content. A heading has no content
186+
// if there are no blocks between it and the next heading at the same level, or the
187+
// end of the document.
188+
func removeEmptySections(bs []md.Block) []md.Block {
189+
res := bs[:0]
190+
delta := 0 // number of lines by which to adjust positions
191+
192+
// Remove preceding headings at same or higher level; they are empty.
193+
rem := func(level int) {
194+
for len(res) > 0 {
195+
last := res[len(res)-1]
196+
if lh, ok := last.(*md.Heading); ok && lh.Level >= level {
197+
res = res[:len(res)-1]
198+
// Adjust subsequent block positions by the size of this block
199+
// plus 1 for the blank line between headings.
200+
delta += lh.EndLine - lh.StartLine + 2
201+
} else {
202+
break
203+
}
204+
}
205+
}
206+
207+
for _, b := range bs {
208+
if h, ok := b.(*md.Heading); ok {
209+
rem(h.Level)
210+
}
211+
addLines(b, -delta)
212+
res = append(res, b)
213+
}
214+
// Remove empty headings at the end of the document.
215+
rem(1)
216+
return res
217+
}
218+
179219
func sortedMarkdownFilenames(fsys fs.FS) ([]string, error) {
180220
var filenames []string
181221
err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
@@ -203,6 +243,8 @@ func lastBlock(doc *md.Document) md.Block {
203243
return doc.Blocks[len(doc.Blocks)-1]
204244
}
205245

246+
// addLines adds n lines to the position of b.
247+
// n can be negative.
206248
func addLines(b md.Block, n int) {
207249
pos := position(b)
208250
pos.StartLine += n
@@ -248,3 +290,14 @@ func parseFile(fsys fs.FS, path string) (*md.Document, error) {
248290
doc := NewParser().Parse(in)
249291
return doc, nil
250292
}
293+
294+
// headingIndex returns the index in bs of the first heading at the given level,
295+
// or len(bs) if there isn't one.
296+
func headingIndex(bs []md.Block, level int) int {
297+
for i, b := range bs {
298+
if h, ok := b.(*md.Heading); ok && h.Level == level {
299+
return i
300+
}
301+
}
302+
return len(bs)
303+
}

relnote/relnote_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,5 +144,44 @@ func TestSortedMarkdownFilenames(t *testing.T) {
144144
if !slices.Equal(got, want) {
145145
t.Errorf("\ngot %v\nwant %v", got, want)
146146
}
147+
}
148+
149+
func TestRemoveEmptySections(t *testing.T) {
150+
doc := NewParser().Parse(`
151+
# h1
152+
not empty
153+
154+
# h2
155+
156+
## h3
157+
158+
### h4
159+
160+
#### h5
161+
162+
### h6
147163
164+
### h7
165+
166+
## h8
167+
something
168+
169+
## h9
170+
171+
# h10
172+
`)
173+
bs := removeEmptySections(doc.Blocks)
174+
got := md.ToMarkdown(&md.Document{Blocks: bs})
175+
want := md.ToMarkdown(NewParser().Parse(`
176+
# h1
177+
not empty
178+
179+
# h2
180+
181+
## h8
182+
something
183+
`))
184+
if got != want {
185+
t.Errorf("\ngot:\n%s\nwant:\n%s", got, want)
186+
}
148187
}

relnote/testdata/empty.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-- 0-heading.md --
2+
# A heading
3+
-- a.md --
4+
## A
5+
-- b.md --
6+
## B
7+
Something.
8+
-- c.md --
9+
## C
10+
11+
### C1
12+
-- d.md --
13+
## D
14+
-- want --
15+
# A heading
16+
17+
## B
18+
Something.

0 commit comments

Comments
 (0)