# -*- coding: utf-8 -*- # # frozen_string_literal: true module Rouge module Lexers class Matlab < RegexLexer title "MATLAB" desc "Matlab" tag 'matlab' aliases 'm' filenames '*.m' mimetypes 'text/x-matlab', 'application/x-matlab' def self.keywords @keywords = Set.new %w( break case catch classdef continue else elseif end for function global if otherwise parfor persistent return spmd switch try while ) end def self.builtins # Load Matlab keywords from separate YML file @builtins ||= ::YAML.load_file(File.join(__dir__, 'matlab/builtins.yml')).tap do |a| Set.new a end end state :root do rule %r/\s+/m, Text # Whitespace rule %r([{]%.*?%[}])m, Comment::Multiline rule %r/%.*$/, Comment::Single rule %r/([.][.][.])(.*?)$/ do groups(Keyword, Comment) end rule %r/^(!)(.*?)(?=%|$)/ do |m| token Keyword, m[1] delegate Shell, m[2] end rule %r/[a-zA-Z][_a-zA-Z0-9]*/m do |m| match = m[0] if self.class.keywords.include? match token Keyword elsif self.class.builtins.include? match token Name::Builtin else token Name end end rule %r{[(){};:,\/\\\]\[]}, Punctuation rule %r/~=|==|<<|>>|[-~+\/*%=<>&^|.@]/, Operator rule %r/(\d+\.\d*|\d*\.\d+)(e[+-]?[0-9]+)?/i, Num::Float rule %r/\d+e[+-]?[0-9]+/i, Num::Float rule %r/\d+L/, Num::Integer::Long rule %r/\d+/, Num::Integer rule %r/'(?=(.*'))/, Str::Single, :chararray rule %r/"(?=(.*"))/, Str::Double, :string rule %r/'/, Operator end state :chararray do rule %r/[^']+/, Str::Single rule %r/''/, Str::Escape rule %r/'/, Str::Single, :pop! end state :string do rule %r/[^"]+/, Str::Double rule %r/""/, Str::Escape rule %r/"/, Str::Double, :pop! end end end end