gitlab-rouge 1.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +23 -0
  3. data/LICENSE +186 -0
  4. data/bin/rougify +16 -0
  5. data/gitlab-rouge.gemspec +17 -0
  6. data/lib/rouge.rb +57 -0
  7. data/lib/rouge/cli.rb +363 -0
  8. data/lib/rouge/demos/apache +21 -0
  9. data/lib/rouge/demos/applescript +2 -0
  10. data/lib/rouge/demos/c +8 -0
  11. data/lib/rouge/demos/clojure +5 -0
  12. data/lib/rouge/demos/coffeescript +5 -0
  13. data/lib/rouge/demos/common_lisp +1 -0
  14. data/lib/rouge/demos/conf +4 -0
  15. data/lib/rouge/demos/cpp +8 -0
  16. data/lib/rouge/demos/csharp +5 -0
  17. data/lib/rouge/demos/css +4 -0
  18. data/lib/rouge/demos/dart +6 -0
  19. data/lib/rouge/demos/diff +7 -0
  20. data/lib/rouge/demos/elixir +1 -0
  21. data/lib/rouge/demos/erb +1 -0
  22. data/lib/rouge/demos/erlang +7 -0
  23. data/lib/rouge/demos/factor +5 -0
  24. data/lib/rouge/demos/gherkin +17 -0
  25. data/lib/rouge/demos/glsl +14 -0
  26. data/lib/rouge/demos/go +7 -0
  27. data/lib/rouge/demos/groovy +9 -0
  28. data/lib/rouge/demos/haml +5 -0
  29. data/lib/rouge/demos/handlebars +7 -0
  30. data/lib/rouge/demos/haskell +6 -0
  31. data/lib/rouge/demos/html +8 -0
  32. data/lib/rouge/demos/http +14 -0
  33. data/lib/rouge/demos/ini +4 -0
  34. data/lib/rouge/demos/io +11 -0
  35. data/lib/rouge/demos/java +5 -0
  36. data/lib/rouge/demos/javascript +1 -0
  37. data/lib/rouge/demos/json +1 -0
  38. data/lib/rouge/demos/json-doc +1 -0
  39. data/lib/rouge/demos/liquid +11 -0
  40. data/lib/rouge/demos/literate_coffeescript +3 -0
  41. data/lib/rouge/demos/literate_haskell +7 -0
  42. data/lib/rouge/demos/llvm +20 -0
  43. data/lib/rouge/demos/lua +12 -0
  44. data/lib/rouge/demos/make +6 -0
  45. data/lib/rouge/demos/markdown +4 -0
  46. data/lib/rouge/demos/matlab +6 -0
  47. data/lib/rouge/demos/moonscript +16 -0
  48. data/lib/rouge/demos/nginx +5 -0
  49. data/lib/rouge/demos/nim +27 -0
  50. data/lib/rouge/demos/objective_c +14 -0
  51. data/lib/rouge/demos/ocaml +12 -0
  52. data/lib/rouge/demos/perl +5 -0
  53. data/lib/rouge/demos/php +3 -0
  54. data/lib/rouge/demos/plaintext +1 -0
  55. data/lib/rouge/demos/powershell +49 -0
  56. data/lib/rouge/demos/prolog +9 -0
  57. data/lib/rouge/demos/properties +7 -0
  58. data/lib/rouge/demos/puppet +6 -0
  59. data/lib/rouge/demos/python +6 -0
  60. data/lib/rouge/demos/qml +9 -0
  61. data/lib/rouge/demos/r +8 -0
  62. data/lib/rouge/demos/racket +24 -0
  63. data/lib/rouge/demos/ruby +9 -0
  64. data/lib/rouge/demos/rust +12 -0
  65. data/lib/rouge/demos/sass +3 -0
  66. data/lib/rouge/demos/scala +3 -0
  67. data/lib/rouge/demos/scheme +4 -0
  68. data/lib/rouge/demos/scss +5 -0
  69. data/lib/rouge/demos/sed +4 -0
  70. data/lib/rouge/demos/shell +2 -0
  71. data/lib/rouge/demos/slim +17 -0
  72. data/lib/rouge/demos/smalltalk +6 -0
  73. data/lib/rouge/demos/sml +4 -0
  74. data/lib/rouge/demos/sql +1 -0
  75. data/lib/rouge/demos/swift +5 -0
  76. data/lib/rouge/demos/tcl +1 -0
  77. data/lib/rouge/demos/tex +1 -0
  78. data/lib/rouge/demos/toml +9 -0
  79. data/lib/rouge/demos/tulip +14 -0
  80. data/lib/rouge/demos/vb +4 -0
  81. data/lib/rouge/demos/viml +5 -0
  82. data/lib/rouge/demos/xml +2 -0
  83. data/lib/rouge/demos/yaml +4 -0
  84. data/lib/rouge/formatter.rb +50 -0
  85. data/lib/rouge/formatters/html.rb +117 -0
  86. data/lib/rouge/formatters/null.rb +19 -0
  87. data/lib/rouge/formatters/terminal256.rb +176 -0
  88. data/lib/rouge/lexer.rb +443 -0
  89. data/lib/rouge/lexers/apache.rb +68 -0
  90. data/lib/rouge/lexers/apache/keywords.yml +453 -0
  91. data/lib/rouge/lexers/apple_script.rb +367 -0
  92. data/lib/rouge/lexers/c.rb +212 -0
  93. data/lib/rouge/lexers/clojure.rb +112 -0
  94. data/lib/rouge/lexers/coffeescript.rb +174 -0
  95. data/lib/rouge/lexers/common_lisp.rb +345 -0
  96. data/lib/rouge/lexers/conf.rb +24 -0
  97. data/lib/rouge/lexers/cpp.rb +66 -0
  98. data/lib/rouge/lexers/csharp.rb +88 -0
  99. data/lib/rouge/lexers/css.rb +271 -0
  100. data/lib/rouge/lexers/dart.rb +104 -0
  101. data/lib/rouge/lexers/diff.rb +31 -0
  102. data/lib/rouge/lexers/elixir.rb +108 -0
  103. data/lib/rouge/lexers/erb.rb +56 -0
  104. data/lib/rouge/lexers/erlang.rb +118 -0
  105. data/lib/rouge/lexers/factor.rb +302 -0
  106. data/lib/rouge/lexers/gherkin.rb +137 -0
  107. data/lib/rouge/lexers/gherkin/keywords.rb +14 -0
  108. data/lib/rouge/lexers/glsl.rb +135 -0
  109. data/lib/rouge/lexers/go.rb +178 -0
  110. data/lib/rouge/lexers/groovy.rb +104 -0
  111. data/lib/rouge/lexers/haml.rb +228 -0
  112. data/lib/rouge/lexers/handlebars.rb +79 -0
  113. data/lib/rouge/lexers/haskell.rb +183 -0
  114. data/lib/rouge/lexers/html.rb +94 -0
  115. data/lib/rouge/lexers/http.rb +80 -0
  116. data/lib/rouge/lexers/ini.rb +57 -0
  117. data/lib/rouge/lexers/io.rb +68 -0
  118. data/lib/rouge/lexers/java.rb +76 -0
  119. data/lib/rouge/lexers/javascript.rb +297 -0
  120. data/lib/rouge/lexers/liquid.rb +287 -0
  121. data/lib/rouge/lexers/literate_coffeescript.rb +33 -0
  122. data/lib/rouge/lexers/literate_haskell.rb +36 -0
  123. data/lib/rouge/lexers/llvm.rb +84 -0
  124. data/lib/rouge/lexers/lua.rb +122 -0
  125. data/lib/rouge/lexers/lua/builtins.rb +22 -0
  126. data/lib/rouge/lexers/make.rb +116 -0
  127. data/lib/rouge/lexers/markdown.rb +154 -0
  128. data/lib/rouge/lexers/matlab.rb +74 -0
  129. data/lib/rouge/lexers/matlab/builtins.rb +11 -0
  130. data/lib/rouge/lexers/moonscript.rb +110 -0
  131. data/lib/rouge/lexers/nginx.rb +71 -0
  132. data/lib/rouge/lexers/nim.rb +152 -0
  133. data/lib/rouge/lexers/objective_c.rb +197 -0
  134. data/lib/rouge/lexers/ocaml.rb +111 -0
  135. data/lib/rouge/lexers/perl.rb +197 -0
  136. data/lib/rouge/lexers/php.rb +173 -0
  137. data/lib/rouge/lexers/php/builtins.rb +204 -0
  138. data/lib/rouge/lexers/plain_text.rb +25 -0
  139. data/lib/rouge/lexers/powershell.rb +96 -0
  140. data/lib/rouge/lexers/prolog.rb +64 -0
  141. data/lib/rouge/lexers/properties.rb +55 -0
  142. data/lib/rouge/lexers/puppet.rb +128 -0
  143. data/lib/rouge/lexers/python.rb +228 -0
  144. data/lib/rouge/lexers/qml.rb +72 -0
  145. data/lib/rouge/lexers/r.rb +56 -0
  146. data/lib/rouge/lexers/racket.rb +542 -0
  147. data/lib/rouge/lexers/ruby.rb +415 -0
  148. data/lib/rouge/lexers/rust.rb +191 -0
  149. data/lib/rouge/lexers/sass.rb +74 -0
  150. data/lib/rouge/lexers/sass/common.rb +180 -0
  151. data/lib/rouge/lexers/scala.rb +142 -0
  152. data/lib/rouge/lexers/scheme.rb +112 -0
  153. data/lib/rouge/lexers/scss.rb +34 -0
  154. data/lib/rouge/lexers/sed.rb +170 -0
  155. data/lib/rouge/lexers/shell.rb +152 -0
  156. data/lib/rouge/lexers/slim.rb +228 -0
  157. data/lib/rouge/lexers/smalltalk.rb +116 -0
  158. data/lib/rouge/lexers/sml.rb +347 -0
  159. data/lib/rouge/lexers/sql.rb +140 -0
  160. data/lib/rouge/lexers/swift.rb +144 -0
  161. data/lib/rouge/lexers/tcl.rb +192 -0
  162. data/lib/rouge/lexers/tex.rb +72 -0
  163. data/lib/rouge/lexers/toml.rb +71 -0
  164. data/lib/rouge/lexers/tulip.rb +75 -0
  165. data/lib/rouge/lexers/vb.rb +164 -0
  166. data/lib/rouge/lexers/viml.rb +101 -0
  167. data/lib/rouge/lexers/viml/keywords.rb +12 -0
  168. data/lib/rouge/lexers/xml.rb +59 -0
  169. data/lib/rouge/lexers/yaml.rb +364 -0
  170. data/lib/rouge/plugins/redcarpet.rb +30 -0
  171. data/lib/rouge/regex_lexer.rb +439 -0
  172. data/lib/rouge/template_lexer.rb +22 -0
  173. data/lib/rouge/text_analyzer.rb +48 -0
  174. data/lib/rouge/theme.rb +195 -0
  175. data/lib/rouge/themes/base16.rb +130 -0
  176. data/lib/rouge/themes/colorful.rb +67 -0
  177. data/lib/rouge/themes/github.rb +71 -0
  178. data/lib/rouge/themes/molokai.rb +82 -0
  179. data/lib/rouge/themes/monokai.rb +92 -0
  180. data/lib/rouge/themes/monokai_sublime.rb +90 -0
  181. data/lib/rouge/themes/thankful_eyes.rb +71 -0
  182. data/lib/rouge/token.rb +182 -0
  183. data/lib/rouge/util.rb +101 -0
  184. data/lib/rouge/version.rb +7 -0
  185. metadata +231 -0
