/
mdfilter.go
72 lines (61 loc) · 1.47 KB
/
mdfilter.go
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
package main
import (
// "log"
"bufio"
"bytes"
"fmt"
"io"
"strings"
"unicode"
)
// A markdown filter. This will read a markdown file and will search for codeblocks
// starting with "#!goseq". It will interpret this as a call to goseq, parse the content
// and build an image.
type MarkdownFilter struct {
input io.Reader
output io.Writer
handler CodeblockHandler
}
type CodeblockHandler func(codeblock string, output io.Writer) error
func (cb *MarkdownFilter) Scan() error {
scanner := bufio.NewScanner(cb.input)
inblock := false
currentIndent := 0
blockcontent := new(bytes.Buffer)
for scanner.Scan() {
line := scanner.Text()
trimmedLine := strings.TrimSpace(line)
indent := cb.lineIndent(line)
if (!inblock) && (indent >= currentIndent+4) && (strings.HasPrefix(trimmedLine, "#!goseq")) {
inblock = true
currentIndent = indent
} else if (inblock) && (indent <= currentIndent-4) && (trimmedLine != "") {
inblock = false
cb.handler(blockcontent.String(), cb.output)
blockcontent.Reset()
currentIndent = indent
}
if inblock {
fmt.Fprintln(blockcontent, line)
} else {
fmt.Fprintln(cb.output, line)
}
//log.Println(inblock, line)
}
if inblock {
cb.handler(blockcontent.String(), cb.output)
}
return scanner.Err()
}
// Determine the line indent
func (cb *MarkdownFilter) lineIndent(line string) int {
indent := 0
for _, r := range line {
if unicode.IsSpace(r) {
indent++
} else {
break
}
}
return indent
}