-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.go
79 lines (70 loc) · 2.12 KB
/
main.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
package main
import (
"embed"
"flag"
"fmt"
"io"
"mime"
"net/http"
"os"
"path/filepath"
"strings"
log "github.com/sirupsen/logrus"
)
var (
listen = flag.String("listen", ":8080", "Interface:port to listen on")
index = flag.String("index", "README.md", "Index (or default) markdown file name")
//go:embed static
static embed.FS
)
func render(cwd string, w http.ResponseWriter, r *http.Request) {
b, err := os.ReadFile(r.URL.Path)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
css, body, err := renderMarkdown(b)
fmt.Fprintf(w, `<!doctype html>
<html lang="en" data-bs-theme="dark"><head><meta charset="utf-8">
<title>%s</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="/static/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="/static/style.css" rel="stylesheet" type="text/css" />
<style>%s</style>
<link rel="icon" type="image/png" href="/static/markdown.png" />
</head><body><article class="markdown-body">`,
filepath.Base(cwd), css)
w.Write(body)
io.WriteString(w, `</article></body></html>`)
}
func markdownRender(cwd string, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "" {
r.URL.Path = *index
}
if strings.HasSuffix(r.URL.Path, ".md") {
render(cwd, w, r)
log.WithFields(log.Fields{"file": r.URL.Path}).Info("Rendered")
return
}
next.ServeHTTP(w, r)
log.WithFields(log.Fields{"file": r.URL.Path}).Info("Served")
})
}
func init() {
mime.AddExtensionType(".css", "text/css")
}
func main() {
flag.Parse()
cwd, err := os.Getwd()
if err != nil {
log.Fatalf("Unable to determine current working directory, err=%s", err)
}
http.Handle("/", http.StripPrefix("/", markdownRender(cwd, http.FileServer(http.Dir(cwd)))))
http.Handle("/static/", http.FileServer(http.FS(static)))
log.WithFields(log.Fields{"dir": cwd, "addr": *listen}).Info("Starting")
if err := http.ListenAndServe(*listen, nil); err != nil {
log.WithFields(log.Fields{"err": err}).Error("Failed at runtime")
}
}