aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/vendor/rsc.io/markdown/break.go
blob: c0ddaabffb6161af80ad83b9bf493c75f08f4b07 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package markdown

import (
	"bytes"
)

type ThematicBreak struct {
	Position
	raw string
}

func (b *ThematicBreak) PrintHTML(buf *bytes.Buffer) {
	buf.WriteString("<hr />\n")
}

func (b *ThematicBreak) printMarkdown(buf *bytes.Buffer, s mdState) {
	buf.WriteString(s.prefix)
	buf.WriteString(b.raw)
	buf.WriteByte('\n')
}

func newHR(p *parseState, s line) (line, bool) {
	if isHR(s) {
		p.doneBlock(&ThematicBreak{Position{p.lineno, p.lineno}, s.string()})
		return line{}, true
	}
	return s, false
}

func isHR(s line) bool {
	t := s
	t.trimSpace(0, 3, false)
	switch c := t.peek(); c {
	case '-', '_', '*':
		for i := 0; ; i++ {
			if !t.trim(c) {
				if i >= 3 {
					break
				}
				return false
			}
			t.skipSpace()
		}
		return t.eof()
	}
	return false
}

type HardBreak struct{}

func (*HardBreak) Inline() {}

func (x *HardBreak) PrintHTML(buf *bytes.Buffer) {
	buf.WriteString("<br />\n")
}

func (x *HardBreak) printMarkdown(buf *bytes.Buffer) {
	buf.WriteString("\\\n")
}

func (x *HardBreak) PrintText(buf *bytes.Buffer) {
	buf.WriteString("\n")
}

type SoftBreak struct{}

func (*SoftBreak) Inline() {}

func (x *SoftBreak) PrintHTML(buf *bytes.Buffer) {
	buf.WriteString("\n")
}

func (x *SoftBreak) printMarkdown(buf *bytes.Buffer) {
	buf.WriteString("\n")
}

func (x *SoftBreak) PrintText(buf *bytes.Buffer) {
	buf.WriteString("\n")
}

func parseBreak(_ *parseState, s string, i int) (Inline, int, int, bool) {
	start := i
	for start > 0 && (s[start-1] == ' ' || s[start-1] == '\t') {
		start--
	}
	end := i + 1
	for end < len(s) && (s[end] == ' ' || s[end] == '\t') {
		end++
	}
	// TODO: Do tabs count? That would be a mess.
	if i >= 2 && s[i-1] == ' ' && s[i-2] == ' ' {
		return &HardBreak{}, start, end, true
	}
	return &SoftBreak{}, start, end, true
}