| # -*- coding: utf-8 -*- # |
| |
| module Rouge |
| module Lexers |
| load_lexer 'c.rb' |
| |
| class ObjectiveC < C |
| tag 'objective_c' |
| title "Objective-C" |
| desc 'an extension of C commonly used to write Apple software' |
| aliases 'objc' |
| filenames '*.m', '*.h' |
| |
| mimetypes 'text/x-objective_c', 'application/x-objective_c' |
| |
| def self.at_keywords |
| @at_keywords ||= %w( |
| selector private protected public encode synchronized try |
| throw catch finally end property synthesize dynamic optional |
| interface implementation import |
| ) |
| end |
| |
| def self.at_builtins |
| @at_builtins ||= %w(true false YES NO) |
| end |
| |
| def self.builtins |
| @builtins ||= %w(YES NO nil) |
| end |
| |
| def self.analyze_text(text) |
| return 1 if text =~ /@(end|implementation|protocol|property)\b/ |
| |
| id = /[a-z$_][a-z0-9$_]*/i |
| return 0.4 if text =~ %r( |
| \[ \s* #{id} \s+ |
| (?: |
| #{id} \s* \] |
| | #{id}? : |
| ) |
| )x |
| return 0.4 if text.include? '@"' |
| end |
| |
| id = /[a-z$_][a-z0-9$_]*/i |
| |
| prepend :statements do |
| rule /@"/, Str, :string |
| rule /@'(\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|\\.|[^\\'\n]')/, |
| Str::Char |
| rule /@(\d+[.]\d*|[.]\d+|\d+)e[+-]?\d+l?/i, |
| Num::Float |
| rule /@(\d+[.]\d*|[.]\d+|\d+f)f?/i, Num::Float |
| rule /@0x\h+[lL]?/, Num::Hex |
| rule /@0[0-7]+l?/i, Num::Oct |
| rule /@\d+l?/, Num::Integer |
| rule /\bin\b/, Keyword |
| |
| rule /@(?:interface|implementation)\b/ do |
| token Keyword |
| goto :classname |
| end |
| |
| rule /@(?:class|protocol)\b/ do |
| token Keyword |
| goto :forward_classname |
| end |
| |
| rule /@([[:alnum:]]+)/ do |m| |
| if self.class.at_keywords.include? m[1] |
| token Keyword |
| elsif self.class.at_builtins.include? m[1] |
| token Name::Builtin |
| else |
| token Error |
| end |
| end |
| |
| rule /[?]/, Punctuation, :ternary |
| rule /\[/, Punctuation, :message |
| rule /@\[/, Punctuation, :array_literal |
| rule /@\{/, Punctuation, :dictionary_literal |
| end |
| |
| state :ternary do |
| rule /:/, Punctuation, :pop! |
| mixin :statements |
| end |
| |
| state :message_shared do |
| rule /\]/, Punctuation, :pop! |
| rule /\{/, Punctuation, :pop! |
| rule /;/, Error |
| |
| mixin :statement |
| end |
| |
| state :message do |
| rule /(#{id})(\s*)(:)/ do |
| groups(Name::Function, Text, Punctuation) |
| goto :message_with_args |
| end |
| |
| rule /(#{id})(\s*)(\])/ do |
| groups(Name::Function, Text, Punctuation) |
| pop! |
| end |
| |
| mixin :message_shared |
| end |
| |
| state :message_with_args do |
| rule /\{/, Punctuation, :function |
| rule /(#{id})(\s*)(:)/ do |
| groups(Name::Function, Text, Punctuation) |
| pop! |
| end |
| |
| mixin :message_shared |
| end |
| |
| state :array_literal do |
| rule /]/, Punctuation, :pop! |
| rule /,/, Punctuation |
| mixin :statements |
| end |
| |
| state :dictionary_literal do |
| rule /}/, Punctuation, :pop! |
| rule /,/, Punctuation |
| mixin :statements |
| end |
| |
| state :classname do |
| mixin :whitespace |
| |
| rule /(#{id})(\s*)(:)(\s*)(#{id})/ do |
| groups(Name::Class, Text, |
| Punctuation, Text, |
| Name::Class) |
| pop! |
| end |
| |
| rule /(#{id})(\s*)([(])(\s*)(#{id})(\s*)([)])/ do |
| groups(Name::Class, Text, |
| Punctuation, Text, |
| Name::Label, Text, |
| Punctuation) |
| pop! |
| end |
| |
| rule id, Name::Class, :pop! |
| end |
| |
| state :forward_classname do |
| mixin :whitespace |
| |
| rule /(#{id})(\s*)(,)(\s*)/ do |
| groups(Name::Class, Text, Punctuation, Text) |
| push |
| end |
| |
| rule /(#{id})(\s*)(;?)/ do |
| groups(Name::Class, Text, Punctuation) |
| pop! |
| end |
| end |
| |
| prepend :root do |
| rule %r( |
| ([-+])(\s*) |
| ([(].*?[)])?(\s*) |
| (?=#{id}:?) |
| )ix do |m| |
| token Keyword, m[1]; token Text, m[2] |
| recurse m[3]; token Text, m[4] |
| push :method_definition |
| end |
| end |
| |
| state :method_definition do |
| rule /,/, Punctuation |
| rule /[.][.][.]/, Punctuation |
| rule /([(].*?[)])(#{id})/ do |m| |
| recurse m[1]; token Name::Variable, m[2] |
| end |
| |
| rule /(#{id})(\s*)(:)/m do |
| groups(Name::Function, Text, Punctuation) |
| end |
| |
| rule /;/, Punctuation, :pop! |
| |
| rule /{/ do |
| token Punctuation |
| goto :function |
| end |
| |
| mixin :inline_whitespace |
| rule %r(//.*?\n), Comment::Single |
| rule /\s+/m, Text |
| |
| rule(//) { pop! } |
| end |
| end |
| end |
| end |