lib/rouge/lexers/svelte.rb
# -*- 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