mirror of
https://github.com/alecthomas/chroma.git
synced 2025-07-03 00:37:01 +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:
@ -4,6 +4,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
. "github.com/alecthomas/chroma" // nolint
|
. "github.com/alecthomas/chroma" // nolint
|
||||||
|
"github.com/alecthomas/chroma/lexers/h"
|
||||||
"github.com/alecthomas/chroma/lexers/internal"
|
"github.com/alecthomas/chroma/lexers/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ var Go = internal.Register(MustNewLexer(
|
|||||||
{`0[xX][0-9a-fA-F]+`, LiteralNumberHex, nil},
|
{`0[xX][0-9a-fA-F]+`, LiteralNumberHex, nil},
|
||||||
{`(0|[1-9][0-9]*)`, LiteralNumberInteger, 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},
|
{`'(\\['"\\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},
|
{`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
|
||||||
{`(<<=|>>=|<<|>>|<=|>=|&\^=|&\^|\+=|-=|\*=|/=|%=|&=|\|=|&&|\|\||<-|\+\+|--|==|!=|:=|\.\.\.|[+\-*/%&])`, Operator, nil},
|
{`(<<=|>>=|<<|>>|<=|>=|&\^=|&\^|\+=|-=|\*=|/=|%=|&=|\|=|&&|\|\||<-|\+\+|--|==|!=|:=|\.\.\.|[+\-*/%&])`, Operator, nil},
|
||||||
{`[|^<>=!()\[\]{}.,;:]`, Punctuation, nil},
|
{`[|^<>=!()\[\]{}.,;:]`, Punctuation, nil},
|
||||||
@ -54,3 +55,53 @@ var Go = internal.Register(MustNewLexer(
|
|||||||
}
|
}
|
||||||
return 0.0
|
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,
|
||||||
|
))
|
||||||
|
@ -195,7 +195,11 @@ func (l *LexerState) Iterator() *Token {
|
|||||||
if l.Lexer.trace {
|
if l.Lexer.trace {
|
||||||
fmt.Fprintf(os.Stderr, "%s: pos=%d, text=%q\n", l.State, l.Pos, string(l.Text[l.Pos:]))
|
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.
|
// No match.
|
||||||
if groups == nil {
|
if groups == nil {
|
||||||
l.Pos++
|
l.Pos++
|
||||||
|
6
remap.go
6
remap.go
@ -58,15 +58,21 @@ func TypeRemappingLexer(lexer Lexer, mapping TypeMapping) Lexer {
|
|||||||
km = map[string]TokenType{}
|
km = map[string]TokenType{}
|
||||||
lut[rt.From] = km
|
lut[rt.From] = km
|
||||||
}
|
}
|
||||||
|
if len(rt.Words) == 0 {
|
||||||
|
km[""] = rt.To
|
||||||
|
} else {
|
||||||
for _, k := range rt.Words {
|
for _, k := range rt.Words {
|
||||||
km[k] = rt.To
|
km[k] = rt.To
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return RemappingLexer(lexer, func(t *Token) []*Token {
|
return RemappingLexer(lexer, func(t *Token) []*Token {
|
||||||
if k, ok := lut[t.Type]; ok {
|
if k, ok := lut[t.Type]; ok {
|
||||||
if tt, ok := k[t.Value]; ok {
|
if tt, ok := k[t.Value]; ok {
|
||||||
t.Type = tt
|
t.Type = tt
|
||||||
|
} else if tt, ok := k[""]; ok {
|
||||||
|
t.Type = tt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return []*Token{t}
|
return []*Token{t}
|
||||||
|
Reference in New Issue
Block a user