diff --git a/formatters/html/html.go b/formatters/html/html.go index c1919a47c..3f68a7db9 100644 --- a/formatters/html/html.go +++ b/formatters/html/html.go @@ -91,11 +91,6 @@ func (h highlightRanges) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h highlightRanges) Less(i, j int) bool { return h[i][0] < h[j][0] } func (f *Formatter) Format(w io.Writer, style *chroma.Style, iterator chroma.Iterator) (err error) { - defer func() { - if perr := recover(); perr != nil { - err = perr.(error) - } - }() return f.writeHTML(w, style, iterator.Tokens()) } diff --git a/formatters/html/html_test.go b/formatters/html/html_test.go index 36e744684..6f10f291e 100644 --- a/formatters/html/html_test.go +++ b/formatters/html/html_test.go @@ -2,7 +2,6 @@ package html import ( "bytes" - "errors" "io/ioutil" "strings" "testing" @@ -50,14 +49,6 @@ func TestSplitTokensIntoLines(t *testing.T) { assert.Equal(t, expected, actual) } -func TestIteratorPanicRecovery(t *testing.T) { - it := func() chroma.Token { - panic(errors.New("bad")) - } - err := New().Format(ioutil.Discard, styles.Fallback, it) - assert.Error(t, err) -} - func TestFormatterStyleToCSS(t *testing.T) { builder := styles.Get("github").Builder() builder.Add(chroma.LineHighlight, "bg:#ffffcc") diff --git a/formatters/svg/svg.go b/formatters/svg/svg.go index 4321c6594..631fa1484 100644 --- a/formatters/svg/svg.go +++ b/formatters/svg/svg.go @@ -62,11 +62,6 @@ type Formatter struct { } func (f *Formatter) Format(w io.Writer, style *chroma.Style, iterator chroma.Iterator) (err error) { - defer func() { - if perr := recover(); perr != nil { - err = perr.(error) - } - }() f.writeSVG(w, style, iterator.Tokens()) return err } diff --git a/formatters/tty_indexed.go b/formatters/tty_indexed.go index 6354cc456..eb90ea7c0 100644 --- a/formatters/tty_indexed.go +++ b/formatters/tty_indexed.go @@ -225,11 +225,6 @@ type indexedTTYFormatter struct { } func (c *indexedTTYFormatter) Format(w io.Writer, style *chroma.Style, it chroma.Iterator) (err error) { - defer func() { - if perr := recover(); perr != nil { - err = perr.(error) - } - }() theme := styleToEscapeSequence(c.table, style) for token := it(); token != chroma.EOF; token = it() { // TODO: Cache token lookups? diff --git a/go.mod b/go.mod index 116d86a75..fdacf0782 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/gorilla/mux v1.7.3 github.com/mattn/go-colorable v0.0.9 github.com/mattn/go-isatty v0.0.4 + github.com/pkg/errors v0.8.1 github.com/sergi/go-diff v1.0.0 // indirect github.com/stretchr/testify v1.3.0 golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 // indirect diff --git a/lexers/b/ballerina.go b/lexers/b/ballerina.go index 40aaa5259..91dc90179 100644 --- a/lexers/b/ballerina.go +++ b/lexers/b/ballerina.go @@ -25,7 +25,7 @@ var Ballerina = internal.Register(MustNewLexer( {`(annotation|bind|but|endpoint|error|function|object|private|public|returns|service|type|var|with|worker)\b`, KeywordDeclaration, nil}, {`(boolean|byte|decimal|float|int|json|map|nil|record|string|table|xml)\b`, KeywordType, nil}, {`(true|false|null)\b`, KeywordConstant, nil}, - {`import(\s+)`, ByGroups(KeywordNamespace, Text), Push("import")}, + {`(import)(\s+)`, ByGroups(KeywordNamespace, Text), Push("import")}, {`"(\\\\|\\"|[^"])*"`, LiteralString, nil}, {`'\\.'|'[^\\]'|'\\u[0-9a-fA-F]{4}'`, LiteralStringChar, nil}, {`(\.)((?:[^\W\d]|\$)[\w$]*)`, ByGroups(Operator, NameAttribute), nil}, diff --git a/lexers/d/docker.go b/lexers/d/docker.go index 75c882b5e..a650eba5f 100644 --- a/lexers/d/docker.go +++ b/lexers/d/docker.go @@ -22,7 +22,7 @@ var Docker = internal.Register(MustNewLexer( {`(ONBUILD)((?:\s*\\?\s*))`, ByGroups(Keyword, Using(b.Bash)), nil}, {`(HEALTHCHECK)(((?:\s*\\?\s*)--\w+=\w+(?:\s*\\?\s*))*)`, ByGroups(Keyword, Using(b.Bash)), nil}, {`(VOLUME|ENTRYPOINT|CMD|SHELL)((?:\s*\\?\s*))(\[.*?\])`, ByGroups(Keyword, Using(b.Bash), Using(j.JSON)), nil}, - {`(LABEL|ENV|ARG)(((?:\s*\\?\s*)\w+=\w+(?:\s*\\?\s*))*)`, ByGroups(Keyword, Using(b.Bash)), nil}, + {`(LABEL|ENV|ARG)((?:(?:\s*\\?\s*)\w+=\w+(?:\s*\\?\s*))*)`, ByGroups(Keyword, Using(b.Bash)), nil}, {`((?:FROM|MAINTAINER|EXPOSE|WORKDIR|USER|STOPSIGNAL)|VOLUME)\b(.*)`, ByGroups(Keyword, LiteralString), nil}, {`((?:RUN|CMD|ENTRYPOINT|ENV|ARG|LABEL|ADD|COPY))`, Keyword, nil}, {`(.*\\\n)*.+`, Using(b.Bash), nil}, diff --git a/lexers/testdata/ballerina.expected b/lexers/testdata/ballerina.expected index f3b491cd1..0a520874e 100644 --- a/lexers/testdata/ballerina.expected +++ b/lexers/testdata/ballerina.expected @@ -1,5 +1,6 @@ [ - {"type":"KeywordNamespace","value":" "}, + {"type":"KeywordNamespace","value":"import"}, + {"type":"Text","value":" "}, {"type":"NameNamespace","value":"ballerina"}, {"type":"Operator","value":"/"}, {"type":"Name","value":"http"}, diff --git a/regexp.go b/regexp.go index 59126db73..9756fe874 100644 --- a/regexp.go +++ b/regexp.go @@ -35,8 +35,13 @@ func ByGroups(emitters ...Emitter) Emitter { return EmitterFunc(func(groups []string, lexer Lexer) Iterator { iterators := make([]Iterator, 0, len(groups)-1) // NOTE: If this panics, there is a mismatch with groups - for i, group := range groups[1:] { - iterators = append(iterators, emitters[i].Emit([]string{group}, lexer)) + if len(emitters) != len(groups)-1 { + iterators = append(iterators, Error.Emit(groups, lexer)) + // panic(errors.Errorf("number of groups %q does not match number of emitters %v", groups, emitters)) + } else { + for i, group := range groups[1:] { + iterators = append(iterators, emitters[i].Emit([]string{group}, lexer)) + } } return Concaterator(iterators...) })