ref: master
./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 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 |
package main import ( "bytes" "embed" "flag" "fmt" "html/template" "log" "net/http" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "github.com/yuin/goldmark" "github.com/yuin/goldmark-meta" "github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/parser" ) type Document struct { Title string Content template.HTML Meta map[string]interface{} } var ( wikiPath string bind string ) //go:embed templates/* var templateData embed.FS func requestError(msg string, w http.ResponseWriter) { log.Printf("500 on " + msg) w.WriteHeader(500) w.Write([]byte("500 Internal Server Error \n")) } func main() { flag.StringVar(&wikiPath, "wiki", wikiPath, "Wiki path") flag.StringVar(&bind, "bind", ":3000", "Address for server to bind to") flag.Parse() // TODO: Write an actual man page if wikiPath == "" { log.Fatalf("You'll need to point to the location of the wiki (--wiki)") return } router := chi.NewRouter() router.Use(middleware.RealIP) router.Use(middleware.Logger) parsedTemplate, _ := template.ParseFS(templateData, "templates/layout.html") // TODO: Make this configurable router.Get("/favicon.ico", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) w.Write([]byte("")) }) router.Get("/*", func(w http.ResponseWriter, r *http.Request) { var ( buf bytes.Buffer ) route := chi.URLParam(r, "*") md := goldmark.New( goldmark.WithExtensions( extension.GFM, extension.Linkify, extension.Table, extension.TaskList, extension.DefinitionList, extension.Strikethrough, extension.Footnote, meta.Meta, ), goldmark.WithParserOptions( parser.WithAutoHeadingID(), ), ) doc, err := Lookup(wikiPath, route) if err != nil { requestError(fmt.Sprintf("Couldn't lookup file: %v", err), w) return } document := &Document{} context := parser.NewContext() if err := md.Convert(doc, &buf, parser.WithContext(context)); err != nil { requestError(fmt.Sprintf("Couldn't convert markdown due: %v", err), w) return } document.Content = template.HTML(buf.String()) document.Meta = meta.Get(context) title, ok := document.Meta["title"].(string) if ok { document.Title = title } err = parsedTemplate.Execute(w, document) if err != nil { requestError(fmt.Sprintf("Couldn't execute the template due %v", err), w) return } }) log.Printf("Alive, at %s", bind) http.ListenAndServe(bind, router) } |