1// Copyright 2021 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package markdown 6 7import ( 8 "bytes" 9) 10 11type ThematicBreak struct { 12 Position 13 raw string 14} 15 16func (b *ThematicBreak) PrintHTML(buf *bytes.Buffer) { 17 buf.WriteString("<hr />\n") 18} 19 20func (b *ThematicBreak) printMarkdown(buf *bytes.Buffer, s mdState) { 21 buf.WriteString(s.prefix) 22 buf.WriteString(b.raw) 23 buf.WriteByte('\n') 24} 25 26func newHR(p *parseState, s line) (line, bool) { 27 if isHR(s) { 28 p.doneBlock(&ThematicBreak{Position{p.lineno, p.lineno}, s.string()}) 29 return line{}, true 30 } 31 return s, false 32} 33 34func isHR(s line) bool { 35 t := s 36 t.trimSpace(0, 3, false) 37 switch c := t.peek(); c { 38 case '-', '_', '*': 39 for i := 0; ; i++ { 40 if !t.trim(c) { 41 if i >= 3 { 42 break 43 } 44 return false 45 } 46 t.skipSpace() 47 } 48 return t.eof() 49 } 50 return false 51} 52 53type HardBreak struct{} 54 55func (*HardBreak) Inline() {} 56 57func (x *HardBreak) PrintHTML(buf *bytes.Buffer) { 58 buf.WriteString("<br />\n") 59} 60 61func (x *HardBreak) printMarkdown(buf *bytes.Buffer) { 62 buf.WriteString("\\\n") 63} 64 65func (x *HardBreak) PrintText(buf *bytes.Buffer) { 66 buf.WriteString("\n") 67} 68 69type SoftBreak struct{} 70 71func (*SoftBreak) Inline() {} 72 73func (x *SoftBreak) PrintHTML(buf *bytes.Buffer) { 74 buf.WriteString("\n") 75} 76 77func (x *SoftBreak) printMarkdown(buf *bytes.Buffer) { 78 buf.WriteString("\n") 79} 80 81func (x *SoftBreak) PrintText(buf *bytes.Buffer) { 82 buf.WriteString("\n") 83} 84 85func parseBreak(_ *parseState, s string, i int) (Inline, int, int, bool) { 86 start := i 87 for start > 0 && (s[start-1] == ' ' || s[start-1] == '\t') { 88 start-- 89 } 90 end := i + 1 91 for end < len(s) && (s[end] == ' ' || s[end] == '\t') { 92 end++ 93 } 94 // TODO: Do tabs count? That would be a mess. 95 if i >= 2 && s[i-1] == ' ' && s[i-2] == ' ' { 96 return &HardBreak{}, start, end, true 97 } 98 return &SoftBreak{}, start, end, true 99} 100