summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/jinja.rb
blob: 15c28b715bdac1547e5e93f06f7e672a4ac1c6c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# -*- coding: utf-8 -*- #
# frozen_string_literal: true

module Rouge
  module Lexers
    class Jinja < TemplateLexer
      title "Jinja"
      desc "Django/Jinja template engine (jinja.pocoo.org)"

      tag 'jinja'
      aliases 'django'

      mimetypes 'application/x-django-templating', 'application/x-jinja',
                'text/html+django', 'text/html+jinja'

      def self.keywords
        @keywords ||= %w(as context do else extends from ignore missing
                         import include reversed recursive scoped
                         autoescape endautoescape block endblock call endcall
                         filter endfilter for endfor if endif macro endmacro
                         set endset trans endtrans with endwith without)
      end

      def self.tests
        @tests ||= %w(callable defined divisibleby equalto escaped even iterable
                      lower mapping none number odd sameas sequence string
                      undefined upper)
      end

      def self.pseudo_keywords
        @pseudo_keywords ||= %w(true false none True False None)
      end

      def self.word_operators
        @word_operators ||= %w(is in and or not)
      end

      state :root do
        # Comments
        rule %r/{#/, Comment, :comment
        rule %r/##.*/, Comment

        # Raw and verbatim
        rule %r/({%-?)(\s*)(raw|verbatim)(\s*)(-?%})/ do |m|
          groups Comment::Preproc, Text, Keyword, Text, Comment::Preproc
          case m[3]
          when "raw"
            push :raw
          when "verbatim"
            push :verbatim
          end
        end

        # Statements
        rule %r/\{\%/ do
          token Comment::Preproc
          push :statement
        end

        # Expressions
        rule %r/\{\{/ do
          token Comment::Preproc
          push :expression
        end

        rule(/(.+?)(?=\\|{{|{%|{#|##)/m) { delegate parent }
        rule(/.+/m) { delegate parent }
      end

      state :filter do
        # Filters are called like variable|foo(arg1, ...)
        rule %r/(\|\s*)(\w+)/ do
          groups Operator, Name::Function
        end
      end

      state :function do
        rule %r/(\w+)(\()/ do
          groups Name::Function, Punctuation
        end
      end

      state :text do
        rule %r/\s+/m, Text
      end

      state :literal do
        # Strings
        rule %r/"(\\.|.)*?"/, Str::Double
        rule %r/'(\\.|.)*?'/, Str::Single

        # Numbers
        rule %r/\d+(?=}\s)/, Num

        # Arithmetic operators (+, -, *, **, //, /)
        # TODO : implement modulo (%)
        rule %r/(\+|\-|\*|\/\/?|\*\*?|=)/, Operator

        # Comparisons operators (<=, <, >=, >, ==, ===, !=)
        rule %r/(<=?|>=?|===?|!=)/, Operator

        # Punctuation (the comma, [], ())
        rule %r/,/,  Punctuation
        rule %r/\[/, Punctuation
        rule %r/\]/, Punctuation
        rule %r/\(/, Punctuation
        rule %r/\)/, Punctuation
      end

      state :comment do
        rule %r/[^#]+/m, Comment
        rule(/#}/) { token Comment; pop! }
        rule %r/#/, Comment
      end

      state :expression do
        rule %r/\w+\.?/m, Name::Variable

        mixin :filter
        mixin :function
        mixin :literal
        mixin :text

        rule %r/%}|}}/, Comment::Preproc, :pop!
      end

      state :statement do
        rule %r/(\w+\.?)/ do |m|
          if self.class.keywords.include?(m[0])
            groups Keyword
          elsif self.class.pseudo_keywords.include?(m[0])
            groups Keyword::Pseudo
          elsif self.class.word_operators.include?(m[0])
            groups Operator::Word
          elsif self.class.tests.include?(m[0])
            groups Name::Builtin
          else
            groups Name::Variable
          end
        end

        mixin :filter
        mixin :function
        mixin :literal
        mixin :text

        rule %r/\%\}/, Comment::Preproc, :pop!
      end

      state :raw do
        rule %r/({%-?)(\s*)(endraw)(\s*)(-?%})/ do
          groups Comment::Preproc, Text, Keyword, Text, Comment::Preproc
          pop!
        end
        rule %r/[^{]+/, Text
        rule %r/{/, Text
      end

      state :verbatim do
        rule %r/({%-?)(\s*)(endverbatim)(\s*)(-?%})/ do
          groups Comment::Preproc, Text, Keyword, Text, Comment::Preproc
          pop!
        end
        rule %r/[^{]+/, Text
        rule %r/{/, Text
      end
    end
  end
end