diff --git a/mdproc/hugo_test.go b/mdproc/hugo_test.go index 04fe2ea..0c9cc78 100644 --- a/mdproc/hugo_test.go +++ b/mdproc/hugo_test.go @@ -17,6 +17,13 @@ categories: [a,b] + + > this is a quote @@ -37,7 +44,7 @@ this is multi line code ` + "```" + ` -and +and this is code too` @@ -45,6 +52,10 @@ and + + > this is a quote *not a list* @@ -63,7 +74,7 @@ this is multi line code ` + "```" + ` -and +and ` + "```" + ` this is code too diff --git a/mdproc/preproc.go b/mdproc/preproc.go index 97a9b08..2f102f3 100644 --- a/mdproc/preproc.go +++ b/mdproc/preproc.go @@ -18,8 +18,9 @@ type fsm struct { out chan pipe.StreamItem // combining multiple input lines - blockBuffer []byte - sendBuffer []byte + multiLineBlockMode bool + blockBuffer []byte + sendBuffer []byte // if we have a termination rule to abide, e.g. implied code fences pending []byte } @@ -43,7 +44,7 @@ func (m *fsm) pipeline(in chan pipe.StreamItem) chan pipe.StreamItem { continue } - m.state = m.state(m, b.Payload()) + m.state = m.state(wrap(m, b.Payload())) m.sync() } }() @@ -51,6 +52,16 @@ func (m *fsm) pipeline(in chan pipe.StreamItem) chan pipe.StreamItem { return m.out } +func wrap(m *fsm, data []byte) (*fsm, []byte) { + if hasCommentStart(data) { + m.multiLineBlockMode = true + } + if hasCommentEnd(data) { + m.multiLineBlockMode = false + } + return m, data +} + func (m *fsm) sync() { if len(m.sendBuffer) > 0 { m.sendBuffer = append(m.sendBuffer, '\n') @@ -60,6 +71,13 @@ func (m *fsm) sync() { } } +func (m *fsm) softBlockFlush() { + if m.multiLineBlockMode { + return + } + m.blockFlush() +} + func (m *fsm) blockFlush() { // blockBuffer to sendbuffer m.sendBuffer = append(m.sendBuffer, m.blockBuffer...) @@ -114,6 +132,14 @@ func needsFence(data []byte) bool { return len(data) >= 4 && string(data[0:4]) == " " } +func hasCommentStart(data []byte) bool { + return bytes.Contains(data, []byte("")) +} + func normalText(m *fsm, data []byte) stateFn { if len(bytes.TrimSpace(data)) == 0 { return normal @@ -121,7 +147,7 @@ func normalText(m *fsm, data []byte) stateFn { if data, isList := handleList(data); isList { m.blockBuffer = append(m.blockBuffer, data...) - m.blockFlush() + m.softBlockFlush() return list } @@ -148,7 +174,7 @@ func normalText(m *fsm, data []byte) stateFn { } m.blockBuffer = append(m.blockBuffer, append(data, '\n')...) - m.blockFlush() + m.softBlockFlush() return normal } @@ -164,7 +190,7 @@ func list(m *fsm, data []byte) stateFn { return list } - m.blockFlush() + m.softBlockFlush() return normalText(m, data) } @@ -173,7 +199,7 @@ func fence(m *fsm, data []byte) stateFn { m.blockBuffer = append(m.blockBuffer, append(data, '\n')...) // second fence returns to normal if isFence(data) { - m.blockFlush() + m.softBlockFlush() return normal } @@ -189,7 +215,7 @@ func toFence(m *fsm, data []byte) stateFn { return toFence } - m.blockFlush() + m.softBlockFlush() return normalText(m, data) } @@ -200,7 +226,7 @@ func paragraph(m *fsm, data []byte) stateFn { m.blockBuffer = bytes.TrimSpace(m.blockBuffer) // TODO, remove double spaces inside paragraphs m.blockBuffer = append(m.blockBuffer, '\n') - m.blockFlush() + m.softBlockFlush() return normal }