1
0
mirror of https://github.com/alecthomas/chroma.git synced 2025-03-21 21:17:50 +02:00

117 lines
2.6 KiB
Go
Raw Normal View History

package main
import (
"html/template"
"log"
"net/http"
"sort"
"strings"
2019-07-16 15:45:06 +10:00
rice "github.com/GeertJohan/go.rice"
"github.com/alecthomas/kong"
2019-07-16 15:45:06 +10:00
"github.com/gorilla/mux"
"github.com/alecthomas/chroma"
"github.com/alecthomas/chroma/formatters/html"
"github.com/alecthomas/chroma/lexers"
"github.com/alecthomas/chroma/styles"
)
2019-07-16 15:45:06 +10:00
var (
templateFiles = rice.MustFindBox("templates")
staticFiles = rice.MustFindBox("static")
2019-07-16 15:45:06 +10:00
htmlTemplate = template.Must(template.New("html").Parse(templateFiles.MustString("index.html.tmpl")))
)
var cli struct {
Bind string `help:"HTTP bind address." default:"127.0.0.1:8080"`
}
type context struct {
Background template.CSS
SelectedLanguage string
Languages []string
SelectedStyle string
Styles []string
Text string
HTML template.HTML
Error string
}
func handler(w http.ResponseWriter, r *http.Request) {
ctx := contextFromRequest(r)
style := styles.Get(ctx.SelectedStyle)
if style == nil {
style = styles.Fallback
}
ctx.Background = template.CSS(html.StyleEntryToCSS(style.Get(chroma.Background)))
language := lexers.Get(ctx.SelectedLanguage)
if language == nil {
language = lexers.Analyse(ctx.Text)
if language != nil {
ctx.SelectedLanguage = language.Config().Name
}
}
if language == nil {
language = lexers.Fallback
}
tokens, err := language.Tokenise(nil, ctx.Text)
if err != nil {
ctx.Error = err.Error()
} else {
buf := &strings.Builder{}
formatter := html.New()
err = formatter.Format(buf, style, tokens)
if err != nil {
ctx.Error = err.Error()
} else {
2019-07-16 14:26:56 +10:00
ctx.HTML = template.HTML(buf.String()) // nolint: gosec
}
}
err = htmlTemplate.Execute(w, &ctx)
if err != nil {
panic(err)
}
}
func contextFromRequest(r *http.Request) context {
err := r.ParseForm()
ctx := context{
SelectedLanguage: r.Form.Get("language"),
SelectedStyle: r.Form.Get("style"),
Text: r.Form.Get("text"),
}
if err != nil {
ctx.Error = err.Error()
return ctx
}
if ctx.SelectedStyle == "" {
ctx.SelectedStyle = "monokailight"
}
for _, lexer := range lexers.Registry.Lexers {
ctx.Languages = append(ctx.Languages, lexer.Config().Name)
}
sort.Strings(ctx.Languages)
for _, style := range styles.Registry {
ctx.Styles = append(ctx.Styles, style.Name)
}
sort.Strings(ctx.Styles)
return ctx
}
func main() {
ctx := kong.Parse(&cli)
log.Println("Starting")
2019-07-16 15:45:06 +10:00
router := mux.NewRouter()
router.Handle("/", http.HandlerFunc(handler))
router.Handle("/static/{file:.*}", http.StripPrefix("/static/", http.FileServer(staticFiles.HTTPBox())))
err := http.ListenAndServe(cli.Bind, router)
ctx.FatalIfErrorf(err)
}