From 8bf5d9d2c82560c81be6809522215bded0cf9911 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Tue, 16 Feb 2016 18:43:22 +0100 Subject: Inital import --- data/.gitkeep | 0 edit.go | 16 ++++++++++++++++ index.go | 27 +++++++++++++++++++++++++++ parse.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ root.go | 11 +++++++++++ save.go | 17 +++++++++++++++++ tmpl/doc | 23 +++++++++++++++++++++++ tmpl/edit | 9 +++++++++ tmpl/index | 8 ++++++++ tmpl/root | 27 +++++++++++++++++++++++++++ tmpl/view | 4 ++++ view.go | 22 ++++++++++++++++++++++ wiki.go | 39 +++++++++++++++++++++++++++++++++++++++ 13 files changed, 252 insertions(+) create mode 100644 data/.gitkeep create mode 100644 edit.go create mode 100644 index.go create mode 100644 parse.go create mode 100644 root.go create mode 100644 save.go create mode 100644 tmpl/doc create mode 100644 tmpl/edit create mode 100644 tmpl/index create mode 100644 tmpl/root create mode 100644 tmpl/view create mode 100644 view.go create mode 100644 wiki.go diff --git a/data/.gitkeep b/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/edit.go b/edit.go new file mode 100644 index 0000000..a425a1a --- /dev/null +++ b/edit.go @@ -0,0 +1,16 @@ +package main + +import ( + "net/http" + "text/template" +) + +func init() { + http.HandleFunc("/edit/", editHandler) +} + +func editHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[len("/edit/"):] + p, _ := loadPage(title) + p.render(w, template.Must(template.ParseFiles("tmpl/root", "tmpl/edit"))) +} diff --git a/index.go b/index.go new file mode 100644 index 0000000..a9613fd --- /dev/null +++ b/index.go @@ -0,0 +1,27 @@ +package main + +import ( + "io/ioutil" + "net/http" + "text/template" +) + +func init() { + http.HandleFunc("/index", indexHandler) +} + +func indexHandler(w http.ResponseWriter, r *http.Request) { + files, err := ioutil.ReadDir("data") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + p := new(Page) + for _, entry := range files { + file := entry.Name() + if !entry.IsDir() && file[0] != '.' { + p.Pages = append(p.Pages, file) + } + } + p.render(w, template.Must(template.ParseFiles("tmpl/root", "tmpl/index"))) +} diff --git a/parse.go b/parse.go new file mode 100644 index 0000000..ccf2a87 --- /dev/null +++ b/parse.go @@ -0,0 +1,49 @@ +package main + +import ( + "bytes" + "regexp" + "strings" + "text/template" +) + +var ( + doc = template.Must(template.ParseFiles("tmpl/doc")) + intlink = regexp.MustCompile(`\[[^\]]+\]`) + extlink = regexp.MustCompile(`(https?|ftp)://\S+`) + imglink = regexp.MustCompile(`\.(jpe?g|png|gif)$`) +) + +func parse(in []byte) string { + buf := new(bytes.Buffer) + for _, v := range strings.Split(string(in), "\r\n\r\n") { + v = intlink.ReplaceAllStringFunc(v, func(s string) string { + tmp := new(bytes.Buffer) + doc.ExecuteTemplate(tmp, "link", s[1:len(s)-1]) + return tmp.String() + }) + v = extlink.ReplaceAllStringFunc(v, func(s string) string { + tmp := new(bytes.Buffer) + if imglink.MatchString(s) { + doc.ExecuteTemplate(tmp, "img", s) + } else { + doc.ExecuteTemplate(tmp, "link", s) + } + return tmp.String() + }) + + switch v[0] { + case ' ': + doc.ExecuteTemplate(buf, "pre", v) + case '-': + lines := strings.Split(v, "\r\n") + for i, l := range lines { + lines[i] = l[1:] + } + doc.ExecuteTemplate(buf, "list", lines) + default: + doc.ExecuteTemplate(buf, "par", v) + } + } + return buf.String() +} diff --git a/root.go b/root.go new file mode 100644 index 0000000..b9b7e4d --- /dev/null +++ b/root.go @@ -0,0 +1,11 @@ +package main + +import "net/http" + +func init() { + http.HandleFunc("/", rootHandler) +} + +func rootHandler(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/view/Root", http.StatusFound) +} diff --git a/save.go b/save.go new file mode 100644 index 0000000..68ac700 --- /dev/null +++ b/save.go @@ -0,0 +1,17 @@ +package main + +import "net/http" + +func init() { + http.HandleFunc("/save/", saveHandler) +} + +func saveHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[len("/save/"):] + p := &Page{Title: title, Body: []byte(r.FormValue("body"))} + if err := p.save(); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + http.Redirect(w, r, "/view/"+title, http.StatusFound) +} diff --git a/tmpl/doc b/tmpl/doc new file mode 100644 index 0000000..f4f1dd3 --- /dev/null +++ b/tmpl/doc @@ -0,0 +1,23 @@ +{{define "link"}} + {{.}} +{{end}} + +{{define "img"}} + +{{end}} + +{{define "par"}} +

{{.}}

+{{end}} + +{{define "pre"}} +
{{.}}
+{{end}} + +{{define "list"}} + +{{end}} diff --git a/tmpl/edit b/tmpl/edit new file mode 100644 index 0000000..16b7846 --- /dev/null +++ b/tmpl/edit @@ -0,0 +1,9 @@ +{{define "title"}}Editing {{.Title}}{{end}} +{{define "content"}} +
+ +
+ + +
+{{end}} diff --git a/tmpl/index b/tmpl/index new file mode 100644 index 0000000..d95deca --- /dev/null +++ b/tmpl/index @@ -0,0 +1,8 @@ +{{define "title"}}Index{{end}} +{{define "content"}} + +{{end}} diff --git a/tmpl/root b/tmpl/root new file mode 100644 index 0000000..ae31e36 --- /dev/null +++ b/tmpl/root @@ -0,0 +1,27 @@ +{{define "root"}} + + + + {{template "title" .}} + + + + +
+
+

{{template "title" .}}

+ +
+{{template "content" .}} +
+ + +{{end}} diff --git a/tmpl/view b/tmpl/view new file mode 100644 index 0000000..24d9b55 --- /dev/null +++ b/tmpl/view @@ -0,0 +1,4 @@ +{{define "title"}}{{.Title}}{{end}} +{{define "content"}} +{{.HTML}} +{{end}} diff --git a/view.go b/view.go new file mode 100644 index 0000000..62f9a4b --- /dev/null +++ b/view.go @@ -0,0 +1,22 @@ +package main + +import ( + "net/http" + "text/template" +) + +func init() { + http.HandleFunc("/view/", viewHandler) +} + +func viewHandler(w http.ResponseWriter, r *http.Request) { + title := r.URL.Path[len("/view/"):] + p, err := loadPage(title) + if err != nil { + http.Redirect(w, r, "/edit/"+title, http.StatusFound) + return + } + + p.HTML = parse(p.Body) + p.render(w, template.Must(template.ParseFiles("tmpl/root", "tmpl/view"))) +} diff --git a/wiki.go b/wiki.go new file mode 100644 index 0000000..5f096c1 --- /dev/null +++ b/wiki.go @@ -0,0 +1,39 @@ +package main + +import ( + "io/ioutil" + "net/http" + "text/template" +) + +type Page struct { + Title string + Body []byte + Pages []string + HTML string +} + +func (p *Page) fileName() string { + return "data/" + p.Title +} + +func (p *Page) save() error { + return ioutil.WriteFile(p.fileName(), p.Body, 0600) +} + +func loadPage(title string) (p *Page, err error) { + p = &Page{Title: title} + p.Body, err = ioutil.ReadFile(p.fileName()) + return +} + +func (p *Page) render(w http.ResponseWriter, tmpl *template.Template) { + err := tmpl.ExecuteTemplate(w, "root", p) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } +} + +func main() { + http.ListenAndServe(":8080", nil) +} -- cgit v1.2.3