gitlab-rouge 1.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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