summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/rouge-4.5.2/lib/rouge/lexers/vue.rb
blob: 5b64f3d037dfb010ddde743238f26ad38d3a5aad (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
# frozen_string_literal: true

module Rouge
  module Lexers
    load_lexer 'html.rb'

    class Vue < HTML
      desc 'Vue.js single-file components'
      tag 'vue'
      aliases 'vuejs'
      filenames '*.vue'

      mimetypes 'text/x-vue', 'application/x-vue'

      def initialize(*)
        super
        @js = Javascript.new(options)
      end

      def lookup_lang(lang)
        lang.downcase!
        lang = lang.gsub(/["']*/, '')
        case lang
        when 'html' then HTML
        when 'css' then CSS
        when 'javascript' then Javascript
        when 'sass' then Sass
        when 'scss' then Scss
        when 'coffee' then Coffeescript
          # TODO: add more when the lexers are done
        else
          PlainText
        end
      end

      start { @js.reset! }

      prepend :root do
        rule %r/(<)(\s*)(template)/ do
          groups Name::Tag, Text, Keyword
          @lang = HTML
          push :template
          push :lang_tag
        end

        rule %r/(<)(\s*)(style)/ do
          groups Name::Tag, Text, Keyword
          @lang = CSS
          push :style
          push :lang_tag
        end

        rule %r/(<)(\s*)(script)/ do
          groups Name::Tag, Text, Keyword
          @lang = Javascript
          push :script
          push :lang_tag
        end
      end

      prepend :tag do
        rule %r/[a-zA-Z0-9_:#\[\]()*.-]+\s*=\s*/m, Name::Attribute, :attr
      end

      state :style do
        rule %r/(<\s*\/\s*)(style)(\s*>)/ do
          groups Name::Tag, Keyword, Name::Tag
          pop!
        end

        mixin :style_content
        mixin :embed
      end

      state :script do
        rule %r/(<\s*\/\s*)(script)(\s*>)/ do
          groups Name::Tag, Keyword, Name::Tag
          pop!
        end

        mixin :script_content
        mixin :embed
      end

      state :lang_tag do
        rule %r/(lang\s*=)(\s*)("(?:\\.|[^\\])*?"|'(\\.|[^\\])*?'|[^\s>]+)/ do |m|
          groups Name::Attribute, Text, Str
          @lang = lookup_lang(m[3])
        end

        mixin :tag
      end

      state :template do
        rule %r((<\s*/\s*)(template)(\s*>)) do
          groups Name::Tag, Keyword, Name::Tag
          pop!
        end

        rule %r/{{/ do
          token Str::Interpol
          push :template_interpol
          @js.reset!
        end

        mixin :embed
      end

      state :template_interpol do
        rule %r/}}/, Str::Interpol, :pop!
        rule %r/}/, Error
        mixin :template_interpol_inner
      end

      state :template_interpol_inner do
        rule(/{/) { delegate @js; push }
        rule(/}/) { delegate @js; pop! }
        rule(/[^{}]+/) { delegate @js }
      end

      state :embed do
        rule(/[^{<]+/) { delegate @lang }
        rule(/[<{][^<{]*/) { delegate @lang }
      end
    end
  end
end