package main import ( "bytes" "regexp" ) var sectionHeadingRe = regexp.MustCompile(`(?m)^#{1,6} `) // splitSections splits raw markdown into sections. // Section 0 is any content before the first heading. // Each subsequent section begins at a heading line and runs to the next. func splitSections(raw []byte) [][]byte { locs := sectionHeadingRe.FindAllIndex(raw, -1) if len(locs) == 0 { return [][]byte{raw} } sections := make([][]byte, 0, len(locs)+1) prev := 0 for _, loc := range locs { sections = append(sections, raw[prev:loc[0]]) prev = loc[0] } sections = append(sections, raw[prev:]) return sections } // joinSections reassembles sections produced by splitSections. // Inserts a newline between sections when a non-empty section lacks a // trailing newline, so an edited section cannot inline the next heading. func joinSections(sections [][]byte) []byte { var buf bytes.Buffer for i, s := range sections { buf.Write(s) if i < len(sections)-1 && len(s) > 0 && s[len(s)-1] != '\n' { buf.WriteByte('\n') } } return buf.Bytes() }