-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathgm_build.go
148 lines (139 loc) · 4.04 KB
/
gm_build.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package main
import (
"io"
"os"
"path/filepath"
"strings"
"github.com/bmatcuk/doublestar/v4"
)
// buildMd compiles the infile (xxx.md | stdin) to outfile (xxx.html | stdout)
func buildMd(infile string) {
// get the dir for link replacement, if any
dir := filepath.Dir(infile)
// Get the input
var input io.Reader
if infile != "" {
f, err := os.Open(infile)
if err != nil {
check(err, "Problem opening", infile)
return
}
defer f.Close()
input = f
} else {
input = os.Stdin
dir = "."
}
// read the input
markdown, err := io.ReadAll(input)
check(err, "Problem reading the markdown.")
//compile the input
html, err := compile(markdown)
check(err, "Problem compiling the markdown.")
if localmdlinks {
html = replaceLinks(html, dir)
}
// output the result
if infile == "" {
os.Stdout.Write(html)
} else {
var outfile string
if readme && strings.ToLower(filepath.Base(infile)) == "readme.md" {
// if it is a README.md file, we want to name it index.html
outfile = filepath.Join(outdir, infile[:len(infile)-9]+"index.html")
} else {
// otherwise we just change the extension
outfile = filepath.Join(outdir, infile[:len(infile)-3]+".html")
}
if os.MkdirAll(filepath.Dir(outfile), os.ModePerm) != nil {
check(err, "Problem to reach/create folder:", filepath.Dir(outfile))
}
err = os.WriteFile(outfile, html, 0644)
check(err, "Problem modifying", outfile)
}
}
func pathFirstPart(path string) string {
i := 0
for ; i < len(path); i++ {
if os.IsPathSeparator(path[i]) {
break
}
}
if i == len(path) {
return path + string(os.PathSeparator)
}
return path[:i+1]
}
func pathHasDot(path string) bool {
wasSeparator := true
for i := 0; i < len(path); i++ {
if path[i] == '.' && wasSeparator {
return true
}
wasSeparator = os.IsPathSeparator(path[i])
}
return false
}
// buildFiles convert all .md files verifying one of the patterns to .html
func buildFiles() {
// get the current directory
cwd, err := os.Getwd()
check(err, "Problem getting the current directory.")
// get the current directory as a filesystem, needed for doublestar.Glob
dirFS := os.DirFS(cwd)
// normalize the output directory and set movefiles and outstart
outdir, err = filepath.Abs(outdir)
check(err, "Problem getting the absolute path of the output directory.")
movefiles := move && outdir != cwd
outdir, err = filepath.Rel(cwd, outdir)
check(err, "Problem getting the relative path of the output directory.")
// get the first part of the relative out path
outstart := pathFirstPart(outdir)
// check all patterns
action := "Building"
if movefiles {
action = "Building and moving"
}
info(action+" files from '%s' to '%s'.\n", cwd, outdir)
for _, pattern := range inpatterns {
info("Looking for '%s'.\n", pattern)
// if the input is piped
if pattern == "stdin" {
buildMd("")
continue
}
// look for all files with the given patterns
// but build only .md ones
allfiles, err := doublestar.Glob(dirFS, pattern, doublestar.WithFilesOnly(), doublestar.WithNoFollow())
check(err, "Problem looking for file pattern:", pattern)
if len(allfiles) == 0 {
info("No files found.\n")
continue
}
for _, infile := range allfiles {
infile = filepath.Clean(infile)
if skipdot && pathHasDot(infile) {
info(" Skipping %s...\n", infile)
continue
}
if strings.HasPrefix(infile, outstart) {
continue
}
if strings.HasSuffix(infile, ".md") {
info(" Converting %s...", infile)
buildMd(infile)
info("done.\n")
} else if movefiles {
// move the file if it is not markdown and not already in the output folder
info(" Moving %s...", infile)
outfile := filepath.Join(outdir, infile)
if os.MkdirAll(filepath.Dir(outfile), os.ModePerm) != nil {
check(err, "Problem to reach/create folder:", filepath.Dir(outfile))
}
err := os.Rename(infile, outfile)
check(err, "Problem moving", infile)
info("done.\n")
}
}
}
}