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

Add support for Go templates.

These are exposed as go-text-template and go-html-template.

Fixes #105.
This commit is contained in:
Alec Thomas 2018-03-18 21:57:34 +11:00
parent db6920e68f
commit f315512f5c
3 changed files with 65 additions and 4 deletions

View File

@ -4,6 +4,7 @@ import (
"strings"
. "github.com/alecthomas/chroma" // nolint
"github.com/alecthomas/chroma/lexers/h"
"github.com/alecthomas/chroma/lexers/internal"
)
@ -38,7 +39,7 @@ var Go = internal.Register(MustNewLexer(
{`0[xX][0-9a-fA-F]+`, LiteralNumberHex, nil},
{`(0|[1-9][0-9]*)`, LiteralNumberInteger, nil},
{`'(\\['"\\abfnrtv]|\\x[0-9a-fA-F]{2}|\\[0-7]{1,3}|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|[^\\])'`, LiteralStringChar, nil},
{"`[^`]*`", LiteralString, nil},
{"(`)([^`]*)(`)", ByGroups(LiteralString, Using(TypeRemappingLexer(GoTextTemplate, TypeMapping{{Other, LiteralString, nil}})), LiteralString), nil},
{`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
{`(<<=|>>=|<<|>>|<=|>=|&\^=|&\^|\+=|-=|\*=|/=|%=|&=|\|=|&&|\|\||<-|\+\+|--|==|!=|:=|\.\.\.|[+\-*/%&])`, Operator, nil},
{`[|^<>=!()\[\]{}.,;:]`, Punctuation, nil},
@ -54,3 +55,53 @@ var Go = internal.Register(MustNewLexer(
}
return 0.0
}))
var goTemplateRules = Rules{
"root": {
{`{{[-]?`, CommentPreproc, Push("template")},
{`[^{]+`, Other, nil},
{`{`, Other, nil},
},
"template": {
{`[-]?}}`, CommentPreproc, Pop(1)},
{`\s+`, Whitespace, nil},
{`/\*.*?\*/`, Comment, nil},
{`(?=}})`, CommentPreproc, Pop(1)}, // Terminate the pipeline
{`\(`, Operator, Push("subexpression")},
{`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
Include("expression"),
},
"subexpression": {
{`\)`, Operator, Pop(1)},
Include("expression"),
},
"expression": {
{`\(`, Operator, Push("subexpression")},
{`(if|while|with|template|end|true|false|nil|and|call|html|index|js|len|not|or|print|printf|println|urlquery|eq|ne|lt|le|gt|ge)\b`, Keyword, nil},
{`\|`, Operator, nil},
{`[^\W\d]\w*`, NameOther, nil},
{`\.(?:[^\W\d]\w*)?`, NameAttribute, nil},
{`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
{`\d+i`, LiteralNumber, nil},
{`\d+\.\d*([Ee][-+]\d+)?i`, LiteralNumber, nil},
{`\.\d+([Ee][-+]\d+)?i`, LiteralNumber, nil},
{`\d+[Ee][-+]\d+i`, LiteralNumber, nil},
{`\d+(\.\d+[eE][+\-]?\d+|\.\d*|[eE][+\-]?\d+)`, LiteralNumberFloat, nil},
{`\.\d+([eE][+\-]?\d+)?`, LiteralNumberFloat, nil},
{`0[0-7]+`, LiteralNumberOct, nil},
{`0[xX][0-9a-fA-F]+`, LiteralNumberHex, nil},
{`(0|[1-9][0-9]*)`, LiteralNumberInteger, nil},
{`'(\\['"\\abfnrtv]|\\x[0-9a-fA-F]{2}|\\[0-7]{1,3}|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|[^\\])'`, LiteralStringChar, nil},
{"`[^`]*`", LiteralString, nil},
},
}
var GoHTMLTemplate = internal.Register(DelegatingLexer(h.HTML, MustNewLexer(
&Config{Name: "go-html-template"},
goTemplateRules,
)))
var GoTextTemplate = internal.Register(MustNewLexer(
&Config{Name: "go-text-template"},
goTemplateRules,
))

View File

@ -195,7 +195,11 @@ func (l *LexerState) Iterator() *Token {
if l.Lexer.trace {
fmt.Fprintf(os.Stderr, "%s: pos=%d, text=%q\n", l.State, l.Pos, string(l.Text[l.Pos:]))
}
ruleIndex, rule, groups := matchRules(l.Text[l.Pos:], l.Rules[l.State])
selectedRule, ok := l.Rules[l.State]
if !ok {
panic("unknown state " + l.State)
}
ruleIndex, rule, groups := matchRules(l.Text[l.Pos:], selectedRule)
// No match.
if groups == nil {
l.Pos++

View File

@ -58,8 +58,12 @@ func TypeRemappingLexer(lexer Lexer, mapping TypeMapping) Lexer {
km = map[string]TokenType{}
lut[rt.From] = km
}
for _, k := range rt.Words {
km[k] = rt.To
if len(rt.Words) == 0 {
km[""] = rt.To
} else {
for _, k := range rt.Words {
km[k] = rt.To
}
}
}
@ -67,6 +71,8 @@ func TypeRemappingLexer(lexer Lexer, mapping TypeMapping) Lexer {
if k, ok := lut[t.Type]; ok {
if tt, ok := k[t.Value]; ok {
t.Type = tt
} else if tt, ok := k[""]; ok {
t.Type = tt
}
}
return []*Token{t}