devtools/hackdoc: init

This is hackdoc, a documentation rendering tool for monorepos.

This is the first code iteration, that can only serve from a local git
checkout.

The code is incomplete, and is WIP.

Change-Id: I68ef7a991191c1bb1b0fdd2a8d8353aba642e28f
diff --git a/devtools/hackdoc/markdown.go b/devtools/hackdoc/markdown.go
new file mode 100644
index 0000000..da52aa5
--- /dev/null
+++ b/devtools/hackdoc/markdown.go
@@ -0,0 +1,49 @@
+package main
+
+import (
+	"fmt"
+	"html/template"
+	"net/http"
+	"strings"
+
+	"code.hackerspace.pl/hscloud/devtools/hackdoc/config"
+	"code.hackerspace.pl/hscloud/devtools/hackdoc/source"
+
+	"github.com/golang/glog"
+	"gopkg.in/russross/blackfriday.v2"
+)
+
+func (s *service) handleMarkdown(w http.ResponseWriter, r *http.Request, src source.Source, branch, path string, cfg *config.Config) {
+	data, err := src.ReadFile(path)
+	if err != nil {
+		glog.Errorf("ReadFile(%q): %w", err)
+		handle500(w, r)
+		return
+	}
+
+	rendered := blackfriday.Run([]byte(data))
+
+	logRequest(w, r, "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
+		w.Write(rendered)
+		return
+	}
+
+	vars := map[string]interface{}{
+		"Rendered":    template.HTML(rendered),
+		"Title":       path,
+		"Path":        path,
+		"PathInDepot": strings.TrimPrefix(path, "//"),
+		"HackdocURL":  flagHackdocURL,
+		"GitwebURL":   fmt.Sprintf(flagGitwebURLPattern, flagGitwebDefaultBranch, strings.TrimPrefix(path, "//")),
+	}
+	err = tmpl.Execute(w, vars)
+	if err != nil {
+		glog.Errorf("Could not execute template for %s: %v", err)
+	}
+}