ソースを参照

tmpview: Render and view markdown docs

Lu Stadler 7 年 前
コミット
c3bf4d70a1
共有3 個のファイルを変更した93 個の追加0 個の削除を含む
  1. 1 0
      go/tmpview/.gitignore
  2. 7 0
      go/tmpview/Makefile
  3. 85 0
      go/tmpview/tmpview.go

+ 1 - 0
go/tmpview/.gitignore

@ -0,0 +1 @@
1
/tmpview

+ 7 - 0
go/tmpview/Makefile

@ -0,0 +1,7 @@
1
NAME = tmpview
2
3
$(NAME): $(NAME).go
4
	go build .
5
6
install: $(NAME)
7
	install -m0755 $(NAME) $(PREFIX)/bin

+ 85 - 0
go/tmpview/tmpview.go

@ -0,0 +1,85 @@
1
package main
2
3
import (
4
	"context"
5
	"fmt"
6
	"io/ioutil"
7
	"log"
8
	"net"
9
	"net/http"
10
	"os"
11
	"os/exec"
12
	"time"
13
14
	"github.com/russross/blackfriday"
15
)
16
17
var (
18
	lastVisit time.Time
19
	srv       *http.Server
20
)
21
22
func main() {
23
	fileName := os.Args[1]
24
	addr := freePort()
25
26
	if os.Args[1] == "serve" {
27
		addr := os.Args[2]
28
		fileName := os.Args[3]
29
30
		mux := http.NewServeMux()
31
		mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
32
			lastVisit = time.Now()
33
34
			data, err := ioutil.ReadFile(fileName)
35
			if err != nil {
36
				http.Error(w, "could not read file", http.StatusNotFound)
37
				log.Println(err)
38
			}
39
40
			style := `body { max-width: 50em; margin: 0 auto; }`
41
			fmt.Fprintf(w, "<!doctype html><html><head><meta charset=\"utf-8\" /><title>%s</title><style>%s</style></head><body>\n\n\n", fileName, style)
42
			w.Write(blackfriday.MarkdownCommon(data))
43
			fmt.Fprintf(w, "\n\n\n</body></html>")
44
		})
45
46
		srv = &http.Server{
47
			Handler: mux,
48
			Addr:    addr,
49
		}
50
		go keepalive()
51
		log.Fatal(srv.ListenAndServe())
52
	}
53
54
	server := exec.Command(os.Args[0], "serve", addr, fileName)
55
	err := server.Start()
56
	if err != nil {
57
		log.Fatal(err)
58
	}
59
60
	cmd := exec.Command("xdg-open", fmt.Sprintf("http://%s/%s", addr, fileName))
61
	err = cmd.Run()
62
	if err != nil {
63
		log.Fatal(err)
64
	}
65
}
66
67
func keepalive() {
68
	for {
69
		time.Sleep(1 * time.Minute)
70
71
		if time.Since(lastVisit) > 5*time.Minute {
72
			log.Println("shutting down")
73
			srv.Shutdown(context.TODO())
74
		}
75
	}
76
}
77
78
func freePort() string {
79
	l, err := net.Listen("tcp4", "localhost:0")
80
	if err != nil {
81
		panic(err)
82
	}
83
	l.Close()
84
	return l.Addr().String()
85
}