cmd/web: review fixes
* check extensions before content * explicitly denote enry hack until upstream fixes[1] * comment each case for the url parts deconstruction trick * use fname as title when no title exists * better title detection logic * kill a random empty line in inline CSS * rename sp (split) to pathComponents [1]: https://github.com/go-enry/go-enry/pull/154 Signed-off-by: Xe Iaso <xe@tailscale.com>
This commit is contained in:
parent
3e64cf9c05
commit
37727362e9
|
@ -449,15 +449,15 @@ func (s *Server) ShowPost(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sp := strings.Split(r.URL.Path, "/")
|
pathComponents := strings.Split(r.URL.Path, "/")
|
||||||
sp = sp[2:]
|
pathComponents = pathComponents[2:]
|
||||||
|
|
||||||
if len(sp) == 0 {
|
if len(pathComponents) == 0 {
|
||||||
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
|
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
id := sp[0]
|
id := pathComponents[0]
|
||||||
|
|
||||||
q := `
|
q := `
|
||||||
SELECT p.filename
|
SELECT p.filename
|
||||||
|
@ -483,19 +483,24 @@ WHERE p.id = ?1`
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lang, safe := enry.GetLanguageByContent(fname, []byte(data))
|
lang, safe := enry.GetLanguageByFilename(fname)
|
||||||
if !safe {
|
if !safe {
|
||||||
lang, _ = enry.GetLanguageByExtension(fname)
|
lang, _ = enry.GetLanguageByContent(fname, []byte(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
var rawHTML *template.HTML
|
var rawHTML *template.HTML
|
||||||
|
|
||||||
|
// XXX(Xe): HACK around https://github.com/go-enry/go-enry/pull/154
|
||||||
|
if filepath.Ext(fname) == ".markdown" {
|
||||||
|
lang = "Markdown"
|
||||||
|
}
|
||||||
|
|
||||||
var cssClass string
|
var cssClass string
|
||||||
if lang != "" {
|
if lang != "" {
|
||||||
cssClass = fmt.Sprintf("lang-%s", strings.ToLower(lang))
|
cssClass = fmt.Sprintf("lang-%s", strings.ToLower(lang))
|
||||||
}
|
}
|
||||||
|
|
||||||
if lang == "Markdown" || filepath.Ext(fname) == ".markdown" {
|
if lang == "Markdown" {
|
||||||
output := blackfriday.MarkdownCommon([]byte(data))
|
output := blackfriday.MarkdownCommon([]byte(data))
|
||||||
p := bluemonday.UGCPolicy()
|
p := bluemonday.UGCPolicy()
|
||||||
p.AllowAttrs("class").Matching(regexp.MustCompile("^language-[a-zA-Z0-9]+$")).OnElements("code")
|
p.AllowAttrs("class").Matching(regexp.MustCompile("^language-[a-zA-Z0-9]+$")).OnElements("code")
|
||||||
|
@ -504,8 +509,10 @@ WHERE p.id = ?1`
|
||||||
rawHTML = &raw
|
rawHTML = &raw
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(sp) != 1 {
|
// If you specify a formatting option:
|
||||||
switch sp[1] {
|
if len(pathComponents) != 1 {
|
||||||
|
switch pathComponents[1] {
|
||||||
|
// view file as plain text in browser
|
||||||
case "raw":
|
case "raw":
|
||||||
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(data)))
|
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(data)))
|
||||||
|
@ -513,6 +520,7 @@ WHERE p.id = ?1`
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
fmt.Fprint(w, data)
|
fmt.Fprint(w, data)
|
||||||
return
|
return
|
||||||
|
// download file to disk (plain text view plus download hint)
|
||||||
case "dl":
|
case "dl":
|
||||||
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%q", fname))
|
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%q", fname))
|
||||||
|
@ -520,15 +528,16 @@ WHERE p.id = ?1`
|
||||||
|
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
fmt.Fprint(w, data)
|
fmt.Fprint(w, data)
|
||||||
|
// view markdown file with a fancy HTML rendering step
|
||||||
case "md":
|
case "md":
|
||||||
if lang != "Markdown" {
|
if lang != "Markdown" {
|
||||||
http.Redirect(w, r, "/paste/"+id, http.StatusTemporaryRedirect)
|
http.Redirect(w, r, "/paste/"+id, http.StatusTemporaryRedirect)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
title, ok := yankTitle(data)
|
title, ok := strings.CutPrefix(strings.Split(strings.TrimSpace(data), "\n")[0], "#")
|
||||||
if !ok {
|
if !ok {
|
||||||
title = fmt.Sprintf("Post by %s")
|
title = fname
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.tmpls.ExecuteTemplate(w, "fancypost.tmpl", struct {
|
err = s.tmpls.ExecuteTemplate(w, "fancypost.tmpl", struct {
|
||||||
|
@ -548,6 +557,7 @@ WHERE p.id = ?1`
|
||||||
log.Printf("%s: %v", r.RemoteAddr, err)
|
log.Printf("%s: %v", r.RemoteAddr, err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
// otherwise, throw a 404
|
||||||
default:
|
default:
|
||||||
s.NotFound(w, r)
|
s.NotFound(w, r)
|
||||||
}
|
}
|
||||||
|
@ -583,24 +593,6 @@ WHERE p.id = ?1`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func yankTitle(input string) (string, bool) {
|
|
||||||
if !strings.HasPrefix(input, "#") {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
|
|
||||||
sp := strings.SplitN(input, "\n", 2)
|
|
||||||
|
|
||||||
if len(sp) != 2 {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
|
|
||||||
titleLine, _ := strings.CutPrefix(sp[0], "#")
|
|
||||||
|
|
||||||
titleLine = strings.TrimSpace(titleLine)
|
|
||||||
|
|
||||||
return titleLine, true
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
background: #fff;
|
background: #fff;
|
||||||
color: #333;
|
color: #333;
|
||||||
font: 16px/1.4 OpenDyslexic, Inter, Helvetica, Arial, sans-serif;
|
font: 16px/1.4 OpenDyslexic, Inter, Helvetica, Arial, sans-serif;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
|
Loading…
Reference in a new issue