| @@ -53,6 +53,7 @@ func (s *Server) siteName() string { |
| 53 | 53 | func (s *Server) stylesheet(w http.ResponseWriter, r *http.Request) { |
| 54 | 54 | w.Header().Set("Content-Type", "text/css; charset=utf-8") |
| 55 | 55 | w.Write(web.StyleCSS) |
| 56 | w.Write(chromaCSS) |
| 56 | 57 | } |
| 57 | 58 | |
| 58 | 59 | func (s *Server) favicon(w http.ResponseWriter, r *http.Request) { |
| @@ -734,25 +735,40 @@ type numberedLine struct { |
| 734 | 735 | Text string |
| 735 | 736 | } |
| 736 | 737 | |
| 738 | // chromaFormatter emits class-based markup (no inline colors), so the |
| 739 | // stylesheet can swap palettes with the color scheme. |
| 740 | var chromaFormatter = html.New(html.WithClasses(true), |
| 741 | html.WithLineNumbers(true), html.LineNumbersInTable(false), |
| 742 | html.WithLinkableLineNumbers(true, "L")) |
| 743 | |
| 737 | 744 | func highlight(filePath string, data []byte) template.HTML { |
| 738 | 745 | lexer := lexers.Match(filePath) |
| 739 | 746 | if lexer == nil { |
| 740 | 747 | lexer = lexers.Fallback |
| 741 | 748 | } |
| 742 | | style := styles.Get("friendly") |
| 743 | | formatter := html.New(html.WithLineNumbers(true), html.LineNumbersInTable(false), |
| 744 | | html.WithLinkableLineNumbers(true, "L")) |
| 745 | 749 | iterator, err := lexer.Tokenise(nil, string(data)) |
| 746 | 750 | if err != nil { |
| 747 | 751 | return template.HTML("<pre>" + template.HTMLEscapeString(string(data)) + "</pre>") |
| 748 | 752 | } |
| 749 | 753 | var buf bytes.Buffer |
| 750 | | if err := formatter.Format(&buf, style, iterator); err != nil { |
| 754 | if err := chromaFormatter.Format(&buf, styles.Get("friendly"), iterator); err != nil { |
| 751 | 755 | return template.HTML("<pre>" + template.HTMLEscapeString(string(data)) + "</pre>") |
| 752 | 756 | } |
| 753 | 757 | return template.HTML(buf.String()) |
| 754 | 758 | } |
| 755 | 759 | |
| 760 | // chromaCSS is both syntax palettes: light by default, dark under the same |
| 761 | // media query the rest of the stylesheet uses. The site's --code-bg stays |
| 762 | // the background either way. |
| 763 | var chromaCSS = func() []byte { |
| 764 | var buf bytes.Buffer |
| 765 | chromaFormatter.WriteCSS(&buf, styles.Get("friendly")) |
| 766 | buf.WriteString("\n@media (prefers-color-scheme: dark) {\n") |
| 767 | chromaFormatter.WriteCSS(&buf, styles.Get("github-dark")) |
| 768 | buf.WriteString("}\n.chroma, .bg { background: var(--code-bg) !important; }\n") |
| 769 | return buf.Bytes() |
| 770 | }() |
| 771 | |
| 756 | 772 | func (s *Server) raw(w http.ResponseWriter, r *http.Request) { |
| 757 | 773 | p, ok := s.repoFor(w, r, r.PathValue("ref")) |
| 758 | 774 | if !ok { |