package markup
import (
"bytes"
"regexp"
)
// brLine is a line holding nothing but a line break tag.
var brLine = regexp.MustCompile(`(?i)^[ \t]*<br[ \t]*/?>[ \t]*$`)
// separateBreaks ends the block at a line that is only <br>. Fossil's
// markdown reads such a line as a paragraph of its own, so the heading
// a forum post writes right under it is a heading. CommonMark opens an
// HTML block there instead, which runs to the next blank line and
// swallows the heading as text. A blank line after the <br> gives the
// fossil reading. Code fences are left as they are.
func separateBreaks(src []byte) []byte {
if !bytes.Contains(bytes.ToLower(src), []byte("<br")) {
return src
}
lines := bytes.SplitAfter(src, []byte("\n"))
var out bytes.Buffer
fence := ""
for i, l := range lines {
out.Write(l)
t := bytes.TrimLeft(l, " ")
switch {
case fence != "":
if bytes.HasPrefix(t, []byte(fence)) {
fence = ""
}
continue
case bytes.HasPrefix(t, []byte("```")):
fence = "```"
continue
case bytes.HasPrefix(t, []byte("~~~")):
fence = "~~~"
continue
}
if brLine.Match(bytes.TrimRight(l, "\r\n")) && i+1 < len(lines) &&
len(bytes.TrimSpace(lines[i+1])) > 0 {
if !bytes.HasSuffix(l, []byte("\n")) {
out.WriteByte('\n')
}
out.WriteByte('\n')
}
}
return out.Bytes()
}