diff --git a/cmd/chromad/main.go b/cmd/chromad/main.go
new file mode 100644
index 0000000..3d45353
--- /dev/null
+++ b/cmd/chromad/main.go
@@ -0,0 +1,183 @@
+package main
+
+import (
+ "html/template"
+ "log"
+ "net/http"
+ "sort"
+ "strings"
+
+ "github.com/alecthomas/kong"
+
+ "github.com/alecthomas/chroma"
+ "github.com/alecthomas/chroma/formatters/html"
+ "github.com/alecthomas/chroma/lexers"
+ "github.com/alecthomas/chroma/styles"
+)
+
+var htmlTemplate = template.Must(template.New("html").Parse(`
+
+
+
+ Chroma Playground
+
+
+
+
+
+
+ {{if .Error}}
{{.Error}}
{{end}}
+
+
Chroma Playground
+
+
+
+
+
+`))
+
+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 {
+ ctx.HTML = template.HTML(buf.String())
+ }
+ }
+
+ 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")
+ err := http.ListenAndServe(cli.Bind, http.HandlerFunc(handler))
+ ctx.FatalIfErrorf(err)
+}
diff --git a/go.mod b/go.mod
index 0c1cb0e..4a3ce96 100644
--- a/go.mod
+++ b/go.mod
@@ -4,12 +4,13 @@ require (
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 // indirect
github.com/alecthomas/kong v0.1.15
- github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 // indirect
+ github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964
github.com/dlclark/regexp2 v1.1.6
+ github.com/elliotchance/pepper v0.5.0 // indirect
github.com/mattn/go-colorable v0.0.9
github.com/mattn/go-isatty v0.0.4
github.com/sergi/go-diff v1.0.0 // indirect
- github.com/stretchr/testify v1.2.2
+ github.com/stretchr/testify v1.3.0
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 // indirect
)
diff --git a/go.sum b/go.sum
index 27210bb..59072dc 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,4 @@
+github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo=
@@ -6,12 +7,18 @@ github.com/alecthomas/kong v0.1.15 h1:IWBg+KrLvoHBicD50OzMI8fKjrtAa1okMR9g38HVM/
github.com/alecthomas/kong v0.1.15/go.mod h1:0m2VYms8rH0qbCqVB2gvGHk74bqLIq0HXjCs5bNbNQU=
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY=
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
+github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dlclark/regexp2 v1.1.6 h1:CqB4MjHw0MFCDj+PHHjiESmHX+N7t0tJzKvC6M97BRg=
github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
+github.com/elliotchance/pepper v0.5.0 h1:ZwjtgTvqM43Z6Rxla47peIKDo+/ec5zTpQADbXoa3q0=
+github.com/elliotchance/pepper v0.5.0/go.mod h1:m8ad8rNGcEp8pvLUgqCFPRO38n7QCEpuZStlGT1owf4=
+github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
+github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
@@ -20,7 +27,12 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 h1:YAFjXN64LMvktoUZH9zgY4lGc/msGN7HQfoSuKCgaDU=
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=