Stanislav N. aka pztrn
48d43ca097
Pagination now works. Temporary hardcoded 10 pastes per page, will be put in configuration later. Maybe. From now user will receive readable error message if error occured. Started to work on syntax highlighting, tried to make lexers detection work but apparently to no avail.
132 lines
3.3 KiB
Go
132 lines
3.3 KiB
Go
package h
|
|
|
|
import (
|
|
"strings"
|
|
|
|
. "github.com/alecthomas/chroma" // nolint
|
|
"github.com/alecthomas/chroma/lexers/internal"
|
|
)
|
|
|
|
// HTTP lexer.
|
|
var HTTP = internal.Register(httpBodyContentTypeLexer(MustNewLexer(
|
|
&Config{
|
|
Name: "HTTP",
|
|
Aliases: []string{"http"},
|
|
Filenames: []string{},
|
|
MimeTypes: []string{},
|
|
NotMultiline: true,
|
|
DotAll: true,
|
|
},
|
|
Rules{
|
|
"root": {
|
|
{`(GET|POST|PUT|DELETE|HEAD|OPTIONS|TRACE|PATCH|CONNECT)( +)([^ ]+)( +)(HTTP)(/)(1\.[01])(\r?\n|\Z)`, ByGroups(NameFunction, Text, NameNamespace, Text, KeywordReserved, Operator, LiteralNumber, Text), Push("headers")},
|
|
{`(HTTP)(/)(1\.[01])( +)(\d{3})( +)([^\r\n]+)(\r?\n|\Z)`, ByGroups(KeywordReserved, Operator, LiteralNumber, Text, LiteralNumber, Text, NameException, Text), Push("headers")},
|
|
},
|
|
"headers": {
|
|
{`([^\s:]+)( *)(:)( *)([^\r\n]+)(\r?\n|\Z)`, EmitterFunc(httpHeaderBlock), nil},
|
|
{`([\t ]+)([^\r\n]+)(\r?\n|\Z)`, EmitterFunc(httpContinuousHeaderBlock), nil},
|
|
{`\r?\n`, Text, Push("content")},
|
|
},
|
|
"content": {
|
|
{`.+`, EmitterFunc(httpContentBlock), nil},
|
|
},
|
|
},
|
|
)))
|
|
|
|
func httpContentBlock(groups []string, lexer Lexer) Iterator {
|
|
tokens := []*Token{
|
|
{Generic, groups[0]},
|
|
}
|
|
return Literator(tokens...)
|
|
|
|
}
|
|
|
|
func httpHeaderBlock(groups []string, lexer Lexer) Iterator {
|
|
tokens := []*Token{
|
|
{Name, groups[1]},
|
|
{Text, groups[2]},
|
|
{Operator, groups[3]},
|
|
{Text, groups[4]},
|
|
{Literal, groups[5]},
|
|
{Text, groups[6]},
|
|
}
|
|
return Literator(tokens...)
|
|
}
|
|
|
|
func httpContinuousHeaderBlock(groups []string, lexer Lexer) Iterator {
|
|
tokens := []*Token{
|
|
{Text, groups[1]},
|
|
{Literal, groups[2]},
|
|
{Text, groups[3]},
|
|
}
|
|
return Literator(tokens...)
|
|
}
|
|
|
|
func httpBodyContentTypeLexer(lexer Lexer) Lexer { return &httpBodyContentTyper{lexer} }
|
|
|
|
type httpBodyContentTyper struct{ Lexer }
|
|
|
|
func (d *httpBodyContentTyper) Tokenise(options *TokeniseOptions, text string) (Iterator, error) {
|
|
var contentType string
|
|
var isContentType bool
|
|
var subIterator Iterator
|
|
|
|
it, err := d.Lexer.Tokenise(options, text)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return func() *Token {
|
|
for token := it(); token != nil; token = it() {
|
|
switch {
|
|
case token.Type == Name && strings.ToLower(token.Value) == "content-type":
|
|
{
|
|
isContentType = true
|
|
}
|
|
case token.Type == Literal && isContentType:
|
|
{
|
|
contentType = strings.TrimSpace(token.Value)
|
|
pos := strings.Index(contentType, ";")
|
|
if pos > 0 {
|
|
contentType = strings.TrimSpace(contentType[:pos])
|
|
}
|
|
}
|
|
case token.Type == Generic && contentType != "":
|
|
{
|
|
lexer := internal.MatchMimeType(contentType)
|
|
|
|
// application/calendar+xml can be treated as application/xml
|
|
// if there's not a better match.
|
|
if lexer == nil && strings.Contains(contentType, "+") {
|
|
slashPos := strings.Index(contentType, "/")
|
|
plusPos := strings.LastIndex(contentType, "+")
|
|
contentType = contentType[:slashPos+1] + contentType[plusPos+1:]
|
|
lexer = internal.MatchMimeType(contentType)
|
|
}
|
|
|
|
if lexer == nil {
|
|
token.Type = Text
|
|
} else {
|
|
subIterator, err = lexer.Tokenise(nil, token.Value)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return token
|
|
}
|
|
|
|
if subIterator != nil {
|
|
for token := subIterator(); token != nil; token = subIterator() {
|
|
return token
|
|
}
|
|
}
|
|
return nil
|
|
|
|
}, nil
|
|
}
|