Permalink
Browse files

Add server-side syntax highlighting

Fixes #1
  • Loading branch information...
emersion committed Aug 5, 2018
1 parent 5990aed commit d21e143baaa1ffb35e2ba28e2190bfc7520790a7
Showing with 89 additions and 13 deletions.
  1. +3 −0 go.mod
  2. +72 −4 matcha.go
  3. +5 −1 public/views/blob.html
  4. +9 −3 public/views/commit.html
  5. +0 −5 public/views/head.html
3 go.mod

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -1,13 +1,18 @@
package matcha

import (
"bytes"
"html/template"
"net/http"
"path"
"path/filepath"
"sort"
"strings"

"github.com/alecthomas/chroma"
"github.com/alecthomas/chroma/formatters"
"github.com/alecthomas/chroma/lexers"
"github.com/alecthomas/chroma/styles"
"github.com/labstack/echo"
"github.com/russross/blackfriday"
"gopkg.in/src-d/go-git.v4"
@@ -282,7 +287,7 @@ func (s *server) blob(c echo.Context, revName, p string) error {
Revision string
Filepath, Filename, Extension string
Parents []breadcumbItem
IsBinary bool
IsBinary, IsText bool
Rendered template.HTML
Contents string
}
@@ -313,6 +318,35 @@ func (s *server) blob(c echo.Context, revName, p string) error {
case "md", "markdown":
rendered := blackfriday.MarkdownCommon([]byte(contents))
data.Rendered = template.HTML(string(rendered))
data.IsText = true
default:
lexer := lexers.Match(filename)
if lexer == nil {
lexer = lexers.Fallback
}
lexer = chroma.Coalesce(lexer)

style := styles.Get("github")
if style == nil {
style = styles.Fallback
}

formatter := formatters.Get("html")
if formatter == nil {
formatter = formatters.Fallback
}

iterator, err := lexer.Tokenise(nil, contents)
if err != nil {
return err
}

var buf bytes.Buffer
if err := formatter.Format(&buf, style, iterator); err != nil {
return err
}

data.Rendered = template.HTML(buf.String())
}
}

@@ -467,8 +501,9 @@ func (s *server) commit(c echo.Context, hash string) error {

var data struct {
*headerData
Commit *object.Commit
Diff string
Commit *object.Commit
Diff string
RenderedDiff template.HTML
}

data.headerData = s.headerData(c)
@@ -487,6 +522,34 @@ func (s *server) commit(c echo.Context, hash string) error {
}

data.Diff = patch.String()

lexer := lexers.Get("patch")
if lexer == nil {
lexer = lexers.Fallback
}
lexer = chroma.Coalesce(lexer)

style := styles.Get("github")
if style == nil {
style = styles.Fallback
}

formatter := formatters.Get("html")
if formatter == nil {
formatter = formatters.Fallback
}

iterator, err := lexer.Tokenise(nil, data.Diff)
if err != nil {
return err
}

var buf bytes.Buffer
if err := formatter.Format(&buf, style, iterator); err != nil {
return err
}

data.RenderedDiff = template.HTML(buf.String())
}

return c.Render(http.StatusOK, "commit.html", data)
@@ -521,10 +584,15 @@ func New(e *echo.Echo, dir string) error {
return err
}

repoPath := ""
if len(reqParts[:i]) > 0 {
repoPath = "/"+path.Join(reqParts[:i]...)
}

req.URL.Path = "/" + path.Join(reqParts[i:]...)
c.Set("repo", r)
c.Set("repo-name", parts[len(dirParts)+i-1])
c.Set("repo-path", "/"+path.Join(reqParts[:i]...))
c.Set("repo-path", repoPath)
return next(c)
}

@@ -20,12 +20,16 @@ <h3>Cannot preview file</h3>
<p>You can download it by clicking on "Raw".</p>
</div>
{{else}}
{{if .Rendered}}
{{if and .IsText .Rendered}}
<div class="Box Box--condensed">
<div class="Box-body markdown-body">
{{.Rendered}}
</div>
</div>
{{else if .Rendered}}
<div class="markdown-body">
{{.Rendered}}
</div>
{{else}}
<div class="markdown-body">
<pre><code class="language-{{.Extension}}">{{.Contents}}</code></pre>
@@ -18,8 +18,14 @@ <h3>{{.Message | commitSummary}}</h3>

<p></p>

<div class="markdown-body">
<pre><code class="language-diff">{{.Diff}}</code></pre>
</div>
{{if .RenderedDiff}}
<div class="markdown-body">
{{.RenderedDiff}}
</div>
{{else}}
<div class="markdown-body">
<pre><code class="language-diff">{{.Diff}}</code></pre>
</div>
{{end}}

{{template "footer.html"}}
@@ -7,11 +7,6 @@
<link rel="stylesheet" href="/static/primer-css/build/build.css">
<link rel="stylesheet" href="/static/primer-utilities/build/build.css">
<link rel="stylesheet" href="/static/octicons/build/octicons.min.css">

<!-- TODO: use local version of highlight.js, or switch to server-side rendering -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</head>
<body>
<div class="container">

0 comments on commit d21e143

Please sign in to comment.