| package main |
| |
| import ( |
| "bytes" |
| "html/template" |
| "net/url" |
| "strings" |
| |
| "code.hackerspace.pl/hscloud/devtools/hackdoc/config" |
| |
| "github.com/golang/glog" |
| "gopkg.in/russross/blackfriday.v2" |
| ) |
| |
| // renderMarkdown renders markdown to HTML, replacing all relative (intra-hackdoc) links with version that have ref set. |
| func renderMarkdown(input []byte, ref string) []byte { |
| r := blackfriday.NewHTMLRenderer(blackfriday.HTMLRendererParameters{ |
| Flags: blackfriday.CommonHTMLFlags, |
| }) |
| |
| parser := blackfriday.New(blackfriday.WithRenderer(r), blackfriday.WithExtensions(blackfriday.CommonExtensions)) |
| ast := parser.Parse(input) |
| |
| var buf bytes.Buffer |
| ast.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus { |
| if ref != "" && entering && node.Type == blackfriday.Link { |
| dest := string(node.Destination) |
| u, err := url.Parse(dest) |
| if err == nil && !u.IsAbs() { |
| q := u.Query() |
| q["ref"] = []string{ref} |
| u.RawQuery = q.Encode() |
| node.Destination = []byte(u.String()) |
| } |
| } |
| return r.RenderNode(&buf, node, entering) |
| }) |
| return buf.Bytes() |
| } |
| |
| func (r *request) handleMarkdown(path string, cfg *config.Config) { |
| data, err := r.source.ReadFile(r.ctx, path) |
| if err != nil { |
| glog.Errorf("ReadFile(%q): %w", err) |
| r.handle500() |
| return |
| } |
| |
| rendered := renderMarkdown([]byte(data), r.ref) |
| |
| 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) |
| 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) |
| } |
| } |