diff options
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | assets/IBMPlexMono-Regular.woff | bin | 50664 -> 0 bytes | |||
-rw-r--r-- | assets/IBMPlexMono-Regular.woff2 | bin | 35536 -> 0 bytes | |||
-rw-r--r-- | assets/style.css | 1 | ||||
-rw-r--r-- | css/main.scss | 29 | ||||
-rw-r--r-- | gopherproxy.go | 31 | ||||
-rw-r--r-- | style.go | 3 | ||||
-rw-r--r-- | template.go | 5 |
8 files changed, 43 insertions, 29 deletions
@@ -6,7 +6,8 @@ dev: build | |||
6 | ./gopherproxy -bind 127.0.0.1:8000 | 6 | ./gopherproxy -bind 127.0.0.1:8000 |
7 | 7 | ||
8 | build: clean | 8 | build: clean |
9 | sassc -t compressed css/main.scss assets/style.css | 9 | sassc -t compressed css/main.scss style.go |
10 | sed -i "s/.*/package gopherproxy\n\nvar styletext = \`&\`/" style.go | ||
10 | go build -o ./gopherproxy ./cmd/gopherproxy/main.go | 11 | go build -o ./gopherproxy ./cmd/gopherproxy/main.go |
11 | 12 | ||
12 | profile: | 13 | profile: |
diff --git a/assets/IBMPlexMono-Regular.woff b/assets/IBMPlexMono-Regular.woff deleted file mode 100644 index 7d63d89..0000000 --- a/assets/IBMPlexMono-Regular.woff +++ /dev/null | |||
Binary files differ | |||
diff --git a/assets/IBMPlexMono-Regular.woff2 b/assets/IBMPlexMono-Regular.woff2 deleted file mode 100644 index d0d7ded..0000000 --- a/assets/IBMPlexMono-Regular.woff2 +++ /dev/null | |||
Binary files differ | |||
diff --git a/assets/style.css b/assets/style.css deleted file mode 100644 index 70b1998..0000000 --- a/assets/style.css +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | @font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:normal;src:url("/assets/IBMPlexMono-Regular.woff2") format("woff2"),url("/assets/IBMPlexMono-Regular.woff") format("woff")}body{background-color:#14171a;color:#cad1d8}.wrap{text-align:center}.content{display:inline-block;min-width:50em;margin:0;padding:2em 1em;text-align:left;font-family:'IBM Plex Mono', 'Fira Code', 'Fira Mono', 'Roboto Mono', 'Droid Sans Mono', Monaco, Consolas, Courier, monospace;font-size:1em;line-height:1.5}::selection{color:#000;background-color:#cad1d8}:link{color:#fff}:visited{color:#cad1d8}:link:hover,:visited:hover{color:#fff}.link-type{color:#929ba3} | ||
diff --git a/css/main.scss b/css/main.scss index dfda503..8ae988e 100644 --- a/css/main.scss +++ b/css/main.scss | |||
@@ -1,20 +1,17 @@ | |||
1 | $accent: scale-color(#e8ad58, $lightness: 30%); | ||
1 | $background: hsl(210, 14%, 9%); | 2 | $background: hsl(210, 14%, 9%); |
2 | $text: mix(hsl(210, 60%, 95%), $background, 85%); | 3 | $text: mix(hsl(210, 60%, 95%), $background, 85%); |
3 | $text-minus: mix(hsl(210, 100%, 95%), $background, 60%); | 4 | $text-minus: mix(hsl(210, 100%, 95%), $background, 60%); |
4 | $text-faint: mix(hsl(210, 100%, 95%), $background, 40%); | 5 | $text-faint: mix(hsl(210, 100%, 95%), $background, 40%); |
5 | $text-plus: #fff; | 6 | $text-plus: #fff; |
6 | $sel-background: $text; | 7 | $link-idle: $text-plus; |
8 | $link-visited: $text; | ||
9 | $sel-background: $accent; | ||
7 | $sel-text: #000; | 10 | $sel-text: #000; |
8 | 11 | ||
9 | @font-face { | ||
10 | font-family: 'IBM Plex Mono'; | ||
11 | font-style: normal; | ||
12 | font-weight: normal; | ||
13 | src: url('/assets/IBMPlexMono-Regular.woff2') format('woff2'), | ||
14 | url('/assets/IBMPlexMono-Regular.woff') format('woff'); | ||
15 | } | ||
16 | |||
17 | body { | 12 | body { |
13 | margin: 0; | ||
14 | padding: 0; | ||
18 | background-color: $background; | 15 | background-color: $background; |
19 | color: $text; | 16 | color: $text; |
20 | } | 17 | } |
@@ -40,18 +37,18 @@ body { | |||
40 | } | 37 | } |
41 | 38 | ||
42 | :link { | 39 | :link { |
43 | color: $text-plus; | 40 | color: $link-idle; |
44 | } | 41 | } |
45 | 42 | ||
46 | :visited { | 43 | :visited { |
47 | color: $text; | 44 | color: $link-visited; |
48 | } | 45 | } |
49 | 46 | ||
50 | :link, :visited { | 47 | // :link, :visited { |
51 | &:hover { | 48 | // &:hover { |
52 | color: $text-plus; | 49 | // color: $text-plus; |
53 | } | 50 | // } |
54 | } | 51 | // } |
55 | 52 | ||
56 | .link-type { | 53 | .link-type { |
57 | color: $text-minus; | 54 | color: $text-minus; |
diff --git a/gopherproxy.go b/gopherproxy.go index 6f1e8ec..dc849d0 100644 --- a/gopherproxy.go +++ b/gopherproxy.go | |||
@@ -22,7 +22,7 @@ type Item struct { | |||
22 | Text string | 22 | Text string |
23 | } | 23 | } |
24 | 24 | ||
25 | func renderDirectory(w http.ResponseWriter, tpl *template.Template, hostport string, d gopher.Directory) error { | 25 | func renderDirectory(w http.ResponseWriter, tpl *template.Template, styletext string, hostport string, d gopher.Directory) error { |
26 | var title string | 26 | var title string |
27 | 27 | ||
28 | out := make([]Item, len(d.Items)) | 28 | out := make([]Item, len(d.Items)) |
@@ -73,9 +73,10 @@ func renderDirectory(w http.ResponseWriter, tpl *template.Template, hostport str | |||
73 | 73 | ||
74 | return tpl.Execute(w, struct { | 74 | return tpl.Execute(w, struct { |
75 | Title string | 75 | Title string |
76 | Style string | ||
76 | Lines []Item | 77 | Lines []Item |
77 | RawText string | 78 | RawText string |
78 | }{title, out, ""}) | 79 | }{title, styletext, out, ""}) |
79 | } | 80 | } |
80 | 81 | ||
81 | // GopherHandler returns a Handler that proxies requests | 82 | // GopherHandler returns a Handler that proxies requests |
@@ -83,7 +84,7 @@ func renderDirectory(w http.ResponseWriter, tpl *template.Template, hostport str | |||
83 | // to the request path and renders the content using the provided template. | 84 | // to the request path and renders the content using the provided template. |
84 | // The optional robots parameters points to a robotstxt.RobotsData struct | 85 | // The optional robots parameters points to a robotstxt.RobotsData struct |
85 | // to test user agents against a configurable robotst.txt file. | 86 | // to test user agents against a configurable robotst.txt file. |
86 | func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, uri string) http.HandlerFunc { | 87 | func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, styletext string, uri string) http.HandlerFunc { |
87 | return func(w http.ResponseWriter, req *http.Request) { | 88 | return func(w http.ResponseWriter, req *http.Request) { |
88 | agent := req.UserAgent() | 89 | agent := req.UserAgent() |
89 | path := strings.TrimPrefix(req.URL.Path, "/") | 90 | path := strings.TrimPrefix(req.URL.Path, "/") |
@@ -127,20 +128,21 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, uri | |||
127 | } | 128 | } |
128 | 129 | ||
129 | if res.Body != nil { | 130 | if res.Body != nil { |
130 | if strings.HasSuffix(uri, ".txt") { | 131 | if strings.HasSuffix(uri, ".txt") || strings.HasSuffix(uri, ".md") { |
131 | // handle .txt files | 132 | // handle .txt files |
132 | buf := new(bytes.Buffer) | 133 | buf := new(bytes.Buffer) |
133 | buf.ReadFrom(res.Body) | 134 | buf.ReadFrom(res.Body) |
134 | tpl.Execute(w, struct { | 135 | tpl.Execute(w, struct { |
135 | Title string | 136 | Title string |
137 | Style string | ||
136 | RawText string | 138 | RawText string |
137 | Lines []Item | 139 | Lines []Item |
138 | }{uri, buf.String(), nil}) | 140 | }{uri, styletext, buf.String(), nil}) |
139 | } else { | 141 | } else { |
140 | io.Copy(w, res.Body) | 142 | io.Copy(w, res.Body) |
141 | } | 143 | } |
142 | } else { | 144 | } else { |
143 | if err := renderDirectory(w, tpl, hostport, res.Dir); err != nil { | 145 | if err := renderDirectory(w, tpl, styletext, hostport, res.Dir); err != nil { |
144 | io.WriteString(w, fmt.Sprintf("<b>Error:</b><pre>%s</pre>", err)) | 146 | io.WriteString(w, fmt.Sprintf("<b>Error:</b><pre>%s</pre>", err)) |
145 | return | 147 | return |
146 | } | 148 | } |
@@ -187,19 +189,30 @@ func ListenAndServe(bind, robotsfile, uri string) error { | |||
187 | } | 189 | } |
188 | } | 190 | } |
189 | 191 | ||
192 | styledata, err := ioutil.ReadFile(".style") | ||
193 | if err == nil { | ||
194 | styletext = string(styledata) | ||
195 | } | ||
196 | |||
190 | tpldata, err := ioutil.ReadFile(".template") | 197 | tpldata, err := ioutil.ReadFile(".template") |
191 | if err == nil { | 198 | if err == nil { |
192 | tpltext = string(tpldata) | 199 | tpltext = string(tpldata) |
193 | } | 200 | } |
194 | 201 | ||
195 | tpl, err = template.New("gophermenu").Parse(tpltext) | 202 | funcMap := template.FuncMap{ |
203 | "safeCss": func(s string) template.CSS { | ||
204 | return template.CSS(s) | ||
205 | }, | ||
206 | } | ||
207 | |||
208 | tpl, err = template.New("gophermenu").Funcs(funcMap).Parse(tpltext) | ||
196 | if err != nil { | 209 | if err != nil { |
197 | log.Fatal(err) | 210 | log.Fatal(err) |
198 | } | 211 | } |
199 | 212 | ||
200 | http.HandleFunc("/", GopherHandler(tpl, robotsdata, uri)) | 213 | http.HandleFunc("/", GopherHandler(tpl, robotsdata, styletext, uri)) |
201 | http.HandleFunc("/robots.txt", RobotsTxtHandler(robotstxtdata)) | 214 | http.HandleFunc("/robots.txt", RobotsTxtHandler(robotstxtdata)) |
202 | http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets/")))) | 215 | // http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets/")))) |
203 | 216 | ||
204 | return http.ListenAndServe(bind, nil) | 217 | return http.ListenAndServe(bind, nil) |
205 | } | 218 | } |
diff --git a/style.go b/style.go new file mode 100644 index 0000000..e6e301a --- /dev/null +++ b/style.go | |||
@@ -0,0 +1,3 @@ | |||
1 | package gopherproxy | ||
2 | |||
3 | var styletext = `body{margin:0;padding:0;background-color:#14171a;color:#cad1d8}.wrap{text-align:center}.content{display:inline-block;min-width:50em;margin:0;padding:2em 1em;text-align:left;font-family:'IBM Plex Mono', 'Fira Code', 'Fira Mono', 'Roboto Mono', 'Droid Sans Mono', Monaco, Consolas, Courier, monospace;font-size:1em;line-height:1.5}::selection{color:#000;background-color:#efc68a}:link{color:#fff}:visited{color:#cad1d8}.link-type{color:#929ba3}` | ||
diff --git a/template.go b/template.go index b42f811..9582e3a 100644 --- a/template.go +++ b/template.go | |||
@@ -6,9 +6,10 @@ var tpltext = `<!doctype html> | |||
6 | <meta charset="utf-8"> | 6 | <meta charset="utf-8"> |
7 | <meta name="viewport" content="width=device-width, initial-scale=1" /> | 7 | <meta name="viewport" content="width=device-width, initial-scale=1" /> |
8 | <title>{{.Title}}</title> | 8 | <title>{{.Title}}</title> |
9 | <link rel="preload" href="/assets/style.css" as="style" /> | ||
10 | <link rel="preload" href="/assets/IBMPlexMono-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous" /> | 9 | <link rel="preload" href="/assets/IBMPlexMono-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous" /> |
11 | <link rel="stylesheet" href="/assets/style.css" /> | 10 | <style> |
11 | {{.Style | safeCss}} | ||
12 | </style> | ||
12 | </head> | 13 | </head> |
13 | <body> | 14 | <body> |
14 | <main class="wrap"> | 15 | <main class="wrap"> |