source: code/trunk/vendor/github.com/alecthomas/chroma/v2/lexers/http.go@ 67

Last change on this file since 67 was 67, checked in by Izuru Yakumo, 23 months ago

Use vendored modules

Signed-off-by: Izuru Yakumo <yakumo.izuru@…>

File size: 3.3 KB
Line 
1package lexers
2
3import (
4 "strings"
5
6 . "github.com/alecthomas/chroma/v2" // nolint
7)
8
9// HTTP lexer.
10var HTTP = Register(httpBodyContentTypeLexer(MustNewLexer(
11 &Config{
12 Name: "HTTP",
13 Aliases: []string{"http"},
14 Filenames: []string{},
15 MimeTypes: []string{},
16 NotMultiline: true,
17 DotAll: true,
18 },
19 httpRules,
20)))
21
22func httpRules() Rules {
23 return Rules{
24 "root": {
25 {`(GET|POST|PUT|DELETE|HEAD|OPTIONS|TRACE|PATCH|CONNECT)( +)([^ ]+)( +)(HTTP)(/)([12]\.[01])(\r?\n|\Z)`, ByGroups(NameFunction, Text, NameNamespace, Text, KeywordReserved, Operator, LiteralNumber, Text), Push("headers")},
26 {`(HTTP)(/)([12]\.[01])( +)(\d{3})( +)([^\r\n]+)(\r?\n|\Z)`, ByGroups(KeywordReserved, Operator, LiteralNumber, Text, LiteralNumber, Text, NameException, Text), Push("headers")},
27 },
28 "headers": {
29 {`([^\s:]+)( *)(:)( *)([^\r\n]+)(\r?\n|\Z)`, EmitterFunc(httpHeaderBlock), nil},
30 {`([\t ]+)([^\r\n]+)(\r?\n|\Z)`, EmitterFunc(httpContinuousHeaderBlock), nil},
31 {`\r?\n`, Text, Push("content")},
32 },
33 "content": {
34 {`.+`, EmitterFunc(httpContentBlock), nil},
35 },
36 }
37}
38
39func httpContentBlock(groups []string, state *LexerState) Iterator {
40 tokens := []Token{
41 {Generic, groups[0]},
42 }
43 return Literator(tokens...)
44}
45
46func httpHeaderBlock(groups []string, state *LexerState) Iterator {
47 tokens := []Token{
48 {Name, groups[1]},
49 {Text, groups[2]},
50 {Operator, groups[3]},
51 {Text, groups[4]},
52 {Literal, groups[5]},
53 {Text, groups[6]},
54 }
55 return Literator(tokens...)
56}
57
58func httpContinuousHeaderBlock(groups []string, state *LexerState) Iterator {
59 tokens := []Token{
60 {Text, groups[1]},
61 {Literal, groups[2]},
62 {Text, groups[3]},
63 }
64 return Literator(tokens...)
65}
66
67func httpBodyContentTypeLexer(lexer Lexer) Lexer { return &httpBodyContentTyper{lexer} }
68
69type httpBodyContentTyper struct{ Lexer }
70
71func (d *httpBodyContentTyper) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { // nolint: gocognit
72 var contentType string
73 var isContentType bool
74 var subIterator Iterator
75
76 it, err := d.Lexer.Tokenise(options, text)
77 if err != nil {
78 return nil, err
79 }
80
81 return func() Token {
82 token := it()
83
84 if token == EOF {
85 if subIterator != nil {
86 return subIterator()
87 }
88 return EOF
89 }
90
91 switch {
92 case token.Type == Name && strings.ToLower(token.Value) == "content-type":
93 {
94 isContentType = true
95 }
96 case token.Type == Literal && isContentType:
97 {
98 isContentType = false
99 contentType = strings.TrimSpace(token.Value)
100 pos := strings.Index(contentType, ";")
101 if pos > 0 {
102 contentType = strings.TrimSpace(contentType[:pos])
103 }
104 }
105 case token.Type == Generic && contentType != "":
106 {
107 lexer := MatchMimeType(contentType)
108
109 // application/calendar+xml can be treated as application/xml
110 // if there's not a better match.
111 if lexer == nil && strings.Contains(contentType, "+") {
112 slashPos := strings.Index(contentType, "/")
113 plusPos := strings.LastIndex(contentType, "+")
114 contentType = contentType[:slashPos+1] + contentType[plusPos+1:]
115 lexer = MatchMimeType(contentType)
116 }
117
118 if lexer == nil {
119 token.Type = Text
120 } else {
121 subIterator, err = lexer.Tokenise(nil, token.Value)
122 if err != nil {
123 panic(err)
124 }
125 return EOF
126 }
127 }
128 }
129 return token
130 }, nil
131}
Note: See TracBrowser for help on using the repository browser.