-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcode_include.go
91 lines (77 loc) · 1.87 KB
/
code_include.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//go:build ignore
// +build ignore
package main
import (
"errors"
"flag"
"log"
"os"
"regexp"
"strconv"
"strings"
)
var (
prefixLine = "```golang"
suffixLine = "```"
codeStart = regexp.MustCompile(`^[\s]*<!--[\s]*include:.*-->[\s]*$`)
codeEnd = regexp.MustCompile(`^[\s]*<!--[\s]*/[\s]*-->[\s]*$`)
nodocEx = regexp.MustCompile(`^.*//[\s]*nodoc[+]?[0-9]*[\s]*$`)
)
func exitOnError(err error) {
if err != nil {
log.Fatal(err)
}
}
func parseInclude(line string) string {
rhs := strings.TrimPrefix(strings.TrimPrefix(line, "<!--"), "include:")
return strings.TrimSpace(strings.TrimSuffix(rhs, "-->"))
}
func nodoc(lines []string) []string {
var out []string
for i := 0; i < len(lines); i++ {
if match := nodocEx.FindString(lines[i]); len(match) > 0 {
parts := strings.Split(match, "nodoc+")
if len(parts) == 2 {
skip, err := strconv.Atoi(parts[1])
exitOnError(err)
i += skip
}
continue
}
out = append(out, lines[i])
}
return out
}
func main() {
file := flag.String("file", "README.md", "source and target file name")
flag.Parse()
text, err := os.ReadFile(*file)
exitOnError(err)
input := strings.Split(string(text), "\n")
start := -1
end := -1
for i, line := range input {
switch {
case codeStart.MatchString(line):
start = i
case codeEnd.MatchString(line):
end = i
}
}
if start < 0 || end < 0 || end < start {
exitOnError(errors.New("failed to find code include"))
}
inc, err := os.ReadFile(parseInclude(input[start]))
exitOnError(err)
code := strings.Split(string(inc), "\n")
out := make([]string, 0, len(input))
out = append(out, input[:start+1]...)
out = append(out, prefixLine)
out = append(out, nodoc(code)...)
out = append(out, suffixLine)
out = append(out, input[end:]...)
output := strings.Join(out, "\n")
// println(output)
err = os.WriteFile(*file, []byte(output), 0644)
exitOnError(err)
}