@@ -0,0 +1,94 @@
1
+ # -*- coding: utf-8 -*- #
2
+
3
+ module Rouge
4
+ module Lexers
5
+ class HTML < RegexLexer
6
+ title "HTML"
7
+ desc "HTML, the markup language of the web"
8
+ tag 'html'
9
+ filenames '*.htm', '*.html', '*.xhtml'
10
+ mimetypes 'text/html', 'application/xhtml+xml'
11
+
12
+ def self.analyze_text(text)
13
+ return 1 if text.doctype?(/\bhtml\b/i)
14
+ return 1 if text =~ /<\s*html\b/
15
+ end
16
+
17
+ state :root do
18
+ rule /[^<&]+/m, Text
19
+ rule /&\S*?;/, Name::Entity
20
+ rule /<!DOCTYPE .*?>/im, Comment::Preproc
21
+ rule /<!\[CDATA\[.*?\]\]>/m, Comment::Preproc
22
+ rule /<!--/, Comment, :comment
23
+ rule /<\?.*?\?>/m, Comment::Preproc # php? really?
24
+
25
+ rule /<\s*script\s*/m do
26
+ token Name::Tag
27
+ push :script_content
28
+ push :tag
29
+ end
30
+
31
+ rule /<\s*style\s*/m do
32
+ token Name::Tag
33
+ push :style_content
34
+ push :tag
35
+ end
36
+
37
+ rule %r(<\s*[a-zA-Z0-9:-]+), Name::Tag, :tag # opening tags
38
+ rule %r(<\s*/\s*[a-zA-Z0-9:-]+\s*>), Name::Tag # closing tags
39
+ end
40
+
41
+ state :comment do
42
+ rule /[^-]+/, Comment
43
+ rule /-->/, Comment, :pop!
44
+ rule /-/, Comment
45
+ end
46
+
47
+ state :tag do
48
+ rule /\s+/m, Text
49
+ rule /[a-zA-Z0-9_:-]+\s*=/m, Name::Attribute, :attr
50
+ rule /[a-zA-Z0-9_:-]+/, Name::Attribute
51
+ rule %r(/?\s*>)m, Name::Tag, :pop!
52
+ end
53
+
54
+ state :attr do
55
+ # TODO: are backslash escapes valid here?
56
+ rule /"/ do
57
+ token Str
58
+ goto :dq
59
+ end
60
+
61
+ rule /'/ do
62
+ token Str
63
+ goto :sq
64
+ end
65
+
66
+ rule /[^\s>]+/, Str, :pop!
67
+ end
68
+
69
+ state :dq do
70
+ rule /"/, Str, :pop!
71
+ rule /[^"]+/, Str
72
+ end
73
+
74
+ state :sq do
75
+ rule /'/, Str, :pop!
76
+ rule /[^']+/, Str
77
+ end
78
+
79
+ state :script_content do
80
+ rule %r(<\s*/\s*script\s*>)m, Name::Tag, :pop!
81
+ rule %r(.*?(?=<\s*/\s*script\s*>))m do
82
+ delegate Javascript
83
+ end
84
+ end
85
+
86
+ state :style_content do
87
+ rule %r(<\s*/\s*style\s*>)m, Name::Tag, :pop!
88
+ rule %r(.*(?=<\s*/\s*style\s*>))m do
89
+ delegate CSS
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,80 @@
1
+ # -*- coding: utf-8 -*- #
2
+
3
+ module Rouge
4
+ module Lexers
5
+ class HTTP < RegexLexer
6
+ tag 'http'
7
+ title "HTTP"
8
+ desc 'http requests and responses'
9
+
10
+ def self.methods
11
+ @methods ||= %w(GET POST PUT DELETE HEAD OPTIONS TRACE PATCH)
12
+ end
13
+
14
+ def content_lexer
15
+ return Lexers::PlainText unless @content_type
16
+
17
+ @content_lexer ||= Lexer.guess_by_mimetype(@content_type)
18
+ rescue Lexer::AmbiguousGuess
19
+ @content_lexer = Lexers::PlainText
20
+ end
21
+
22
+ start { @content_type = 'text/plain' }
23
+
24
+ state :root do
25
+ # request
26
+ rule %r(
27
+ (#{HTTP.methods.join('|')})([ ]+) # method
28
+ ([^ ]+)([ ]+) # path
29
+ (HTTPS?)(/)(1[.][01])(\r?\n|$) # http version
30
+ )ox do
31
+ groups(
32
+ Name::Function, Text,
33
+ Name::Namespace, Text,
34
+ Keyword, Operator, Num, Text
35
+ )
36
+
37
+ push :headers
38
+ end
39
+
40
+ # response
41
+ rule %r(
42
+ (HTTPS?)(/)(1[.][01])([ ]+) # http version
43
+ (\d{3})([ ]+) # status
44
+ ([^\r\n]+)(\r?\n|$) # status message
45
+ )x do
46
+ groups(
47
+ Keyword, Operator, Num, Text,
48
+ Num, Text,
49
+ Name::Exception, Text
50
+ )
51
+ push :headers
52
+ end
53
+ end
54
+
55
+ state :headers do
56
+ rule /([^\s:]+)( *)(:)( *)([^\r\n]+)(\r?\n|$)/ do |m|
57
+ key = m[1]
58
+ value = m[5]
59
+ if key.strip.downcase == 'content-type'
60
+ @content_type = value.split(';')[0].downcase
61
+ end
62
+
63
+ groups Name::Attribute, Text, Punctuation, Text, Str, Text
64
+ end
65
+
66
+ rule /([^\r\n]+)(\r?\n|$)/ do
67
+ groups Str, Text
68
+ end
69
+
70
+ rule /\r?\n/, Text, :content
71
+ end
72
+
73
+ state :content do
74
+ rule /.+/m do |m|
75
+ delegate(content_lexer)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,57 @@
1
+ # -*- coding: utf-8 -*- #
2
+
3
+ module Rouge
4
+ module Lexers
5
+ class INI < RegexLexer
6
+ title "INI"
7
+ desc 'the INI configuration format'
8
+ tag 'ini'
9
+
10
+ # TODO add more here
11
+ filenames '*.ini', '*.INI', '*.gitconfig'
12
+ mimetypes 'text/x-ini'
13
+
14
+ def self.analyze_text(text)
15
+ return 0.1 if text =~ /\A\[[\w.]+\]\s*\w+=\w+/
16
+ end
17
+
18
+ identifier = /[\w.]+/
19
+
20
+ state :basic do
21
+ rule /[;#].*?\n/, Comment
22
+ rule /\s+/, Text
23
+ rule /\\\n/, Str::Escape
24
+ end
25
+
26
+ state :root do
27
+ mixin :basic
28
+
29
+ rule /(#{identifier})(\s*)(=)/ do
30
+ groups Name::Property, Text, Punctuation
31
+ push :value
32
+ end
33
+
34
+ rule /\[.*?\]/, Name::Namespace
35
+ end
36
+
37
+ state :value do
38
+ rule /\n/, Text, :pop!
39
+ mixin :basic
40
+ rule /"/, Str, :dq
41
+ rule /'.*?'/, Str
42
+ mixin :esc_str
43
+ rule /[^\\\n]+/, Str
44
+ end
45
+
46
+ state :dq do
47
+ rule /"/, Str, :pop!
48
+ mixin :esc_str
49
+ rule /[^\\"]+/m, Str
50
+ end
51
+
52
+ state :esc_str do
53
+ rule /\\./m, Str::Escape
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,68 @@
1
+ # -*- coding: utf-8 -*- #
2
+
3
+ module Rouge
4
+ module Lexers
5
+ class IO < RegexLexer
6
+ tag 'io'
7
+ title "Io"
8
+ desc 'The IO programming language (http://iolanguage.com)'
9
+ mimetypes 'text/x-iosrc'
10
+ filenames '*.io'
11
+
12
+ def self.analyze_text(text)
13
+ return 1 if text.shebang? 'io'
14
+ end
15
+
16
+ def self.constants
17
+ @constants ||= Set.new %w(nil false true)
18
+ end
19
+
20
+ def self.builtins
21
+ @builtins ||= Set.new %w(
22
+ args call clone do doFile doString else elseif for if list
23
+ method return super then
24
+ )
25
+ end
26
+
27
+ state :root do
28
+ rule /\s+/m, Text
29
+ rule %r(//.*?\n), Comment::Single
30
+ rule %r(#.*?\n), Comment::Single
31
+ rule %r(/(\\\n)?[*].*?[*](\\\n)?/)m, Comment::Multiline
32
+ rule %r(/[+]), Comment::Multiline, :nested_comment
33
+
34
+ rule /"(\\\\|\\"|[^"])*"/, Str
35
+
36
+ rule %r(:?:=), Keyword
37
+ rule /[()]/, Punctuation
38
+
39
+ rule %r([-=;,*+><!/|^.%&\[\]{}]), Operator
40
+
41
+ rule /[A-Z]\w*/, Name::Class
42
+
43
+ rule /[a-z_]\w*/ do |m|
44
+ name = m[0]
45
+
46
+ if self.class.constants.include? name
47
+ token Keyword::Constant
48
+ elsif self.class.builtins.include? name
49
+ token Name::Builtin
50
+ else
51
+ token Name
52
+ end
53
+ end
54
+
55
+ rule %r((\d+[.]?\d*|\d*[.]\d+)(e[+-]?[0-9]+)?)i, Num::Float
56
+ rule /\d+/, Num::Integer
57
+
58
+ rule /@@?/, Keyword
59
+ end
60
+
61
+ state :nested_comment do
62
+ rule %r([^/+]+)m, Comment::Multiline
63
+ rule %r(/[+]), Comment::Multiline, :nested_comment
64
+ rule %r([+]/), Comment::Multiline, :pop!
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,76 @@
1
+ # -*- coding: utf-8 -*- #
2
+
3
+ module Rouge
4
+ module Lexers
5
+ class Java < RegexLexer
6
+ title "Java"
7
+ desc "The Java programming language (java.com)"
8
+
9
+ tag 'java'
10
+ filenames '*.java'
11
+ mimetypes 'text/x-java'
12
+
13
+ keywords = %w(
14
+ assert break case catch continue default do else finally for
15
+ if goto instanceof new return switch this throw try while
16
+ )
17
+
18
+ declarations = %w(
19
+ abstract const enum extends final implements native private protected
20
+ public static strictfp super synchronized throws transient volatile
21
+ )
22
+
23
+ types = %w(boolean byte char double float int long short void)
24
+
25
+ id = /[a-zA-Z_][a-zA-Z0-9_]*/
26
+
27
+ state :root do
28
+ rule %r(^
29
+ (\s*(?:[a-zA-Z_][a-zA-Z0-9_.\[\]]*\s+)+?) # return arguments
30
+ ([a-zA-Z_][a-zA-Z0-9_]*) # method name
31
+ (\s*)(\() # signature start
32
+ )mx do |m|
33
+ # TODO: do this better, this shouldn't need a delegation
34
+ delegate Java, m[1]
35
+ token Name::Function, m[2]
36
+ token Text, m[3]
37
+ token Punctuation, m[4]
38
+ end
39
+
40
+ rule /\s+/, Text
41
+ rule %r(//.*?$), Comment::Single
42
+ rule %r(/\*.*?\*/)m, Comment::Multiline
43
+ rule /@#{id}/, Name::Decorator
44
+ rule /(?:#{keywords.join('|')})\b/, Keyword
45
+ rule /(?:#{declarations.join('|')})\b/, Keyword::Declaration
46
+ rule /(?:#{types.join('|')})\b/, Keyword::Type
47
+ rule /package\b/, Keyword::Namespace
48
+ rule /(?:true|false|null)\b/, Keyword::Constant
49
+ rule /(?:class|interface)\b/, Keyword::Declaration, :class
50
+ rule /import\b/, Keyword::Namespace, :import
51
+ rule /"(\\\\|\\"|[^"])*"/, Str
52
+ rule /'(?:\\.|[^\\]|\\u[0-9a-f]{4})'/, Str::Char
53
+ rule /(\.)(#{id})/ do
54
+ groups Operator, Name::Attribute
55
+ end
56
+ rule /#{id}:/, Name::Label
57
+ rule /\$?#{id}/, Name
58
+ rule /[~^*!%&\[\](){}<>\|+=:;,.\/?-]/, Operator
59
+ rule /[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?/, Num::Float
60
+ rule /0x[0-9a-f]+/, Num::Hex
61
+ rule /[0-9]+L?/, Num::Integer
62
+ # rule /\n/, Text
63
+ end
64
+
65
+ state :class do
66
+ rule /\s+/m, Text
67
+ rule id, Name::Class, :pop!
68
+ end
69
+
70
+ state :import do
71
+ rule /\s+/m, Text
72
+ rule /[a-z0-9_.]+\*?/i, Name::Namespace, :pop!
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,297 @@
1
+ # -*- coding: utf-8 -*- #
2
+
3
+ module Rouge
4
+ module Lexers
5
+ class Javascript < RegexLexer
6
+ title "JavaScript"
7
+ desc "JavaScript, the browser scripting language"
8
+
9
+ tag 'javascript'
10
+ aliases 'js'
11
+ filenames '*.js'
12
+ mimetypes 'application/javascript', 'application/x-javascript',
13
+ 'text/javascript', 'text/x-javascript'
14
+
15
+ def self.analyze_text(text)
16
+ return 1 if text.shebang?('node')
17
+ return 1 if text.shebang?('jsc')
18
+ # TODO: rhino, spidermonkey, etc
19
+ end
20
+
21
+ state :comments_and_whitespace do
22
+ rule /\s+/, Text
23
+ rule /<!--/, Comment # really...?
24
+ rule %r(//.*?$), Comment::Single
25
+ rule %r(/\*.*?\*/)m, Comment::Multiline
26
+ end
27
+
28
+ state :expr_start do
29
+ mixin :comments_and_whitespace
30
+
31
+ rule %r(/) do
32
+ token Str::Regex
33
+ goto :regex
34
+ end
35
+
36
+ rule /[{]/, Punctuation, :object
37
+
38
+ rule //, Text, :pop!
39
+ end
40
+
41
+ state :regex do
42
+ rule %r(/) do
43
+ token Str::Regex
44
+ goto :regex_end
45
+ end
46
+
47
+ rule %r([^/]\n), Error, :pop!
48
+
49
+ rule /\n/, Error, :pop!
50
+ rule /\[\^/, Str::Escape, :regex_group
51
+ rule /\[/, Str::Escape, :regex_group
52
+ rule /\\./, Str::Escape
53
+ rule %r{[(][?][:=<!]}, Str::Escape
54
+ rule /[{][\d,]+[}]/, Str::Escape
55
+ rule /[()?]/, Str::Escape
56
+ rule /./, Str::Regex
57
+ end
58
+
59
+ state :regex_end do
60
+ rule /[gim]+/, Str::Regex, :pop!
61
+ rule(//) { pop! }
62
+ end
63
+
64
+ state :regex_group do
65
+ # specially highlight / in a group to indicate that it doesn't
66
+ # close the regex
67
+ rule /\//, Str::Escape
68
+
69
+ rule %r([^/]\n) do
70
+ token Error
71
+ pop! 2
72
+ end
73
+
74
+ rule /\]/, Str::Escape, :pop!
75
+ rule /\\./, Str::Escape
76
+ rule /./, Str::Regex
77
+ end
78
+
79
+ state :bad_regex do
80
+ rule /[^\n]+/, Error, :pop!
81
+ end
82
+
83
+ def self.keywords
84
+ @keywords ||= Set.new %w(
85
+ for in while do break return continue switch case default
86
+ if else throw try catch finally new delete typeof instanceof
87
+ void this yield
88
+ )
89
+ end
90
+
91
+ def self.declarations
92
+ @declarations ||= Set.new %w(var let with function)
93
+ end
94
+
95
+ def self.reserved
96
+ @reserved ||= Set.new %w(
97
+ abstract boolean byte char class const debugger double enum
98
+ export extends final float goto implements import int interface
99
+ long native package private protected public short static
100
+ super synchronized throws transient volatile
101
+ )
102
+ end
103
+
104
+ def self.constants
105
+ @constants ||= Set.new %w(true false null NaN Infinity undefined)
106
+ end
107
+
108
+ def self.builtins
109
+ @builtins ||= %w(
110
+ Array Boolean Date Error Function Math netscape
111
+ Number Object Packages RegExp String sun decodeURI
112
+ decodeURIComponent encodeURI encodeURIComponent
113
+ Error eval isFinite isNaN parseFloat parseInt document this
114
+ window
115
+ )
116
+ end
117
+
118
+ id = /[$a-zA-Z_][a-zA-Z0-9_]*/
119
+
120
+ state :root do
121
+ rule /\A\s*#!.*?\n/m, Comment::Preproc, :statement
122
+ rule /\n/, Text, :statement
123
+ rule %r((?<=\n)(?=\s|/|<!--)), Text, :expr_start
124
+ mixin :comments_and_whitespace
125
+ rule %r(\+\+ | -- | ~ | && | \|\| | \\(?=\n) | << | >>>? | ===
126
+ | !== )x,
127
+ Operator, :expr_start
128
+ rule %r([-<>+*%&|\^/!=]=?), Operator, :expr_start
129
+ rule /[(\[,]/, Punctuation, :expr_start
130
+ rule /;/, Punctuation, :statement
131
+ rule /[)\].]/, Punctuation
132
+
133
+ rule /[?]/ do
134
+ token Punctuation
135
+ push :ternary
136
+ push :expr_start
137
+ end
138
+
139
+ rule /[{}]/, Punctuation, :statement
140
+
141
+ rule id do |m|
142
+ if self.class.keywords.include? m[0]
143
+ token Keyword
144
+ push :expr_start
145
+ elsif self.class.declarations.include? m[0]
146
+ token Keyword::Declaration
147
+ push :expr_start
148
+ elsif self.class.reserved.include? m[0]
149
+ token Keyword::Reserved
150
+ elsif self.class.constants.include? m[0]
151
+ token Keyword::Constant
152
+ elsif self.class.builtins.include? m[0]
153
+ token Name::Builtin
154
+ else
155
+ token Name::Other
156
+ end
157
+ end
158
+
159
+ rule /[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?/, Num::Float
160
+ rule /0x[0-9a-fA-F]+/, Num::Hex
161
+ rule /[0-9]+/, Num::Integer
162
+ rule /"(\\\\|\\"|[^"])*"/, Str::Double
163
+ rule /'(\\\\|\\'|[^'])*'/, Str::Single
164
+ end
165
+
166
+ # braced parts that aren't object literals
167
+ state :statement do
168
+ rule /(#{id})(\s*)(:)/ do
169
+ groups Name::Label, Text, Punctuation
170
+ end
171
+
172
+ rule /[{}]/, Punctuation
173
+
174
+ mixin :expr_start
175
+ end
176
+
177
+ # object literals
178
+ state :object do
179
+ mixin :comments_and_whitespace
180
+ rule /[}]/ do
181
+ token Punctuation
182
+ goto :statement
183
+ end
184
+
185
+ rule /(#{id})(\s*)(:)/ do
186
+ groups Name::Attribute, Text, Punctuation
187
+ push :expr_start
188
+ end
189
+
190
+ rule /:/, Punctuation
191
+ mixin :root
192
+ end
193
+
194
+ # ternary expressions, where <id>: is not a label!
195
+ state :ternary do
196
+ rule /:/ do
197
+ token Punctuation
198
+ goto :expr_start
199
+ end
200
+
201
+ mixin :root
202
+ end
203
+ end
204
+
205
+ class JSON < RegexLexer
206
+ desc "JavaScript Object Notation (json.org)"
207
+ tag 'json'
208
+ filenames '*.json'
209
+ mimetypes 'application/json', 'application/vnd.api+json'
210
+
211
+ # TODO: is this too much of a performance hit? JSON is quite simple,
212
+ # so I'd think this wouldn't be too bad, but for large documents this
213
+ # could mean doing two full lexes.
214
+ def self.analyze_text(text)
215
+ return 0.8 if text =~ /\A\s*{/m && text.lexes_cleanly?(self)
216
+ end
217
+
218
+ string = /"(\\.|[^"])*"/
219
+
220
+ state :root do
221
+ mixin :whitespace
222
+ rule /(?:true|false|null)\b/, Keyword::Constant
223
+ rule /{/, Punctuation, :object_key_initial
224
+ rule /\[/, Punctuation, :array
225
+ rule /-?(?:0|[1-9]\d*)\.\d+(?:e[+-]\d+)?/i, Num::Float
226
+ rule /-?(?:0|[1-9]\d*)(?:e[+-]\d+)?/i, Num::Integer
227
+ mixin :has_string
228
+ end
229
+
230
+ state :whitespace do
231
+ rule /\s+/m, Text::Whitespace
232
+ end
233
+
234
+ state :has_string do
235
+ rule string, Str::Double
236
+ end
237
+
238
+ # in object_key_initial it's allowed to immediately close the object again
239
+ state :object_key_initial do
240
+ mixin :whitespace
241
+ rule string do
242
+ token Name::Tag
243
+ goto :object_key
244
+ end
245
+ rule /}/, Punctuation, :pop!
246
+ end
247
+
248
+ # in object_key at least one more name/value pair is required
249
+ state :object_key do
250
+ mixin :whitespace
251
+ rule string, Name::Tag
252
+ rule /:/, Punctuation, :object_val
253
+ rule /}/, Error, :pop!
254
+ end
255
+
256
+ state :object_val do
257
+ rule /,/, Punctuation, :pop!
258
+ rule(/}/) { token Punctuation; pop!(2) }
259
+ mixin :root
260
+ end
261
+
262
+ state :array do
263
+ rule /\]/, Punctuation, :pop!
264
+ rule /,/, Punctuation
265
+ mixin :root
266
+ end
267
+ end
268
+
269
+ class JSONDOC < JSON
270
+ desc "JavaScript Object Notation with extenstions for documentation"
271
+ tag 'json-doc'
272
+
273
+ prepend :root do
274
+ mixin :comments
275
+ rule /(\.\.\.)/, Comment::Single
276
+ end
277
+
278
+ prepend :object_key_initial do
279
+ mixin :comments
280
+ rule /(\.\.\.)/, Comment::Single
281
+ end
282
+
283
+ prepend :object_key do
284
+ mixin :comments
285
+ rule /(\.\.\.)/ do
286
+ token Comment::Single
287
+ goto :object_key_initial
288
+ end
289
+ end
290
+
291
+ state :comments do
292
+ rule %r(//.*?$), Comment::Single
293
+ end
294
+ end
295
+
296
+ end
297
+ end