*: more hackdoc updates

Change-Id: Ib9830c66fe36c423d38f447905c470b67cde5399
diff --git a/devtools/hackdoc/markdown.go b/devtools/hackdoc/markdown.go
index 911c2c0..fb46c5d 100644
--- a/devtools/hackdoc/markdown.go
+++ b/devtools/hackdoc/markdown.go
@@ -8,6 +8,7 @@
 
 	"code.hackerspace.pl/hscloud/devtools/hackdoc/config"
 
+	"github.com/gabriel-vasile/mimetype"
 	"github.com/golang/glog"
 	"gopkg.in/russross/blackfriday.v2"
 )
@@ -31,6 +32,7 @@
 				q["ref"] = []string{ref}
 				u.RawQuery = q.Encode()
 				node.Destination = []byte(u.String())
+				glog.Infof("link fix %q -> %q", dest, u.String())
 			}
 		}
 		return r.RenderNode(&buf, node, entering)
@@ -38,7 +40,12 @@
 	return buf.Bytes()
 }
 
-func (r *request) handleMarkdown(path string, cfg *config.Config) {
+type pathPart struct {
+	Label string
+	Path  string
+}
+
+func (r *request) handleFile(path string, cfg *config.Config) {
 	data, err := r.source.ReadFile(r.ctx, path)
 	if err != nil {
 		glog.Errorf("ReadFile(%q): %w", err)
@@ -46,30 +53,55 @@
 		return
 	}
 
-	rendered := renderMarkdown([]byte(data), r.ref)
+	// TODO(q3k): do MIME detection instead.
+	if strings.HasSuffix(path, ".md") {
+		rendered := renderMarkdown([]byte(data), r.ref)
 
-	r.logRequest("serving markdown at %s, cfg %+v", path, cfg)
+		r.logRequest("serving markdown at %s, cfg %+v", path, cfg)
 
-	// TODO(q3k): allow markdown files to override which template to load
-	tmpl, ok := cfg.Templates["default"]
-	if !ok {
-		glog.Errorf("No default template found for %s", path)
-		// TODO(q3k): implement fallback template
-		r.w.Write(rendered)
+		// TODO(q3k): allow markdown files to override which template to load
+		tmpl, ok := cfg.Templates["default"]
+		if !ok {
+			glog.Errorf("No default template found for %s", path)
+			// TODO(q3k): implement fallback template
+			r.w.Write(rendered)
+			return
+		}
+
+		pathInDepot := strings.TrimPrefix(path, "//")
+		pathParts := []pathPart{
+			{Label: "//", Path: "/"},
+		}
+		parts := strings.Split(pathInDepot, "/")
+		fullPath := ""
+		for i, p := range parts {
+			label := p
+			if i != len(parts)-1 {
+				label = label + "/"
+			}
+			fullPath += "/" + p
+			pathParts = append(pathParts, pathPart{Label: label, Path: fullPath})
+		}
+
+		vars := map[string]interface{}{
+			"Rendered":    template.HTML(rendered),
+			"Title":       path,
+			"Path":        path,
+			"PathInDepot": pathInDepot,
+			"PathParts":   pathParts,
+			"HackdocURL":  flagHackdocURL,
+			"WebLinks":    r.source.WebLinks(pathInDepot),
+		}
+		err = tmpl.Execute(r.w, vars)
+		if err != nil {
+			glog.Errorf("Could not execute template for %s: %v", err)
+		}
+
 		return
 	}
 
-	pathInDepot := strings.TrimPrefix(path, "//")
-	vars := map[string]interface{}{
-		"Rendered":    template.HTML(rendered),
-		"Title":       path,
-		"Path":        path,
-		"PathInDepot": pathInDepot,
-		"HackdocURL":  flagHackdocURL,
-		"WebLinks":    r.source.WebLinks(pathInDepot),
-	}
-	err = tmpl.Execute(r.w, vars)
-	if err != nil {
-		glog.Errorf("Could not execute template for %s: %v", err)
-	}
+	// Just serve the file.
+	mime := mimetype.Detect(data)
+	r.w.Header().Set("Content-Type", mime.String())
+	r.w.Write(data)
 }