summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/svelte.rb
blob: 733a23cc11a35a7b9736656965080c921ddda2e4 (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
# -*- coding: utf-8 -*- #
# frozen_string_literal: true

module Rouge
  module Lexers
    load_lexer 'html.rb'

    class Svelte < HTML
      desc 'Svelte single-file components (https://svelte.dev/)'
      tag 'svelte'
      filenames '*.svelte'
      mimetypes 'text/x-svelte', 'application/x-svelte'

      def initialize(*)
        super
        # todo add support for typescript script blocks
        @js = Javascript.new(options)
      end

      # Shorthand syntax for passing attributes - ex, `{src}` instead of `src={src}`
      prepend :tag do
        rule %r/(\{)\s*([a-zA-Z0-9_]+)\s*(})/m do
          groups Str::Interpol, Name::Variable, Str::Interpol
          pop!
        end
      end

      prepend :attr do
        # Duplicate template_start mixin here with a pop!
        # Because otherwise we'll never exit the attr state
        rule %r/\{/ do
          token Str::Interpol
          pop!
          push :template
        end
      end

      # handle templates within attribute single/double quotes
      prepend :dq do
        mixin :template_start
      end

      prepend :sq do
        mixin :template_start
      end

      prepend :root do
        # detect curly braces within HTML text (outside of tags/attributes)
        rule %r/([^<&{]*)(\{)(\s*)/ do
          groups Text, Str::Interpol, Text
          push :template
        end
      end

      state :template_start do
        # open template
        rule %r/\s*\{\s*/, Str::Interpol, :template
      end

      state :template do
        # template end
        rule %r/}/, Str::Interpol, :pop!

        # Allow JS lexer to handle matched curly braces within template
        rule(/(?<=^|[^\\])\{+.*?(?<=^|[^\\])\}+/) do
          delegate @js
        end

        # keywords
        rule %r/@(debug|html)\b/, Keyword
        rule %r/(#await)(.*)(then|catch)(\s+)(\w+)/ do |m|
          token Keyword, m[1]
          delegate @js, m[2]
          token Keyword, m[3]
          token Text, m[4]
          delegate @js, m[5]
        end
        rule %r/([#\/])(await|each|if|key)\b/, Keyword
        rule %r/(:else)(\s+)(if)?\b/ do
          groups Keyword, Text, Keyword
        end
        rule %r/:?(catch|then)\b/, Keyword

        # allow JS parser to handle anything that's not a curly brace
        rule %r/[^{}]+/ do
          delegate @js
        end
      end
    end
  end
end