PageRenderTime 63ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/pygments/lexers/agile.py

https://bitbucket.org/pnathan/pygments-main
Python | 1815 lines | 1526 code | 114 blank | 175 comment | 28 complexity | b65aa70f94be6e388cb58ea9b6e333a2 MD5 | raw file
Possible License(s): BSD-2-Clause
  1. # -*- coding: utf-8 -*-
  2. """
  3. pygments.lexers.agile
  4. ~~~~~~~~~~~~~~~~~~~~~
  5. Lexers for agile languages.
  6. :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS.
  7. :license: BSD, see LICENSE for details.
  8. """
  9. import re
  10. from pygments.lexer import Lexer, RegexLexer, ExtendedRegexLexer, \
  11. LexerContext, include, combined, do_insertions, bygroups, using
  12. from pygments.token import Error, Text, Other, \
  13. Comment, Operator, Keyword, Name, String, Number, Generic, Punctuation
  14. from pygments.util import get_bool_opt, get_list_opt, shebang_matches
  15. from pygments import unistring as uni
  16. __all__ = ['PythonLexer', 'PythonConsoleLexer', 'PythonTracebackLexer',
  17. 'Python3Lexer', 'Python3TracebackLexer', 'RubyLexer',
  18. 'RubyConsoleLexer', 'PerlLexer', 'LuaLexer', 'MoonScriptLexer',
  19. 'CrocLexer', 'MiniDLexer', 'IoLexer', 'TclLexer', 'FactorLexer', 'FancyLexer']
  20. # b/w compatibility
  21. from pygments.lexers.functional import SchemeLexer
  22. from pygments.lexers.jvm import IokeLexer, ClojureLexer
  23. line_re = re.compile('.*?\n')
  24. class PythonLexer(RegexLexer):
  25. """
  26. For `Python <http://www.python.org>`_ source code.
  27. """
  28. name = 'Python'
  29. aliases = ['python', 'py', 'sage']
  30. filenames = ['*.py', '*.pyw', '*.sc', 'SConstruct', 'SConscript', '*.tac', '*.sage']
  31. mimetypes = ['text/x-python', 'application/x-python']
  32. tokens = {
  33. 'root': [
  34. (r'\n', Text),
  35. (r'^(\s*)([rRuU]{,2}"""(?:.|\n)*?""")', bygroups(Text, String.Doc)),
  36. (r"^(\s*)([rRuU]{,2}'''(?:.|\n)*?''')", bygroups(Text, String.Doc)),
  37. (r'[^\S\n]+', Text),
  38. (r'#.*$', Comment),
  39. (r'[]{}:(),;[]', Punctuation),
  40. (r'\\\n', Text),
  41. (r'\\', Text),
  42. (r'(in|is|and|or|not)\b', Operator.Word),
  43. (r'!=|==|<<|>>|[-~+/*%=<>&^|.]', Operator),
  44. include('keywords'),
  45. (r'(def)((?:\s|\\\s)+)', bygroups(Keyword, Text), 'funcname'),
  46. (r'(class)((?:\s|\\\s)+)', bygroups(Keyword, Text), 'classname'),
  47. (r'(from)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Text),
  48. 'fromimport'),
  49. (r'(import)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Text),
  50. 'import'),
  51. include('builtins'),
  52. include('backtick'),
  53. ('(?:[rR]|[uU][rR]|[rR][uU])"""', String, 'tdqs'),
  54. ("(?:[rR]|[uU][rR]|[rR][uU])'''", String, 'tsqs'),
  55. ('(?:[rR]|[uU][rR]|[rR][uU])"', String, 'dqs'),
  56. ("(?:[rR]|[uU][rR]|[rR][uU])'", String, 'sqs'),
  57. ('[uU]?"""', String, combined('stringescape', 'tdqs')),
  58. ("[uU]?'''", String, combined('stringescape', 'tsqs')),
  59. ('[uU]?"', String, combined('stringescape', 'dqs')),
  60. ("[uU]?'", String, combined('stringescape', 'sqs')),
  61. include('name'),
  62. include('numbers'),
  63. ],
  64. 'keywords': [
  65. (r'(assert|break|continue|del|elif|else|except|exec|'
  66. r'finally|for|global|if|lambda|pass|print|raise|'
  67. r'return|try|while|yield|as|with)\b', Keyword),
  68. ],
  69. 'builtins': [
  70. (r'(?<!\.)(__import__|abs|all|any|apply|basestring|bin|bool|buffer|'
  71. r'bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|'
  72. r'complex|delattr|dict|dir|divmod|enumerate|eval|execfile|exit|'
  73. r'file|filter|float|frozenset|getattr|globals|hasattr|hash|hex|id|'
  74. r'input|int|intern|isinstance|issubclass|iter|len|list|locals|'
  75. r'long|map|max|min|next|object|oct|open|ord|pow|property|range|'
  76. r'raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|'
  77. r'sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|'
  78. r'vars|xrange|zip)\b', Name.Builtin),
  79. (r'(?<!\.)(self|None|Ellipsis|NotImplemented|False|True'
  80. r')\b', Name.Builtin.Pseudo),
  81. (r'(?<!\.)(ArithmeticError|AssertionError|AttributeError|'
  82. r'BaseException|DeprecationWarning|EOFError|EnvironmentError|'
  83. r'Exception|FloatingPointError|FutureWarning|GeneratorExit|IOError|'
  84. r'ImportError|ImportWarning|IndentationError|IndexError|KeyError|'
  85. r'KeyboardInterrupt|LookupError|MemoryError|NameError|'
  86. r'NotImplemented|NotImplementedError|OSError|OverflowError|'
  87. r'OverflowWarning|PendingDeprecationWarning|ReferenceError|'
  88. r'RuntimeError|RuntimeWarning|StandardError|StopIteration|'
  89. r'SyntaxError|SyntaxWarning|SystemError|SystemExit|TabError|'
  90. r'TypeError|UnboundLocalError|UnicodeDecodeError|'
  91. r'UnicodeEncodeError|UnicodeError|UnicodeTranslateError|'
  92. r'UnicodeWarning|UserWarning|ValueError|VMSError|Warning|'
  93. r'WindowsError|ZeroDivisionError)\b', Name.Exception),
  94. ],
  95. 'numbers': [
  96. (r'(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?j?', Number.Float),
  97. (r'\d+[eE][+-]?[0-9]+j?', Number.Float),
  98. (r'0[0-7]+j?', Number.Oct),
  99. (r'0[xX][a-fA-F0-9]+', Number.Hex),
  100. (r'\d+L', Number.Integer.Long),
  101. (r'\d+j?', Number.Integer)
  102. ],
  103. 'backtick': [
  104. ('`.*?`', String.Backtick),
  105. ],
  106. 'name': [
  107. (r'@[a-zA-Z0-9_.]+', Name.Decorator),
  108. ('[a-zA-Z_][a-zA-Z0-9_]*', Name),
  109. ],
  110. 'funcname': [
  111. ('[a-zA-Z_][a-zA-Z0-9_]*', Name.Function, '#pop')
  112. ],
  113. 'classname': [
  114. ('[a-zA-Z_][a-zA-Z0-9_]*', Name.Class, '#pop')
  115. ],
  116. 'import': [
  117. (r'(?:[ \t]|\\\n)+', Text),
  118. (r'as\b', Keyword.Namespace),
  119. (r',', Operator),
  120. (r'[a-zA-Z_][a-zA-Z0-9_.]*', Name.Namespace),
  121. (r'', Text, '#pop') # all else: go back
  122. ],
  123. 'fromimport': [
  124. (r'(?:[ \t]|\\\n)+', Text),
  125. (r'import\b', Keyword.Namespace, '#pop'),
  126. # if None occurs here, it's "raise x from None", since None can
  127. # never be a module name
  128. (r'None\b', Name.Builtin.Pseudo, '#pop'),
  129. # sadly, in "raise x from y" y will be highlighted as namespace too
  130. (r'[a-zA-Z_.][a-zA-Z0-9_.]*', Name.Namespace),
  131. # anything else here also means "raise x from y" and is therefore
  132. # not an error
  133. (r'', Text, '#pop'),
  134. ],
  135. 'stringescape': [
  136. (r'\\([\\abfnrtv"\']|\n|N{.*?}|u[a-fA-F0-9]{4}|'
  137. r'U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})', String.Escape)
  138. ],
  139. 'strings': [
  140. (r'%(\([a-zA-Z0-9_]+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?'
  141. '[hlL]?[diouxXeEfFgGcrs%]', String.Interpol),
  142. (r'[^\\\'"%\n]+', String),
  143. # quotes, percents and backslashes must be parsed one at a time
  144. (r'[\'"\\]', String),
  145. # unhandled string formatting sign
  146. (r'%', String)
  147. # newlines are an error (use "nl" state)
  148. ],
  149. 'nl': [
  150. (r'\n', String)
  151. ],
  152. 'dqs': [
  153. (r'"', String, '#pop'),
  154. (r'\\\\|\\"|\\\n', String.Escape), # included here for raw strings
  155. include('strings')
  156. ],
  157. 'sqs': [
  158. (r"'", String, '#pop'),
  159. (r"\\\\|\\'|\\\n", String.Escape), # included here for raw strings
  160. include('strings')
  161. ],
  162. 'tdqs': [
  163. (r'"""', String, '#pop'),
  164. include('strings'),
  165. include('nl')
  166. ],
  167. 'tsqs': [
  168. (r"'''", String, '#pop'),
  169. include('strings'),
  170. include('nl')
  171. ],
  172. }
  173. def analyse_text(text):
  174. return shebang_matches(text, r'pythonw?(2(\.\d)?)?')
  175. class Python3Lexer(RegexLexer):
  176. """
  177. For `Python <http://www.python.org>`_ source code (version 3.0).
  178. *New in Pygments 0.10.*
  179. """
  180. name = 'Python 3'
  181. aliases = ['python3', 'py3']
  182. filenames = [] # Nothing until Python 3 gets widespread
  183. mimetypes = ['text/x-python3', 'application/x-python3']
  184. flags = re.MULTILINE | re.UNICODE
  185. uni_name = "[%s][%s]*" % (uni.xid_start, uni.xid_continue)
  186. tokens = PythonLexer.tokens.copy()
  187. tokens['keywords'] = [
  188. (r'(assert|break|continue|del|elif|else|except|'
  189. r'finally|for|global|if|lambda|pass|raise|nonlocal|'
  190. r'return|try|while|yield|as|with|True|False|None)\b', Keyword),
  191. ]
  192. tokens['builtins'] = [
  193. (r'(?<!\.)(__import__|abs|all|any|bin|bool|bytearray|bytes|'
  194. r'chr|classmethod|cmp|compile|complex|delattr|dict|dir|'
  195. r'divmod|enumerate|eval|filter|float|format|frozenset|getattr|'
  196. r'globals|hasattr|hash|hex|id|input|int|isinstance|issubclass|'
  197. r'iter|len|list|locals|map|max|memoryview|min|next|object|oct|'
  198. r'open|ord|pow|print|property|range|repr|reversed|round|'
  199. r'set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|'
  200. r'vars|zip)\b', Name.Builtin),
  201. (r'(?<!\.)(self|Ellipsis|NotImplemented)\b', Name.Builtin.Pseudo),
  202. (r'(?<!\.)(ArithmeticError|AssertionError|AttributeError|'
  203. r'BaseException|BufferError|BytesWarning|DeprecationWarning|'
  204. r'EOFError|EnvironmentError|Exception|FloatingPointError|'
  205. r'FutureWarning|GeneratorExit|IOError|ImportError|'
  206. r'ImportWarning|IndentationError|IndexError|KeyError|'
  207. r'KeyboardInterrupt|LookupError|MemoryError|NameError|'
  208. r'NotImplementedError|OSError|OverflowError|'
  209. r'PendingDeprecationWarning|ReferenceError|'
  210. r'RuntimeError|RuntimeWarning|StopIteration|'
  211. r'SyntaxError|SyntaxWarning|SystemError|SystemExit|TabError|'
  212. r'TypeError|UnboundLocalError|UnicodeDecodeError|'
  213. r'UnicodeEncodeError|UnicodeError|UnicodeTranslateError|'
  214. r'UnicodeWarning|UserWarning|ValueError|VMSError|Warning|'
  215. r'WindowsError|ZeroDivisionError)\b', Name.Exception),
  216. ]
  217. tokens['numbers'] = [
  218. (r'(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?', Number.Float),
  219. (r'0[oO][0-7]+', Number.Oct),
  220. (r'0[bB][01]+', Number.Bin),
  221. (r'0[xX][a-fA-F0-9]+', Number.Hex),
  222. (r'\d+', Number.Integer)
  223. ]
  224. tokens['backtick'] = []
  225. tokens['name'] = [
  226. (r'@[a-zA-Z0-9_]+', Name.Decorator),
  227. (uni_name, Name),
  228. ]
  229. tokens['funcname'] = [
  230. (uni_name, Name.Function, '#pop')
  231. ]
  232. tokens['classname'] = [
  233. (uni_name, Name.Class, '#pop')
  234. ]
  235. tokens['import'] = [
  236. (r'(\s+)(as)(\s+)', bygroups(Text, Keyword, Text)),
  237. (r'\.', Name.Namespace),
  238. (uni_name, Name.Namespace),
  239. (r'(\s*)(,)(\s*)', bygroups(Text, Operator, Text)),
  240. (r'', Text, '#pop') # all else: go back
  241. ]
  242. tokens['fromimport'] = [
  243. (r'(\s+)(import)\b', bygroups(Text, Keyword), '#pop'),
  244. (r'\.', Name.Namespace),
  245. (uni_name, Name.Namespace),
  246. ]
  247. # don't highlight "%s" substitutions
  248. tokens['strings'] = [
  249. (r'[^\\\'"%\n]+', String),
  250. # quotes, percents and backslashes must be parsed one at a time
  251. (r'[\'"\\]', String),
  252. # unhandled string formatting sign
  253. (r'%', String)
  254. # newlines are an error (use "nl" state)
  255. ]
  256. def analyse_text(text):
  257. return shebang_matches(text, r'pythonw?3(\.\d)?')
  258. class PythonConsoleLexer(Lexer):
  259. """
  260. For Python console output or doctests, such as:
  261. .. sourcecode:: pycon
  262. >>> a = 'foo'
  263. >>> print a
  264. foo
  265. >>> 1 / 0
  266. Traceback (most recent call last):
  267. File "<stdin>", line 1, in <module>
  268. ZeroDivisionError: integer division or modulo by zero
  269. Additional options:
  270. `python3`
  271. Use Python 3 lexer for code. Default is ``False``.
  272. *New in Pygments 1.0.*
  273. """
  274. name = 'Python console session'
  275. aliases = ['pycon']
  276. mimetypes = ['text/x-python-doctest']
  277. def __init__(self, **options):
  278. self.python3 = get_bool_opt(options, 'python3', False)
  279. Lexer.__init__(self, **options)
  280. def get_tokens_unprocessed(self, text):
  281. if self.python3:
  282. pylexer = Python3Lexer(**self.options)
  283. tblexer = Python3TracebackLexer(**self.options)
  284. else:
  285. pylexer = PythonLexer(**self.options)
  286. tblexer = PythonTracebackLexer(**self.options)
  287. curcode = ''
  288. insertions = []
  289. curtb = ''
  290. tbindex = 0
  291. tb = 0
  292. for match in line_re.finditer(text):
  293. line = match.group()
  294. if line.startswith(u'>>> ') or line.startswith(u'... '):
  295. tb = 0
  296. insertions.append((len(curcode),
  297. [(0, Generic.Prompt, line[:4])]))
  298. curcode += line[4:]
  299. elif line.rstrip() == u'...' and not tb:
  300. # only a new >>> prompt can end an exception block
  301. # otherwise an ellipsis in place of the traceback frames
  302. # will be mishandled
  303. insertions.append((len(curcode),
  304. [(0, Generic.Prompt, u'...')]))
  305. curcode += line[3:]
  306. else:
  307. if curcode:
  308. for item in do_insertions(insertions,
  309. pylexer.get_tokens_unprocessed(curcode)):
  310. yield item
  311. curcode = ''
  312. insertions = []
  313. if (line.startswith(u'Traceback (most recent call last):') or
  314. re.match(ur' File "[^"]+", line \d+\n$', line)):
  315. tb = 1
  316. curtb = line
  317. tbindex = match.start()
  318. elif line == 'KeyboardInterrupt\n':
  319. yield match.start(), Name.Class, line
  320. elif tb:
  321. curtb += line
  322. if not (line.startswith(' ') or line.strip() == u'...'):
  323. tb = 0
  324. for i, t, v in tblexer.get_tokens_unprocessed(curtb):
  325. yield tbindex+i, t, v
  326. else:
  327. yield match.start(), Generic.Output, line
  328. if curcode:
  329. for item in do_insertions(insertions,
  330. pylexer.get_tokens_unprocessed(curcode)):
  331. yield item
  332. class PythonTracebackLexer(RegexLexer):
  333. """
  334. For Python tracebacks.
  335. *New in Pygments 0.7.*
  336. """
  337. name = 'Python Traceback'
  338. aliases = ['pytb']
  339. filenames = ['*.pytb']
  340. mimetypes = ['text/x-python-traceback']
  341. tokens = {
  342. 'root': [
  343. (r'^Traceback \(most recent call last\):\n',
  344. Generic.Traceback, 'intb'),
  345. # SyntaxError starts with this.
  346. (r'^(?= File "[^"]+", line \d+)', Generic.Traceback, 'intb'),
  347. (r'^.*\n', Other),
  348. ],
  349. 'intb': [
  350. (r'^( File )("[^"]+")(, line )(\d+)(, in )(.+)(\n)',
  351. bygroups(Text, Name.Builtin, Text, Number, Text, Name, Text)),
  352. (r'^( File )("[^"]+")(, line )(\d+)(\n)',
  353. bygroups(Text, Name.Builtin, Text, Number, Text)),
  354. (r'^( )(.+)(\n)',
  355. bygroups(Text, using(PythonLexer), Text)),
  356. (r'^([ \t]*)(\.\.\.)(\n)',
  357. bygroups(Text, Comment, Text)), # for doctests...
  358. (r'^(.+)(: )(.+)(\n)',
  359. bygroups(Generic.Error, Text, Name, Text), '#pop'),
  360. (r'^([a-zA-Z_][a-zA-Z0-9_]*)(:?\n)',
  361. bygroups(Generic.Error, Text), '#pop')
  362. ],
  363. }
  364. class Python3TracebackLexer(RegexLexer):
  365. """
  366. For Python 3.0 tracebacks, with support for chained exceptions.
  367. *New in Pygments 1.0.*
  368. """
  369. name = 'Python 3.0 Traceback'
  370. aliases = ['py3tb']
  371. filenames = ['*.py3tb']
  372. mimetypes = ['text/x-python3-traceback']
  373. tokens = {
  374. 'root': [
  375. (r'\n', Text),
  376. (r'^Traceback \(most recent call last\):\n', Generic.Traceback, 'intb'),
  377. (r'^During handling of the above exception, another '
  378. r'exception occurred:\n\n', Generic.Traceback),
  379. (r'^The above exception was the direct cause of the '
  380. r'following exception:\n\n', Generic.Traceback),
  381. ],
  382. 'intb': [
  383. (r'^( File )("[^"]+")(, line )(\d+)(, in )(.+)(\n)',
  384. bygroups(Text, Name.Builtin, Text, Number, Text, Name, Text)),
  385. (r'^( )(.+)(\n)',
  386. bygroups(Text, using(Python3Lexer), Text)),
  387. (r'^([ \t]*)(\.\.\.)(\n)',
  388. bygroups(Text, Comment, Text)), # for doctests...
  389. (r'^(.+)(: )(.+)(\n)',
  390. bygroups(Generic.Error, Text, Name, Text), '#pop'),
  391. (r'^([a-zA-Z_][a-zA-Z0-9_]*)(:?\n)',
  392. bygroups(Generic.Error, Text), '#pop')
  393. ],
  394. }
  395. class RubyLexer(ExtendedRegexLexer):
  396. """
  397. For `Ruby <http://www.ruby-lang.org>`_ source code.
  398. """
  399. name = 'Ruby'
  400. aliases = ['rb', 'ruby', 'duby']
  401. filenames = ['*.rb', '*.rbw', 'Rakefile', '*.rake', '*.gemspec',
  402. '*.rbx', '*.duby']
  403. mimetypes = ['text/x-ruby', 'application/x-ruby']
  404. flags = re.DOTALL | re.MULTILINE
  405. def heredoc_callback(self, match, ctx):
  406. # okay, this is the hardest part of parsing Ruby...
  407. # match: 1 = <<-?, 2 = quote? 3 = name 4 = quote? 5 = rest of line
  408. start = match.start(1)
  409. yield start, Operator, match.group(1) # <<-?
  410. yield match.start(2), String.Heredoc, match.group(2) # quote ", ', `
  411. yield match.start(3), Name.Constant, match.group(3) # heredoc name
  412. yield match.start(4), String.Heredoc, match.group(4) # quote again
  413. heredocstack = ctx.__dict__.setdefault('heredocstack', [])
  414. outermost = not bool(heredocstack)
  415. heredocstack.append((match.group(1) == '<<-', match.group(3)))
  416. ctx.pos = match.start(5)
  417. ctx.end = match.end(5)
  418. # this may find other heredocs
  419. for i, t, v in self.get_tokens_unprocessed(context=ctx):
  420. yield i, t, v
  421. ctx.pos = match.end()
  422. if outermost:
  423. # this is the outer heredoc again, now we can process them all
  424. for tolerant, hdname in heredocstack:
  425. lines = []
  426. for match in line_re.finditer(ctx.text, ctx.pos):
  427. if tolerant:
  428. check = match.group().strip()
  429. else:
  430. check = match.group().rstrip()
  431. if check == hdname:
  432. for amatch in lines:
  433. yield amatch.start(), String.Heredoc, amatch.group()
  434. yield match.start(), Name.Constant, match.group()
  435. ctx.pos = match.end()
  436. break
  437. else:
  438. lines.append(match)
  439. else:
  440. # end of heredoc not found -- error!
  441. for amatch in lines:
  442. yield amatch.start(), Error, amatch.group()
  443. ctx.end = len(ctx.text)
  444. del heredocstack[:]
  445. def gen_rubystrings_rules():
  446. def intp_regex_callback(self, match, ctx):
  447. yield match.start(1), String.Regex, match.group(1) # begin
  448. nctx = LexerContext(match.group(3), 0, ['interpolated-regex'])
  449. for i, t, v in self.get_tokens_unprocessed(context=nctx):
  450. yield match.start(3)+i, t, v
  451. yield match.start(4), String.Regex, match.group(4) # end[mixounse]*
  452. ctx.pos = match.end()
  453. def intp_string_callback(self, match, ctx):
  454. yield match.start(1), String.Other, match.group(1)
  455. nctx = LexerContext(match.group(3), 0, ['interpolated-string'])
  456. for i, t, v in self.get_tokens_unprocessed(context=nctx):
  457. yield match.start(3)+i, t, v
  458. yield match.start(4), String.Other, match.group(4) # end
  459. ctx.pos = match.end()
  460. states = {}
  461. states['strings'] = [
  462. # easy ones
  463. (r'\:@{0,2}([a-zA-Z_]\w*[\!\?]?|\*\*?|[-+]@?|'
  464. r'[/%&|^`~]|\[\]=?|<<|>>|<=?>|>=?|===?)', String.Symbol),
  465. (r":'(\\\\|\\'|[^'])*'", String.Symbol),
  466. (r"'(\\\\|\\'|[^'])*'", String.Single),
  467. (r':"', String.Symbol, 'simple-sym'),
  468. (r'"', String.Double, 'simple-string'),
  469. (r'(?<!\.)`', String.Backtick, 'simple-backtick'),
  470. ]
  471. # double-quoted string and symbol
  472. for name, ttype, end in ('string', String.Double, '"'), \
  473. ('sym', String.Symbol, '"'), \
  474. ('backtick', String.Backtick, '`'):
  475. states['simple-'+name] = [
  476. include('string-intp-escaped'),
  477. (r'[^\\%s#]+' % end, ttype),
  478. (r'[\\#]', ttype),
  479. (end, ttype, '#pop'),
  480. ]
  481. # braced quoted strings
  482. for lbrace, rbrace, name in ('\\{', '\\}', 'cb'), \
  483. ('\\[', '\\]', 'sb'), \
  484. ('\\(', '\\)', 'pa'), \
  485. ('<', '>', 'ab'):
  486. states[name+'-intp-string'] = [
  487. (r'\\[\\' + lbrace + rbrace + ']', String.Other),
  488. (r'(?<!\\)' + lbrace, String.Other, '#push'),
  489. (r'(?<!\\)' + rbrace, String.Other, '#pop'),
  490. include('string-intp-escaped'),
  491. (r'[\\#' + lbrace + rbrace + ']', String.Other),
  492. (r'[^\\#' + lbrace + rbrace + ']+', String.Other),
  493. ]
  494. states['strings'].append((r'%[QWx]?' + lbrace, String.Other,
  495. name+'-intp-string'))
  496. states[name+'-string'] = [
  497. (r'\\[\\' + lbrace + rbrace + ']', String.Other),
  498. (r'(?<!\\)' + lbrace, String.Other, '#push'),
  499. (r'(?<!\\)' + rbrace, String.Other, '#pop'),
  500. (r'[\\#' + lbrace + rbrace + ']', String.Other),
  501. (r'[^\\#' + lbrace + rbrace + ']+', String.Other),
  502. ]
  503. states['strings'].append((r'%[qsw]' + lbrace, String.Other,
  504. name+'-string'))
  505. states[name+'-regex'] = [
  506. (r'\\[\\' + lbrace + rbrace + ']', String.Regex),
  507. (r'(?<!\\)' + lbrace, String.Regex, '#push'),
  508. (r'(?<!\\)' + rbrace + '[mixounse]*', String.Regex, '#pop'),
  509. include('string-intp'),
  510. (r'[\\#' + lbrace + rbrace + ']', String.Regex),
  511. (r'[^\\#' + lbrace + rbrace + ']+', String.Regex),
  512. ]
  513. states['strings'].append((r'%r' + lbrace, String.Regex,
  514. name+'-regex'))
  515. # these must come after %<brace>!
  516. states['strings'] += [
  517. # %r regex
  518. (r'(%r([^a-zA-Z0-9]))((?:\\\2|(?!\2).)*)(\2[mixounse]*)',
  519. intp_regex_callback),
  520. # regular fancy strings with qsw
  521. (r'%[qsw]([^a-zA-Z0-9])((?:\\\1|(?!\1).)*)\1', String.Other),
  522. (r'(%[QWx]([^a-zA-Z0-9]))((?:\\\2|(?!\2).)*)(\2)',
  523. intp_string_callback),
  524. # special forms of fancy strings after operators or
  525. # in method calls with braces
  526. (r'(?<=[-+/*%=<>&!^|~,(])(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)',
  527. bygroups(Text, String.Other, None)),
  528. # and because of fixed width lookbehinds the whole thing a
  529. # second time for line startings...
  530. (r'^(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)',
  531. bygroups(Text, String.Other, None)),
  532. # all regular fancy strings without qsw
  533. (r'(%([^a-zA-Z0-9\s]))((?:\\\2|(?!\2).)*)(\2)',
  534. intp_string_callback),
  535. ]
  536. return states
  537. tokens = {
  538. 'root': [
  539. (r'#.*?$', Comment.Single),
  540. (r'=begin\s.*?\n=end.*?$', Comment.Multiline),
  541. # keywords
  542. (r'(BEGIN|END|alias|begin|break|case|defined\?|'
  543. r'do|else|elsif|end|ensure|for|if|in|next|redo|'
  544. r'rescue|raise|retry|return|super|then|undef|unless|until|when|'
  545. r'while|yield)\b', Keyword),
  546. # start of function, class and module names
  547. (r'(module)(\s+)([a-zA-Z_][a-zA-Z0-9_]*(::[a-zA-Z_][a-zA-Z0-9_]*)*)',
  548. bygroups(Keyword, Text, Name.Namespace)),
  549. (r'(def)(\s+)', bygroups(Keyword, Text), 'funcname'),
  550. (r'def(?=[*%&^`~+-/\[<>=])', Keyword, 'funcname'),
  551. (r'(class)(\s+)', bygroups(Keyword, Text), 'classname'),
  552. # special methods
  553. (r'(initialize|new|loop|include|extend|raise|attr_reader|'
  554. r'attr_writer|attr_accessor|attr|catch|throw|private|'
  555. r'module_function|public|protected|true|false|nil)\b',
  556. Keyword.Pseudo),
  557. (r'(not|and|or)\b', Operator.Word),
  558. (r'(autoload|block_given|const_defined|eql|equal|frozen|include|'
  559. r'instance_of|is_a|iterator|kind_of|method_defined|nil|'
  560. r'private_method_defined|protected_method_defined|'
  561. r'public_method_defined|respond_to|tainted)\?', Name.Builtin),
  562. (r'(chomp|chop|exit|gsub|sub)!', Name.Builtin),
  563. (r'(?<!\.)(Array|Float|Integer|String|__id__|__send__|abort|'
  564. r'ancestors|at_exit|autoload|binding|callcc|caller|'
  565. r'catch|chomp|chop|class_eval|class_variables|'
  566. r'clone|const_defined\?|const_get|const_missing|const_set|'
  567. r'constants|display|dup|eval|exec|exit|extend|fail|fork|'
  568. r'format|freeze|getc|gets|global_variables|gsub|'
  569. r'hash|id|included_modules|inspect|instance_eval|'
  570. r'instance_method|instance_methods|'
  571. r'instance_variable_get|instance_variable_set|instance_variables|'
  572. r'lambda|load|local_variables|loop|'
  573. r'method|method_missing|methods|module_eval|name|'
  574. r'object_id|open|p|print|printf|private_class_method|'
  575. r'private_instance_methods|'
  576. r'private_methods|proc|protected_instance_methods|'
  577. r'protected_methods|public_class_method|'
  578. r'public_instance_methods|public_methods|'
  579. r'putc|puts|raise|rand|readline|readlines|require|'
  580. r'scan|select|self|send|set_trace_func|singleton_methods|sleep|'
  581. r'split|sprintf|srand|sub|syscall|system|taint|'
  582. r'test|throw|to_a|to_s|trace_var|trap|untaint|untrace_var|'
  583. r'warn)\b', Name.Builtin),
  584. (r'__(FILE|LINE)__\b', Name.Builtin.Pseudo),
  585. # normal heredocs
  586. (r'(?<!\w)(<<-?)(["`\']?)([a-zA-Z_]\w*)(\2)(.*?\n)',
  587. heredoc_callback),
  588. # empty string heredocs
  589. (r'(<<-?)("|\')()(\2)(.*?\n)', heredoc_callback),
  590. (r'__END__', Comment.Preproc, 'end-part'),
  591. # multiline regex (after keywords or assignments)
  592. (r'(?:^|(?<=[=<>~!])|'
  593. r'(?<=(?:\s|;)when\s)|'
  594. r'(?<=(?:\s|;)or\s)|'
  595. r'(?<=(?:\s|;)and\s)|'
  596. r'(?<=(?:\s|;|\.)index\s)|'
  597. r'(?<=(?:\s|;|\.)scan\s)|'
  598. r'(?<=(?:\s|;|\.)sub\s)|'
  599. r'(?<=(?:\s|;|\.)sub!\s)|'
  600. r'(?<=(?:\s|;|\.)gsub\s)|'
  601. r'(?<=(?:\s|;|\.)gsub!\s)|'
  602. r'(?<=(?:\s|;|\.)match\s)|'
  603. r'(?<=(?:\s|;)if\s)|'
  604. r'(?<=(?:\s|;)elsif\s)|'
  605. r'(?<=^when\s)|'
  606. r'(?<=^index\s)|'
  607. r'(?<=^scan\s)|'
  608. r'(?<=^sub\s)|'
  609. r'(?<=^gsub\s)|'
  610. r'(?<=^sub!\s)|'
  611. r'(?<=^gsub!\s)|'
  612. r'(?<=^match\s)|'
  613. r'(?<=^if\s)|'
  614. r'(?<=^elsif\s)'
  615. r')(\s*)(/)', bygroups(Text, String.Regex), 'multiline-regex'),
  616. # multiline regex (in method calls or subscripts)
  617. (r'(?<=\(|,|\[)/', String.Regex, 'multiline-regex'),
  618. # multiline regex (this time the funny no whitespace rule)
  619. (r'(\s+)(/)(?![\s=])', bygroups(Text, String.Regex),
  620. 'multiline-regex'),
  621. # lex numbers and ignore following regular expressions which
  622. # are division operators in fact (grrrr. i hate that. any
  623. # better ideas?)
  624. # since pygments 0.7 we also eat a "?" operator after numbers
  625. # so that the char operator does not work. Chars are not allowed
  626. # there so that you can use the ternary operator.
  627. # stupid example:
  628. # x>=0?n[x]:""
  629. (r'(0_?[0-7]+(?:_[0-7]+)*)(\s*)([/?])?',
  630. bygroups(Number.Oct, Text, Operator)),
  631. (r'(0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*)(\s*)([/?])?',
  632. bygroups(Number.Hex, Text, Operator)),
  633. (r'(0b[01]+(?:_[01]+)*)(\s*)([/?])?',
  634. bygroups(Number.Bin, Text, Operator)),
  635. (r'([\d]+(?:_\d+)*)(\s*)([/?])?',
  636. bygroups(Number.Integer, Text, Operator)),
  637. # Names
  638. (r'@@[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable.Class),
  639. (r'@[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable.Instance),
  640. (r'\$[a-zA-Z0-9_]+', Name.Variable.Global),
  641. (r'\$[!@&`\'+~=/\\,;.<>_*$?:"]', Name.Variable.Global),
  642. (r'\$-[0adFiIlpvw]', Name.Variable.Global),
  643. (r'::', Operator),
  644. include('strings'),
  645. # chars
  646. (r'\?(\\[MC]-)*' # modifiers
  647. r'(\\([\\abefnrstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})|\S)'
  648. r'(?!\w)',
  649. String.Char),
  650. (r'[A-Z][a-zA-Z0-9_]+', Name.Constant),
  651. # this is needed because ruby attributes can look
  652. # like keywords (class) or like this: ` ?!?
  653. (r'(\.|::)([a-zA-Z_]\w*[\!\?]?|[*%&^`~+-/\[<>=])',
  654. bygroups(Operator, Name)),
  655. (r'[a-zA-Z_]\w*[\!\?]?', Name),
  656. (r'(\[|\]|\*\*|<<?|>>?|>=|<=|<=>|=~|={3}|'
  657. r'!~|&&?|\|\||\.{1,3})', Operator),
  658. (r'[-+/*%=<>&!^|~]=?', Operator),
  659. (r'[(){};,/?:\\]', Punctuation),
  660. (r'\s+', Text)
  661. ],
  662. 'funcname': [
  663. (r'\(', Punctuation, 'defexpr'),
  664. (r'(?:([a-zA-Z_][a-zA-Z0-9_]*)(\.))?'
  665. r'([a-zA-Z_]\w*[\!\?]?|\*\*?|[-+]@?|'
  666. r'[/%&|^`~]|\[\]=?|<<|>>|<=?>|>=?|===?)',
  667. bygroups(Name.Class, Operator, Name.Function), '#pop'),
  668. (r'', Text, '#pop')
  669. ],
  670. 'classname': [
  671. (r'\(', Punctuation, 'defexpr'),
  672. (r'<<', Operator, '#pop'),
  673. (r'[A-Z_]\w*', Name.Class, '#pop'),
  674. (r'', Text, '#pop')
  675. ],
  676. 'defexpr': [
  677. (r'(\))(\.|::)?', bygroups(Punctuation, Operator), '#pop'),
  678. (r'\(', Operator, '#push'),
  679. include('root')
  680. ],
  681. 'in-intp': [
  682. ('}', String.Interpol, '#pop'),
  683. include('root'),
  684. ],
  685. 'string-intp': [
  686. (r'#{', String.Interpol, 'in-intp'),
  687. (r'#@@?[a-zA-Z_][a-zA-Z0-9_]*', String.Interpol),
  688. (r'#\$[a-zA-Z_][a-zA-Z0-9_]*', String.Interpol)
  689. ],
  690. 'string-intp-escaped': [
  691. include('string-intp'),
  692. (r'\\([\\abefnrstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})',
  693. String.Escape)
  694. ],
  695. 'interpolated-regex': [
  696. include('string-intp'),
  697. (r'[\\#]', String.Regex),
  698. (r'[^\\#]+', String.Regex),
  699. ],
  700. 'interpolated-string': [
  701. include('string-intp'),
  702. (r'[\\#]', String.Other),
  703. (r'[^\\#]+', String.Other),
  704. ],
  705. 'multiline-regex': [
  706. include('string-intp'),
  707. (r'\\\\', String.Regex),
  708. (r'\\/', String.Regex),
  709. (r'[\\#]', String.Regex),
  710. (r'[^\\/#]+', String.Regex),
  711. (r'/[mixounse]*', String.Regex, '#pop'),
  712. ],
  713. 'end-part': [
  714. (r'.+', Comment.Preproc, '#pop')
  715. ]
  716. }
  717. tokens.update(gen_rubystrings_rules())
  718. def analyse_text(text):
  719. return shebang_matches(text, r'ruby(1\.\d)?')
  720. class RubyConsoleLexer(Lexer):
  721. """
  722. For Ruby interactive console (**irb**) output like:
  723. .. sourcecode:: rbcon
  724. irb(main):001:0> a = 1
  725. => 1
  726. irb(main):002:0> puts a
  727. 1
  728. => nil
  729. """
  730. name = 'Ruby irb session'
  731. aliases = ['rbcon', 'irb']
  732. mimetypes = ['text/x-ruby-shellsession']
  733. _prompt_re = re.compile('irb\([a-zA-Z_][a-zA-Z0-9_]*\):\d{3}:\d+[>*"\'] '
  734. '|>> |\?> ')
  735. def get_tokens_unprocessed(self, text):
  736. rblexer = RubyLexer(**self.options)
  737. curcode = ''
  738. insertions = []
  739. for match in line_re.finditer(text):
  740. line = match.group()
  741. m = self._prompt_re.match(line)
  742. if m is not None:
  743. end = m.end()
  744. insertions.append((len(curcode),
  745. [(0, Generic.Prompt, line[:end])]))
  746. curcode += line[end:]
  747. else:
  748. if curcode:
  749. for item in do_insertions(insertions,
  750. rblexer.get_tokens_unprocessed(curcode)):
  751. yield item
  752. curcode = ''
  753. insertions = []
  754. yield match.start(), Generic.Output, line
  755. if curcode:
  756. for item in do_insertions(insertions,
  757. rblexer.get_tokens_unprocessed(curcode)):
  758. yield item
  759. class PerlLexer(RegexLexer):
  760. """
  761. For `Perl <http://www.perl.org>`_ source code.
  762. """
  763. name = 'Perl'
  764. aliases = ['perl', 'pl']
  765. filenames = ['*.pl', '*.pm']
  766. mimetypes = ['text/x-perl', 'application/x-perl']
  767. flags = re.DOTALL | re.MULTILINE
  768. # TODO: give this to a perl guy who knows how to parse perl...
  769. tokens = {
  770. 'balanced-regex': [
  771. (r'/(\\\\|\\[^\\]|[^\\/])*/[egimosx]*', String.Regex, '#pop'),
  772. (r'!(\\\\|\\[^\\]|[^\\!])*![egimosx]*', String.Regex, '#pop'),
  773. (r'\\(\\\\|[^\\])*\\[egimosx]*', String.Regex, '#pop'),
  774. (r'{(\\\\|\\[^\\]|[^\\}])*}[egimosx]*', String.Regex, '#pop'),
  775. (r'<(\\\\|\\[^\\]|[^\\>])*>[egimosx]*', String.Regex, '#pop'),
  776. (r'\[(\\\\|\\[^\\]|[^\\\]])*\][egimosx]*', String.Regex, '#pop'),
  777. (r'\((\\\\|\\[^\\]|[^\\\)])*\)[egimosx]*', String.Regex, '#pop'),
  778. (r'@(\\\\|\\[^\\]|[^\\\@])*@[egimosx]*', String.Regex, '#pop'),
  779. (r'%(\\\\|\\[^\\]|[^\\\%])*%[egimosx]*', String.Regex, '#pop'),
  780. (r'\$(\\\\|\\[^\\]|[^\\\$])*\$[egimosx]*', String.Regex, '#pop'),
  781. ],
  782. 'root': [
  783. (r'\#.*?$', Comment.Single),
  784. (r'^=[a-zA-Z0-9]+\s+.*?\n=cut', Comment.Multiline),
  785. (r'(case|continue|do|else|elsif|for|foreach|if|last|my|'
  786. r'next|our|redo|reset|then|unless|until|while|use|'
  787. r'print|new|BEGIN|CHECK|INIT|END|return)\b', Keyword),
  788. (r'(format)(\s+)([a-zA-Z0-9_]+)(\s*)(=)(\s*\n)',
  789. bygroups(Keyword, Text, Name, Text, Punctuation, Text), 'format'),
  790. (r'(eq|lt|gt|le|ge|ne|not|and|or|cmp)\b', Operator.Word),
  791. # common delimiters
  792. (r's/(\\\\|\\[^\\]|[^\\/])*/(\\\\|\\[^\\]|[^\\/])*/[egimosx]*',
  793. String.Regex),
  794. (r's!(\\\\|\\!|[^!])*!(\\\\|\\!|[^!])*![egimosx]*', String.Regex),
  795. (r's\\(\\\\|[^\\])*\\(\\\\|[^\\])*\\[egimosx]*', String.Regex),
  796. (r's@(\\\\|\\[^\\]|[^\\@])*@(\\\\|\\[^\\]|[^\\@])*@[egimosx]*',
  797. String.Regex),
  798. (r's%(\\\\|\\[^\\]|[^\\%])*%(\\\\|\\[^\\]|[^\\%])*%[egimosx]*',
  799. String.Regex),
  800. # balanced delimiters
  801. (r's{(\\\\|\\[^\\]|[^\\}])*}\s*', String.Regex, 'balanced-regex'),
  802. (r's<(\\\\|\\[^\\]|[^\\>])*>\s*', String.Regex, 'balanced-regex'),
  803. (r's\[(\\\\|\\[^\\]|[^\\\]])*\]\s*', String.Regex,
  804. 'balanced-regex'),
  805. (r's\((\\\\|\\[^\\]|[^\\\)])*\)\s*', String.Regex,
  806. 'balanced-regex'),
  807. (r'm?/(\\\\|\\[^\\]|[^\\/\n])*/[gcimosx]*', String.Regex),
  808. (r'm(?=[/!\\{<\[\(@%\$])', String.Regex, 'balanced-regex'),
  809. (r'((?<==~)|(?<=\())\s*/(\\\\|\\[^\\]|[^\\/])*/[gcimosx]*',
  810. String.Regex),
  811. (r'\s+', Text),
  812. (r'(abs|accept|alarm|atan2|bind|binmode|bless|caller|chdir|'
  813. r'chmod|chomp|chop|chown|chr|chroot|close|closedir|connect|'
  814. r'continue|cos|crypt|dbmclose|dbmopen|defined|delete|die|'
  815. r'dump|each|endgrent|endhostent|endnetent|endprotoent|'
  816. r'endpwent|endservent|eof|eval|exec|exists|exit|exp|fcntl|'
  817. r'fileno|flock|fork|format|formline|getc|getgrent|getgrgid|'
  818. r'getgrnam|gethostbyaddr|gethostbyname|gethostent|getlogin|'
  819. r'getnetbyaddr|getnetbyname|getnetent|getpeername|getpgrp|'
  820. r'getppid|getpriority|getprotobyname|getprotobynumber|'
  821. r'getprotoent|getpwent|getpwnam|getpwuid|getservbyname|'
  822. r'getservbyport|getservent|getsockname|getsockopt|glob|gmtime|'
  823. r'goto|grep|hex|import|index|int|ioctl|join|keys|kill|last|'
  824. r'lc|lcfirst|length|link|listen|local|localtime|log|lstat|'
  825. r'map|mkdir|msgctl|msgget|msgrcv|msgsnd|my|next|no|oct|open|'
  826. r'opendir|ord|our|pack|package|pipe|pop|pos|printf|'
  827. r'prototype|push|quotemeta|rand|read|readdir|'
  828. r'readline|readlink|readpipe|recv|redo|ref|rename|require|'
  829. r'reverse|rewinddir|rindex|rmdir|scalar|seek|seekdir|'
  830. r'select|semctl|semget|semop|send|setgrent|sethostent|setnetent|'
  831. r'setpgrp|setpriority|setprotoent|setpwent|setservent|'
  832. r'setsockopt|shift|shmctl|shmget|shmread|shmwrite|shutdown|'
  833. r'sin|sleep|socket|socketpair|sort|splice|split|sprintf|sqrt|'
  834. r'srand|stat|study|substr|symlink|syscall|sysopen|sysread|'
  835. r'sysseek|system|syswrite|tell|telldir|tie|tied|time|times|tr|'
  836. r'truncate|uc|ucfirst|umask|undef|unlink|unpack|unshift|untie|'
  837. r'utime|values|vec|wait|waitpid|wantarray|warn|write'
  838. r')\b', Name.Builtin),
  839. (r'((__(DATA|DIE|WARN)__)|(STD(IN|OUT|ERR)))\b', Name.Builtin.Pseudo),
  840. (r'<<([\'"]?)([a-zA-Z_][a-zA-Z0-9_]*)\1;?\n.*?\n\2\n', String),
  841. (r'__END__', Comment.Preproc, 'end-part'),
  842. (r'\$\^[ADEFHILMOPSTWX]', Name.Variable.Global),
  843. (r"\$[\\\"\[\]'&`+*.,;=%~?@$!<>(^|/-](?!\w)", Name.Variable.Global),
  844. (r'[$@%#]+', Name.Variable, 'varname'),
  845. (r'0_?[0-7]+(_[0-7]+)*', Number.Oct),
  846. (r'0x[0-9A-Fa-f]+(_[0-9A-Fa-f]+)*', Number.Hex),
  847. (r'0b[01]+(_[01]+)*', Number.Bin),
  848. (r'(?i)(\d*(_\d*)*\.\d+(_\d*)*|\d+(_\d*)*\.\d+(_\d*)*)(e[+-]?\d+)?',
  849. Number.Float),
  850. (r'(?i)\d+(_\d*)*e[+-]?\d+(_\d*)*', Number.Float),
  851. (r'\d+(_\d+)*', Number.Integer),
  852. (r"'(\\\\|\\[^\\]|[^'\\])*'", String),
  853. (r'"(\\\\|\\[^\\]|[^"\\])*"', String),
  854. (r'`(\\\\|\\[^\\]|[^`\\])*`', String.Backtick),
  855. (r'<([^\s>]+)>', String.Regex),
  856. (r'(q|qq|qw|qr|qx)\{', String.Other, 'cb-string'),
  857. (r'(q|qq|qw|qr|qx)\(', String.Other, 'rb-string'),
  858. (r'(q|qq|qw|qr|qx)\[', String.Other, 'sb-string'),
  859. (r'(q|qq|qw|qr|qx)\<', String.Other, 'lt-string'),
  860. (r'(q|qq|qw|qr|qx)([^a-zA-Z0-9])(.|\n)*?\2', String.Other),
  861. (r'package\s+', Keyword, 'modulename'),
  862. (r'sub\s+', Keyword, 'funcname'),
  863. (r'(\[\]|\*\*|::|<<|>>|>=|<=>|<=|={3}|!=|=~|'
  864. r'!~|&&?|\|\||\.{1,3})', Operator),
  865. (r'[-+/*%=<>&^|!\\~]=?', Operator),
  866. (r'[\(\)\[\]:;,<>/\?\{\}]', Punctuation), # yes, there's no shortage
  867. # of punctuation in Perl!
  868. (r'(?=\w)', Name, 'name'),
  869. ],
  870. 'format': [
  871. (r'\.\n', String.Interpol, '#pop'),
  872. (r'[^\n]*\n', String.Interpol),
  873. ],
  874. 'varname': [
  875. (r'\s+', Text),
  876. (r'\{', Punctuation, '#pop'), # hash syntax?
  877. (r'\)|,', Punctuation, '#pop'), # argument specifier
  878. (r'[a-zA-Z0-9_]+::', Name.Namespace),
  879. (r'[a-zA-Z0-9_:]+', Name.Variable, '#pop'),
  880. ],
  881. 'name': [
  882. (r'[a-zA-Z0-9_]+::', Name.Namespace),
  883. (r'[a-zA-Z0-9_:]+', Name, '#pop'),
  884. (r'[A-Z_]+(?=[^a-zA-Z0-9_])', Name.Constant, '#pop'),
  885. (r'(?=[^a-zA-Z0-9_])', Text, '#pop'),
  886. ],
  887. 'modulename': [
  888. (r'[a-zA-Z_]\w*', Name.Namespace, '#pop')
  889. ],
  890. 'funcname': [
  891. (r'[a-zA-Z_]\w*[\!\?]?', Name.Function),
  892. (r'\s+', Text),
  893. # argument declaration
  894. (r'(\([$@%]*\))(\s*)', bygroups(Punctuation, Text)),
  895. (r'.*?{', Punctuation, '#pop'),
  896. (r';', Punctuation, '#pop'),
  897. ],
  898. 'cb-string': [
  899. (r'\\[\{\}\\]', String.Other),
  900. (r'\\', String.Other),
  901. (r'\{', String.Other, 'cb-string'),
  902. (r'\}', String.Other, '#pop'),
  903. (r'[^\{\}\\]+', String.Other)
  904. ],
  905. 'rb-string': [
  906. (r'\\[\(\)\\]', String.Other),
  907. (r'\\', String.Other),
  908. (r'\(', String.Other, 'rb-string'),
  909. (r'\)', String.Other, '#pop'),
  910. (r'[^\(\)]+', String.Other)
  911. ],
  912. 'sb-string': [
  913. (r'\\[\[\]\\]', String.Other),
  914. (r'\\', String.Other),
  915. (r'\[', String.Other, 'sb-string'),
  916. (r'\]', String.Other, '#pop'),
  917. (r'[^\[\]]+', String.Other)
  918. ],
  919. 'lt-string': [
  920. (r'\\[\<\>\\]', String.Other),
  921. (r'\\', String.Other),
  922. (r'\<', String.Other, 'lt-string'),
  923. (r'\>', String.Other, '#pop'),
  924. (r'[^\<\>]+', String.Other)
  925. ],
  926. 'end-part': [
  927. (r'.+', Comment.Preproc, '#pop')
  928. ]
  929. }
  930. def analyse_text(text):
  931. if shebang_matches(text, r'perl'):
  932. return True
  933. if 'my $' in text:
  934. return 0.9
  935. return 0.1 # who knows, might still be perl!
  936. class LuaLexer(RegexLexer):
  937. """
  938. For `Lua <http://www.lua.org>`_ source code.
  939. Additional options accepted:
  940. `func_name_highlighting`
  941. If given and ``True``, highlight builtin function names
  942. (default: ``True``).
  943. `disabled_modules`
  944. If given, must be a list of module names whose function names
  945. should not be highlighted. By default all modules are highlighted.
  946. To get a list of allowed modules have a look into the
  947. `_luabuiltins` module:
  948. .. sourcecode:: pycon
  949. >>> from pygments.lexers._luabuiltins import MODULES
  950. >>> MODULES.keys()
  951. ['string', 'coroutine', 'modules', 'io', 'basic', ...]
  952. """
  953. name = 'Lua'
  954. aliases = ['lua']
  955. filenames = ['*.lua', '*.wlua']
  956. mimetypes = ['text/x-lua', 'application/x-lua']
  957. tokens = {
  958. 'root': [
  959. # lua allows a file to start with a shebang
  960. (r'#!(.*?)$', Comment.Preproc),
  961. (r'', Text, 'base'),
  962. ],
  963. 'base': [
  964. (r'(?s)--\[(=*)\[.*?\]\1\]', Comment.Multiline),
  965. ('--.*$', Comment.Single),
  966. (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float),
  967. (r'(?i)\d+e[+-]?\d+', Number.Float),
  968. ('(?i)0x[0-9a-f]*', Number.Hex),
  969. (r'\d+', Number.Integer),
  970. (r'\n', Text),
  971. (r'[^\S\n]', Text),
  972. # multiline strings
  973. (r'(?s)\[(=*)\[.*?\]\1\]', String),
  974. (r'(==|~=|<=|>=|\.\.\.|\.\.|[=+\-*/%^<>#])', Operator),
  975. (r'[\[\]\{\}\(\)\.,:;]', Punctuation),
  976. (r'(and|or|not)\b', Operator.Word),
  977. ('(break|do|else|elseif|end|for|if|in|repeat|return|then|until|'
  978. r'while)\b', Keyword),
  979. (r'(local)\b', Keyword.Declaration),
  980. (r'(true|false|nil)\b', Keyword.Constant),
  981. (r'(function)\b', Keyword, 'funcname'),
  982. (r'[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?', Name),
  983. ("'", String.Single, combined('stringescape', 'sqs')),
  984. ('"', String.Double, combined('stringescape', 'dqs'))
  985. ],
  986. 'funcname': [
  987. (r'\s+', Text),
  988. ('(?:([A-Za-z_][A-Za-z0-9_]*)(\.))?([A-Za-z_][A-Za-z0-9_]*)',
  989. bygroups(Name.Class, Punctuation, Name.Function), '#pop'),
  990. # inline function
  991. ('\(', Punctuation, '#pop'),
  992. ],
  993. # if I understand correctly, every character is valid in a lua string,
  994. # so this state is only for later corrections
  995. 'string': [
  996. ('.', String)
  997. ],
  998. 'stringescape': [
  999. (r'''\\([abfnrtv\\"']|\d{1,3})''', String.Escape)
  1000. ],
  1001. 'sqs': [
  1002. ("'", String, '#pop'),
  1003. include('string')
  1004. ],
  1005. 'dqs': [
  1006. ('"', String, '#pop'),
  1007. include('string')
  1008. ]
  1009. }
  1010. def __init__(self, **options):
  1011. self.func_name_highlighting = get_bool_opt(
  1012. options, 'func_name_highlighting', True)
  1013. self.disabled_modules = get_list_opt(options, 'disabled_modules', [])
  1014. self._functions = set()
  1015. if self.func_name_highlighting:
  1016. from pygments.lexers._luabuiltins import MODULES
  1017. for mod, func in MODULES.iteritems():
  1018. if mod not in self.disabled_modules:
  1019. self._functions.update(func)
  1020. RegexLexer.__init__(self, **options)
  1021. def get_tokens_unprocessed(self, text):
  1022. for index, token, value in \
  1023. RegexLexer.get_tokens_unprocessed(self, text):
  1024. if token is Name:
  1025. if value in self._functions:
  1026. yield index, Name.Builtin, value
  1027. continue
  1028. elif '.' in value:
  1029. a, b = value.split('.')
  1030. yield index, Name, a
  1031. yield index + len(a), Punctuation, u'.'
  1032. yield index + len(a) + 1, Name, b
  1033. continue
  1034. yield index, token, value
  1035. class MoonScriptLexer(LuaLexer):
  1036. """
  1037. For `MoonScript <http://moonscript.org.org>`_ source code.
  1038. *New in Pygments 1.5.*
  1039. """
  1040. name = "MoonScript"
  1041. aliases = ["moon", "moonscript"]
  1042. filenames = ["*.moon"]
  1043. mimetypes = ['text/x-moonscript', 'application/x-moonscript']
  1044. tokens = {
  1045. 'root': [
  1046. (r'#!(.*?)$', Comment.Preproc),
  1047. (r'', Text, 'base'),
  1048. ],
  1049. 'base': [
  1050. ('--.*$', Comment.Single),
  1051. (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float),
  1052. (r'(?i)\d+e[+-]?\d+', Number.Float),
  1053. (r'(?i)0x[0-9a-f]*', Number.Hex),
  1054. (r'\d+', Number.Integer),
  1055. (r'\n', Text),
  1056. (r'[^\S\n]+', Text),
  1057. (r'(?s)\[(=*)\[.*?\]\1\]', String),
  1058. (r'(->|=>)', Name.Function),
  1059. (r':[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable),
  1060. (r'(==|!=|~=|<=|>=|\.\.\.|\.\.|[=+\-*/%^<>#!.\\:])', Operator),
  1061. (r'[;,]', Punctuation),
  1062. (r'[\[\]\{\}\(\)]', Keyword.Type),
  1063. (r'[a-zA-Z_][a-zA-Z0-9_]*:', Name.Variable),
  1064. (r"(class|extends|if|then|super|do|with|import|export|"
  1065. r"while|elseif|return|for|in|from|when|using|else|"
  1066. r"and|or|not|switch|break)\b", Keyword),
  1067. (r'(true|false|nil)\b', Keyword.Constant),
  1068. (r'(and|or|not)\b', Operator.Word),
  1069. (r'(self)\b', Name.Builtin.Pseudo),
  1070. (r'@@?([a-zA-Z_][a-zA-Z0-9_]*)?', Name.Variable.Class),
  1071. (r'[A-Z]\w*', Name.Class), # proper name
  1072. (r'[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?', Name),
  1073. ("'", String.Single, combined('stringescape', 'sqs')),
  1074. ('"', String.Double, combined('stringescape', 'dqs'))
  1075. ],
  1076. 'stringescape': [
  1077. (r'''\\([abfnrtv\\"']|\d{1,3})''', String.Escape)
  1078. ],
  1079. 'sqs': [
  1080. ("'", String.Single, '#pop'),
  1081. (".", String)
  1082. ],
  1083. 'dqs': [
  1084. ('"', String.Double, '#pop'),
  1085. (".", String)
  1086. ]
  1087. }
  1088. def get_tokens_unprocessed(self, text):
  1089. # set . as Operator instead of Punctuation
  1090. for index, token, value in \
  1091. LuaLexer.get_tokens_unprocessed(self, text):
  1092. if token == Punctuation and value == ".":
  1093. token = Operator
  1094. yield index, token, value
  1095. class CrocLexer(RegexLexer):
  1096. """
  1097. For `Croc <http://jfbillingsley.com/croc>`_ source.
  1098. """
  1099. name = 'Croc'
  1100. filenames = ['*.croc']
  1101. aliases = ['croc']
  1102. mimetypes = ['text/x-crocsrc']
  1103. tokens = {
  1104. 'root': [
  1105. (r'\n', Text),
  1106. (r'\s+', Text),
  1107. # Comments
  1108. (r'//(.*?)\n', Comment.Single),
  1109. (r'/\*', Comment.Multiline, 'nestedcomment'),
  1110. # Keywords
  1111. (r'(as|assert|break|case|catch|class|continue|default'
  1112. r'|do|else|finally|for|foreach|function|global|namespace'
  1113. r'|if|import|in|is|local|module|return|scope|super|switch'
  1114. r'|this|throw|try|vararg|while|with|yield)\b', Keyword),
  1115. (r'(false|true|null)\b', Keyword.Constant),
  1116. # FloatLiteral
  1117. (r'([0-9][0-9_]*)(?=[.eE])(\.[0-9][0-9_]*)?([eE][+\-]?[0-9_]+)?', Number.Float),
  1118. # IntegerLiteral
  1119. # -- Binary
  1120. (r'0[bB][01][01_]*', Number),
  1121. # -- Hexadecimal
  1122. (r'0[xX][0-9a-fA-F][0-9a-fA-F_]*', Number.Hex),
  1123. # -- Decimal
  1124. (r'([0-9][0-9_]*)(?![.eE])', Number.Integer),
  1125. # CharacterLiteral
  1126. (r"""'(\\['"\\nrt]|\\x[0-9a-fA-F]{2}|\\[0-9]{1,3}"""
  1127. r"""|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|.)'""",
  1128. String.Char
  1129. ),
  1130. # StringLiteral
  1131. # -- WysiwygString
  1132. (r'@"(""|[^"])*"', String),
  1133. (r'@`(``|[^`])*`', String),
  1134. (r"@'(''|[^'])*'", String),
  1135. # -- DoubleQuotedString
  1136. (r'"(\\\\|\\"|[^"])*"', String),
  1137. # Tokens
  1138. (
  1139. r'(~=|\^=|%=|\*=|==|!=|>>>=|>>>|>>=|>>|>=|<=>|\?=|-\>'
  1140. r'|<<=|<<|<=|\+\+|\+=|--|-=|\|\||\|=|&&|&=|\.\.|/=)'
  1141. r'|[-/.&$@|\+<>!()\[\]{}?,;:=*%^~#\\]', Punctuation
  1142. ),
  1143. # Identifier
  1144. (r'[a-zA-Z_]\w*', Name),
  1145. ],
  1146. 'nestedcomment': [
  1147. (r'[^*/]+', Comment.Multiline),
  1148. (r'/\*', Comment.Multiline, '#push'),
  1149. (r'\*/', Comment.Multiline, '#pop'),
  1150. (r'[*/]', Comment.Multiline),
  1151. ],
  1152. }
  1153. class MiniDLexer(CrocLexer):
  1154. """
  1155. For MiniD source. MiniD is now known as Croc.
  1156. """
  1157. name = 'MiniD'
  1158. filenames = ['*.md']
  1159. aliases = ['minid']
  1160. mimetypes = ['text/x-minidsrc']
  1161. class IoLexer(RegexLexer):
  1162. """
  1163. For `Io <http://iolanguage.com/>`_ (a small, prototype-based
  1164. programming language) source.
  1165. *New in Pygments 0.10.*
  1166. """
  1167. name = 'Io'
  1168. filenames = ['*.io']
  1169. aliases = ['io']
  1170. mimetypes = ['text/x-iosrc']
  1171. tokens = {
  1172. 'root': [
  1173. (r'\n', Text),
  1174. (r'\s+', Text),
  1175. # Comments
  1176. (r'//(.*?)\n', Comment.Single),
  1177. (r'#(.*?)\n', Comment.Single),
  1178. (r'/(\\\n)?[*](.|\n)*?[*](\\\n)?/', Comment.Multiline),
  1179. (r'/\+', Comment.Multiline, 'nestedcomment'),
  1180. # DoubleQuotedString
  1181. (r'"(\\\\|\\"|[^"])*"', String),
  1182. # Operators
  1183. (r'::=|:=|=|\(|\)|;|,|\*|-|\+|>|<|@|!|/|\||\^|\.|%|&|\[|\]|\{|\}',
  1184. Operator),
  1185. # keywords
  1186. (r'(clone|do|doFile|doString|method|for|if|else|elseif|then)\b',
  1187. Keyword),
  1188. # constants
  1189. (r'(nil|false|true)\b', Name.Constant),
  1190. # names
  1191. (r'(Object|list|List|Map|args|Sequence|Coroutine|File)\b',
  1192. Name.Builtin),
  1193. ('[a-zA-Z_][a-zA-Z0-9_]*', Name),
  1194. # numbers
  1195. (r'(\d+\.?\d*|\d*\.\d+)([eE][+-]?[0-9]+)?', Number.Float),
  1196. (r'\d+', Number.Integer)
  1197. ],
  1198. 'nestedcomment': [
  1199. (r'[^+/]+', Comment.Multiline),
  1200. (r'/\+', Comment.Multiline, '#push'),
  1201. (r'\+/', Comment.Multiline, '#pop'),
  1202. (r'[+/]', Comment.Multiline),
  1203. ]
  1204. }
  1205. class TclLexer(RegexLexer):
  1206. """
  1207. For Tcl source code.
  1208. *New in Pygments 0.10.*
  1209. """
  1210. keyword_cmds_re = (
  1211. r'\b(after|apply|array|break|catch|continue|elseif|else|error|'
  1212. r'eval|expr|for|foreach|global|if|namespace|proc|rename|return|'
  1213. r'set|switch|then|trace|unset|update|uplevel|upvar|variable|'
  1214. r'vwait|while)\b'
  1215. )
  1216. builtin_cmds_re = (
  1217. r'\b(append|bgerror|binary|cd|chan|clock|close|concat|dde|dict|'
  1218. r'encoding|eof|exec|exit|fblocked|fconfigure|fcopy|file|'
  1219. r'fileevent|flush|format|gets|glob|history|http|incr|info|interp|'
  1220. r'join|lappend|lassign|lindex|linsert|list|llength|load|loadTk|'
  1221. r'lrange|lrepeat|lreplace|lreverse|lsearch|lset|lsort|mathfunc|'
  1222. r'mathop|memory|msgcat|open|package|pid|pkg::create|pkg_mkIndex|'
  1223. r'platform|platform::shell|puts|pwd|re_syntax|read|refchan|'
  1224. r'regexp|registry|regsub|scan|seek|socket|source|split|string|'
  1225. r'subst|tell|time|tm|unknown|unload)\b'
  1226. )
  1227. name = 'Tcl'
  1228. aliases = ['tcl']
  1229. filenames = ['*.tcl']
  1230. mimetypes = ['text/x-tcl', 'text/x-script.tcl', 'application/x-tcl']
  1231. def _gen_command_rules(keyword_cmds_re, builtin_cmds_re, context=""):
  1232. return [
  1233. (keyword_cmds_re, Keyword, 'params' + context),
  1234. (builtin_cmds_re, Name.Builtin, 'params' + context),
  1235. (r'([\w\.\-]+)', Name.Variable, 'params' + context),
  1236. (r'#', Comment, 'comment'),
  1237. ]
  1238. tokens = {
  1239. 'root': [
  1240. include('command'),
  1241. include('basic'),
  1242. include('data'),
  1243. (r'}', Keyword), # HACK: somehow we miscounted our braces
  1244. ],
  1245. 'command': _gen_command_rules(keyword_cmds_re, builtin_cmds_re),
  1246. 'command-in-brace': _gen_command_rules(keyword_cmds_re,
  1247. builtin_cmds_re,
  1248. "-in-brace"),
  1249. 'command-in-bracket': _gen_command_rules(keyword_cmds_re,
  1250. builtin_cmds_re,
  1251. "-in-bracket"),
  1252. 'command-in-paren': _gen_command_rules(keyword_cmds_re,
  1253. builtin_cmds_re,
  1254. "-in-paren"),
  1255. 'basic': [
  1256. (r'\(', Keyword, 'paren'),
  1257. (r'\[', Keyword, 'bracket'),
  1258. (r'\{', Keyword, 'brace'),
  1259. (r'"', String.Double, 'string'),
  1260. (r'(eq|ne|in|ni)\b', Operator.Word),
  1261. (r'!=|==|<<|>>|<=|>=|&&|\|\||\*\*|[-+~!*/%<>&^|?:]', Operator),
  1262. ],
  1263. 'data': [
  1264. (r'\s+', Text),
  1265. (r'0x[a-fA-F0-9]+', Number.Hex),
  1266. (r'0[0-7]+', Number.Oct),
  1267. (r'\d+\.\d+', Number.Float),
  1268. (r'\d+', Number.Integer),
  1269. (r'\$([\w\.\-\:]+)', Name.Variable),
  1270. (r'([\w\.\-\:]+)', Text),
  1271. ],
  1272. 'params': [
  1273. (r';', Keyword, '#pop'),
  1274. (r'\n', Text, '#pop'),
  1275. (r'(else|elseif|then)\b', Keyword),
  1276. include('basic'),
  1277. include('data'),
  1278. ],
  1279. 'params-in-brace': [
  1280. (r'}', Keyword, ('#pop', '#pop')),
  1281. include('params')
  1282. ],
  1283. 'params-in-paren': [
  1284. (r'\)', Keyword, ('#pop', '#pop')),
  1285. include('params')
  1286. ],
  1287. 'params-in-bracket': [
  1288. (r'\]', Keyword, ('#pop', '#pop')),
  1289. include('params')
  1290. ],
  1291. 'string': [
  1292. (r'\[', String.Double, 'string-square'),
  1293. (r'(?s)(\\\\|\\[0-7]+|\\.|[^"\\])', String.Double),
  1294. (r'"', String.Double, '#pop')
  1295. ],
  1296. 'string-square': [
  1297. (r'\[', String.Double, 'string-square'),
  1298. (r'(?s)(\\\\|\\[0-7]+|\\.|\\\n|[^\]\\])', String.Double),
  1299. (r'\]', String.Double, '#pop')
  1300. ],
  1301. 'brace': [
  1302. (r'}', Keyword, '#pop'),
  1303. include('command-in-brace'),
  1304. include('basic'),
  1305. include('data'),
  1306. ],
  1307. 'paren': [
  1308. (r'\)', Keyword, '#pop'),
  1309. include('command-in-paren'),
  1310. include('basic'),
  1311. include('data'),
  1312. ],
  1313. 'bracket': [
  1314. (r'\]', Keyword, '#pop'),
  1315. include('command-in-bracket'),
  1316. include('basic'),
  1317. include('data'),
  1318. ],
  1319. 'comment': [
  1320. (r'.*[^\\]\n', Comment, '#pop'),
  1321. (r'.*\\\n', Comment),
  1322. ],
  1323. }
  1324. def analyse_text(text):
  1325. return shebang_matches(text, r'(tcl)')
  1326. class FactorLexer(RegexLexer):
  1327. """
  1328. Lexer for the `Factor <http://factorcode.org>`_ language.
  1329. *New in Pygments 1.4.*
  1330. """
  1331. name = 'Factor'
  1332. aliases = ['factor']
  1333. filenames = ['*.factor']
  1334. mimetypes = ['text/x-factor']
  1335. flags = re.MULTILINE | re.UNICODE
  1336. builtin_kernel = (
  1337. r'(?:or|2bi|2tri|while|wrapper|nip|4dip|wrapper\\?|bi\\*|'
  1338. r'callstack>array|both\\?|hashcode|die|dupd|callstack|'
  1339. r'callstack\\?|3dup|tri@|pick|curry|build|\\?execute|3bi|'
  1340. r'prepose|>boolean|\\?if|clone|eq\\?|tri\\*|\\?|=|swapd|'
  1341. r'2over|2keep|3keep|clear|2dup|when|not|tuple\\?|dup|2bi\\*|'
  1342. r'2tri\\*|call|tri-curry|object|bi@|do|unless\\*|if\\*|loop|'
  1343. r'bi-curry\\*|drop|when\\*|assert=|retainstack|assert\\?|-rot|'
  1344. r'execute|2bi@|2tri@|boa|with|either\\?|3drop|bi|curry\\?|'
  1345. r'datastack|until|3dip|over|3curry|tri-curry\\*|tri-curry@|swap|'
  1346. r'and|2nip|throw|bi-curry|\\(clone\\)|hashcode\\*|compose|2dip|if|3tri|'
  1347. r'unless|compose\\?|tuple|keep|2curry|equal\\?|assert|tri|2drop|'
  1348. r'most|<wrapper>|boolean\\?|identity-hashcode|identity-tuple\\?|'
  1349. r'null|new|dip|bi-curry@|rot|xor|identity-tuple|boolean)\s'
  1350. )
  1351. builtin_assocs = (
  1352. r'(?:\\?at|assoc\\?|assoc-clone-like|assoc=|delete-at\\*|'
  1353. r'assoc-partition|extract-keys|new-assoc|value\\?|assoc-size|'
  1354. r'map>assoc|push-at|assoc-like|key\\?|assoc-intersect|'
  1355. r'assoc-refine|update|assoc-union|assoc-combine|at\\*|'
  1356. r'assoc-empty\\?|at\\+|set-at|assoc-all\\?|assoc-subset\\?|'
  1357. r'assoc-hashcode|change-at|assoc-each|assoc-diff|zip|values|'
  1358. r'value-at|rename-at|inc-at|enum\\?|at|cache|assoc>map|<enum>|'
  1359. r'assoc|assoc-map|enum|value-at\\*|assoc-map-as|>alist|'
  1360. r'assoc-filter-as|clear-assoc|assoc-stack|maybe-set-at|'
  1361. r'substitute|assoc-filter|2cache|delete-at|assoc-find|keys|'
  1362. r'assoc-any\\?|unzip)\s'
  1363. )
  1364. builtin_combinators = (
  1365. r'(?:case|execute-effect|no-cond|no-case\\?|3cleave>quot|2cleave|'
  1366. r'cond>quot|wrong-values\\?|no-cond\\?|cleave>quot|no-case|'
  1367. r'case>quot|3cleave|wrong-values|to-fixed-point|alist>quot|'
  1368. r'case-find|cond|cleave|call-effect|2cleave>quot|recursive-hashcode|'
  1369. r'linear-case-quot|spread|spread>quot)\s'
  1370. )
  1371. builtin_math = (
  1372. r'(?:number=|if-zero|next-power-of-2|each-integer|\\?1\\+|'
  1373. r'fp-special\\?|imaginary-part|unless-zero|float>bits|number\\?|'
  1374. r'fp-infinity\\?|bignum\\?|fp-snan\\?|denominator|fp-bitwise=|\\*|'
  1375. r'\\+|power-of-2\\?|-|u>=|/|>=|bitand|log2-expects-positive|<|'
  1376. r'log2|>|integer\\?|number|bits>double|2/|zero\\?|(find-integer)|'
  1377. r'bits>float|float\\?|shift|ratio\\?|even\\?|ratio|fp-sign|bitnot|'
  1378. r'>fixnum|complex\\?|/i|/f|byte-array>bignum|when-zero|sgn|>bignum|'
  1379. r'next-float|u<|u>|mod|recip|rational|find-last-integer|>float|'
  1380. r'(all-integers\\?)|2^|times|integer|fixnum\\?|neg|fixnum|sq|'
  1381. r'bignum|(each-integer)|bit\\?|fp-qnan\\?|find-integer|complex|'
  1382. r'<fp-nan>|real|double>bits|bitor|rem|fp-nan-payload|all-integers\\?|'
  1383. r'real-part|log2-expects-positive\\?|prev-float|align|unordered\\?|'
  1384. r'float|fp-nan\\?|abs|bitxor|u<=|odd\\?|<=|/mod|rational\\?|>integer|'
  1385. r'real\\?|numerator)\s'
  1386. )
  1387. builtin_sequences = (
  1388. r'(?:member-eq\\?|append|assert-sequence=|find-last-from|trim-head-slice|'
  1389. r'clone-like|3sequence|assert-sequence\\?|map-as|last-index-from|'
  1390. r'reversed|index-from|cut\\*|pad-tail|remove-eq!|concat-as|'
  1391. r'but-last|snip|trim-tail|nths|nth|2selector|sequence|slice\\?|'
  1392. r'<slice>|partition|remove-nth|tail-slice|empty\\?|tail\\*|'
  1393. r'if-empty|find-from|virtual-sequence\\?|member\\?|set-length|'
  1394. r'drop-prefix|unclip|unclip-last-slice|iota|map-sum|'
  1395. r'bounds-error\\?|sequence-hashcode-step|selector-for|'
  1396. r'accumulate-as|map|start|midpoint@|\\(accumulate\\)|rest-slice|'
  1397. r'prepend|fourth|sift|accumulate!|new-sequence|follow|map!|'
  1398. r'like|first4|1sequence|reverse|slice|unless-empty|padding|'
  1399. r'virtual@|repetition\\?|set-last|index|4sequence|max-length|'
  1400. r'set-second|immutable-sequence|first2|first3|replicate-as|'
  1401. r'reduce-index|unclip-slice|supremum|suffix!|insert-nth|'
  1402. r'trim-tail-slice|tail|3append|short|count|suffix|concat|'
  1403. r'flip|filter|sum|immutable\\?|reverse!|2sequence|map-integers|'
  1404. r'delete-all|start\\*|indices|snip-slice|check-slice|sequence\\?|'
  1405. r'head|map-find|filter!|append-as|reduce|sequence=|halves|'
  1406. r'collapse-slice|interleave|2map|filter-as|binary-reduce|'
  1407. r'slice-error\\?|product|bounds-check\\?|bounds-check|harvest|'
  1408. r'immutable|virtual-exemplar|find|produce|remove|pad-head|last|'
  1409. r'replicate|set-fourth|remove-eq|shorten|reversed\\?|'
  1410. r'map-find-last|3map-as|2unclip-slice|shorter\\?|3map|find-last|'
  1411. r'head-slice|pop\\*|2map-as|tail-slice\\*|but-last-slice|'
  1412. r'2map-reduce|iota\\?|collector-for|accumulate|each|selector|'
  1413. r'append!|new-resizable|cut-slice|each-index|head-slice\\*|'
  1414. r'2reverse-each|sequence-hashcode|pop|set-nth|\\?nth|'
  1415. r'<flat-slice>|second|join|when-empty|collector|'
  1416. r'immutable-sequence\\?|<reversed>|all\\?|3append-as|'
  1417. r'virtual-sequence|subseq\\?|remove-nth!|push-either|new-like|'
  1418. r'length|last-index|push-if|2all\\?|lengthen|assert-sequence|'
  1419. r'copy|map-reduce|move|third|first|3each|tail\\?|set-first|'
  1420. r'prefix|bounds-error|any\\?|<repetition>|trim-slice|exchange|'
  1421. r'surround|2reduce|cut|change-nth|min-length|set-third|produce-as|'
  1422. r'push-all|head\\?|delete-slice|rest|sum-lengths|2each|head\\*|'
  1423. r'infimum|remove!|glue|slice-error|subseq|trim|replace-slice|'
  1424. r'push|repetition|map-index|trim-head|unclip-last|mismatch)\s'
  1425. )
  1426. builtin_namespaces = (
  1427. r'(?:global|\\+@|change|set-namestack|change-global|init-namespaces|'
  1428. r'on|off|set-global|namespace|set|with-scope|bind|with-variable|'
  1429. r'inc|dec|counter|initialize|namestack|get|get-global|make-assoc)\s'
  1430. )
  1431. builtin_arrays = (
  1432. r'(?:<array>|2array|3array|pair|>array|1array|4array|pair\\?|'
  1433. r'array|resize-array|array\\?)\s'
  1434. )
  1435. builtin_io = (
  1436. r'(?:\\+character\\+|bad-seek-type\\?|readln|each-morsel|stream-seek|'
  1437. r'read|print|with-output-stream|contents|write1|stream-write1|'
  1438. r'stream-copy|stream-element-type|with-input-stream|'
  1439. r'stream-print|stream-read|stream-contents|stream-tell|'
  1440. r'tell-output|bl|seek-output|bad-seek-type|nl|stream-nl|write|'
  1441. r'flush|stream-lines|\\+byte\\+|stream-flush|read1|'
  1442. r'seek-absolute\\?|stream-read1|lines|stream-readln|'
  1443. r'stream-read-until|each-line|seek-end|with-output-stream\\*|'
  1444. r'seek-absolute|with-streams|seek-input|seek-relative\\?|'
  1445. r'input-stream|stream-write|read-partial|seek-end\\?|'
  1446. r'seek-relative|error-stream|read-until|with-input-stream\\*|'
  1447. r'with-streams\\*|tell-input|each-block|output-stream|'
  1448. r'stream-read-partial|each-stream-block|each-stream-line)\s'
  1449. )
  1450. builtin_strings = (
  1451. r'(?:resize-string|>string|<string>|1string|string|string\\?)\s'
  1452. )
  1453. builtin_vectors = (
  1454. r'(?:vector\\?|<vector>|\\?push|vector|>vector|1vector)\s'
  1455. )
  1456. builtin_continuations = (
  1457. r'(?:with-return|restarts|return-continuation|with-datastack|'
  1458. r'recover|rethrow-restarts|<restart>|ifcc|set-catchstack|'
  1459. r'>continuation<|cleanup|ignore-errors|restart\\?|'
  1460. r'compute-restarts|attempt-all-error|error-thread|continue|'
  1461. r'<continuation>|attempt-all-error\\?|condition\\?|'
  1462. r'<condition>|throw-restarts|error|catchstack|continue-with|'
  1463. r'thread-error-hook|continuation|rethrow|callcc1|'
  1464. r'error-continuation|callcc0|attempt-all|condition|'
  1465. r'continuation\\?|restart|return)\s'
  1466. )
  1467. tokens = {
  1468. 'root': [
  1469. # TODO: (( inputs -- outputs ))
  1470. # TODO: << ... >>
  1471. # defining words
  1472. (r'(\s*)(:|::|MACRO:|MEMO:)(\s+)(\S+)',
  1473. bygroups(Text, Keyword, Text, Name.Function)),
  1474. (r'(\s*)(M:)(\s+)(\S+)(\s+)(\S+)',
  1475. bygroups(Text, Keyword, Text, Name.Class, Text, Name.Function)),
  1476. (r'(\s*)(GENERIC:)(\s+)(\S+)',
  1477. bygroups(Text, Keyword, Text, Name.Function)),
  1478. (r'(\s*)(HOOK:|GENERIC#)(\s+)(\S+)(\s+)(\S+)',
  1479. bygroups(Text, Keyword, Text, Name.Function, Text, Name.Function)),
  1480. (r'(\()(\s+)', bygroups(Name.Function, Text), 'stackeffect'),
  1481. (r'\;\s', Keyword),
  1482. # imports and namespaces
  1483. (r'(USING:)((?:\s|\\\s)+)',
  1484. bygroups(Keyword.Namespace, Text), 'import'),
  1485. (r'(USE:)(\s+)(\S+)',
  1486. bygroups(Keyword.Namespace, Text, Name.Namespace)),
  1487. (r'(UNUSE:)(\s+)(\S+)',
  1488. bygroups(Keyword.Namespace, Text, Name.Namespace)),
  1489. (r'(QUALIFIED:)(\s+)(\S+)',
  1490. bygroups(Keyword.Namespace, Text, Name.Namespace)),
  1491. (r'(QUALIFIED-WITH:)(\s+)(\S+)',
  1492. bygroups(Keyword.Namespace, Text, Name.Namespace)),
  1493. (r'(FROM:|EXCLUDE:)(\s+)(\S+)(\s+)(=>)',
  1494. bygroups(Keyword.Namespace, Text, Name.Namespace, Text, Text)),
  1495. (r'(IN:)(\s+)(\S+)',
  1496. bygroups(Keyword.Namespace, Text, Name.Namespace)),
  1497. (r'(?:ALIAS|DEFER|FORGET|POSTPONE):', Keyword.Namespace),
  1498. # tuples and classes
  1499. (r'(TUPLE:)(\s+)(\S+)(\s+<\s+)(\S+)',
  1500. bygroups(Keyword, Text, Name.Class, Text, Name.Class), 'slots'),
  1501. (r'(TUPLE:)(\s+)(\S+)',
  1502. bygroups(Keyword, Text, Name.Class), 'slots'),
  1503. (r'(UNION:)(\s+)(\S+)', bygroups(Keyword, Text, Name.Class)),
  1504. (r'(INTERSECTION:)(\s+)(\S+)', bygroups(Keyword, Text, Name.Class)),
  1505. (r'(PREDICATE:)(\s+)(\S+)(\s+<\s+)(\S+)',
  1506. bygroups(Keyword, Text, Name.Class, Text, Name.Class)),
  1507. (r'(C:)(\s+)(\S+)(\s+)(\S+)',
  1508. bygroups(Keyword, Text, Name.Function, Text, Name.Class)),
  1509. (r'INSTANCE:', Keyword),
  1510. (r'SLOT:', Keyword),
  1511. (r'MIXIN:', Keyword),
  1512. (r'(?:SINGLETON|SINGLETONS):', Keyword),
  1513. # other syntax
  1514. (r'CONSTANT:', Keyword),
  1515. (r'(?:SYMBOL|SYMBOLS):', Keyword),
  1516. (r'ERROR:', Keyword),
  1517. (r'SYNTAX:', Keyword),
  1518. (r'(HELP:)(\s+)(\S+)', bygroups(Keyword, Text, Name.Function)),
  1519. (r'(MAIN:)(\s+)(\S+)',
  1520. bygroups(Keyword.Namespace, Text, Name.Function)),
  1521. (r'(?:ALIEN|TYPEDEF|FUNCTION|STRUCT):', Keyword),
  1522. # vocab.private
  1523. # TODO: words inside vocab.private should have red names?
  1524. (r'(?:<PRIVATE|PRIVATE>)', Keyword.Namespace),
  1525. # strings
  1526. (r'"""\s+(?:.|\n)*?\s+"""', String),
  1527. (r'"(?:\\\\|\\"|[^"])*"', String),
  1528. (r'CHAR:\s+(\\[\\abfnrstv]*|\S)\s', String.Char),
  1529. # comments
  1530. (r'\!\s+.*$', Comment),
  1531. (r'#\!\s+.*$', Comment),
  1532. # boolean constants
  1533. (r'(t|f)\s', Name.Constant),
  1534. # numbers
  1535. (r'-?\d+\.\d+\s', Number.Float),
  1536. (r'-?\d+\s', Number.Integer),
  1537. (r'HEX:\s+[a-fA-F\d]+\s', Number.Hex),
  1538. (r'BIN:\s+[01]+\s', Number.Integer),
  1539. (r'OCT:\s+[0-7]+\s', Number.Oct),
  1540. # operators
  1541. (r'[-+/*=<>^]\s', Operator),
  1542. # keywords
  1543. (r'(?:deprecated|final|foldable|flushable|inline|recursive)\s',
  1544. Keyword),
  1545. # builtins
  1546. (builtin_kernel, Name.Builtin),
  1547. (builtin_assocs, Name.Builtin),
  1548. (builtin_combinators, Name.Builtin),
  1549. (builtin_math, Name.Builtin),
  1550. (builtin_sequences, Name.Builtin),
  1551. (builtin_namespaces, Name.Builtin),
  1552. (builtin_arrays, Name.Builtin),
  1553. (builtin_io, Name.Builtin),
  1554. (builtin_strings, Name.Builtin),
  1555. (builtin_vectors, Name.Builtin),
  1556. (builtin_continuations, Name.Builtin),
  1557. # whitespaces - usually not relevant
  1558. (r'\s+', Text),
  1559. # everything else is text
  1560. (r'\S+', Text),
  1561. ],
  1562. 'stackeffect': [
  1563. (r'\s*\(', Name.Function, 'stackeffect'),
  1564. (r'\)', Name.Function, '#pop'),
  1565. (r'\-\-', Name.Function),
  1566. (r'\s+', Text),
  1567. (r'\S+', Name.Variable),
  1568. ],
  1569. 'slots': [
  1570. (r'\s+', Text),
  1571. (r';\s', Keyword, '#pop'),
  1572. (r'\S+', Name.Variable),
  1573. ],
  1574. 'import': [
  1575. (r';', Keyword, '#pop'),
  1576. (r'\S+', Name.Namespace),
  1577. (r'\s+', Text),
  1578. ],
  1579. }
  1580. class FancyLexer(RegexLexer):
  1581. """
  1582. Pygments Lexer For `Fancy <http://www.fancy-lang.org/>`_.
  1583. Fancy is a self-hosted, pure object-oriented, dynamic,
  1584. class-based, concurrent general-purpose programming language
  1585. running on Rubinius, the Ruby VM.
  1586. *New in Pygments 1.5.*
  1587. """
  1588. name = 'Fancy'
  1589. filenames = ['*.fy', '*.fancypack']
  1590. aliases = ['fancy', 'fy']
  1591. mimetypes = ['text/x-fancysrc']
  1592. tokens = {
  1593. # copied from PerlLexer:
  1594. 'balanced-regex': [
  1595. (r'/(\\\\|\\/|[^/])*/[egimosx]*', String.Regex, '#pop'),
  1596. (r'!(\\\\|\\!|[^!])*![egimosx]*', String.Regex, '#pop'),
  1597. (r'\\(\\\\|[^\\])*\\[egimosx]*', String.Regex, '#pop'),
  1598. (r'{(\\\\|\\}|[^}])*}[egimosx]*', String.Regex, '#pop'),
  1599. (r'<(\\\\|\\>|[^>])*>[egimosx]*', String.Regex, '#pop'),
  1600. (r'\[(\\\\|\\\]|[^\]])*\][egimosx]*', String.Regex, '#pop'),
  1601. (r'\((\\\\|\\\)|[^\)])*\)[egimosx]*', String.Regex, '#pop'),
  1602. (r'@(\\\\|\\\@|[^\@])*@[egimosx]*', String.Regex, '#pop'),
  1603. (r'%(\\\\|\\\%|[^\%])*%[egimosx]*', String.Regex, '#pop'),
  1604. (r'\$(\\\\|\\\$|[^\$])*\$[egimosx]*', String.Regex, '#pop'),
  1605. ],
  1606. 'root': [
  1607. (r'\s+', Text),
  1608. # balanced delimiters (copied from PerlLexer):
  1609. (r's{(\\\\|\\}|[^}])*}\s*', String.Regex, 'balanced-regex'),
  1610. (r's<(\\\\|\\>|[^>])*>\s*', String.Regex, 'balanced-regex'),
  1611. (r's\[(\\\\|\\\]|[^\]])*\]\s*', String.Regex, 'balanced-regex'),
  1612. (r's\((\\\\|\\\)|[^\)])*\)\s*', String.Regex, 'balanced-regex'),
  1613. (r'm?/(\\\\|\\/|[^/\n])*/[gcimosx]*', String.Regex),
  1614. (r'm(?=[/!\\{<\[\(@%\$])', String.Regex, 'balanced-regex'),
  1615. # Comments
  1616. (r'#(.*?)\n', Comment.Single),
  1617. # Symbols
  1618. (r'\'([^\'\s\[\]\(\)\{\}]+|\[\])', String.Symbol),
  1619. # Multi-line DoubleQuotedString
  1620. (r'"""(\\\\|\\"|[^"])*"""', String),
  1621. # DoubleQuotedString
  1622. (r'"(\\\\|\\"|[^"])*"', String),
  1623. # keywords
  1624. (r'(def|class|try|catch|finally|retry|return|return_local|match|'
  1625. r'case|->|=>)\b', Keyword),
  1626. # constants
  1627. (r'(self|super|nil|false|true)\b', Name.Constant),
  1628. (r'[(){};,/?\|:\\]', Punctuation),
  1629. # names
  1630. (r'(Object|Array|Hash|Directory|File|Class|String|Number|'
  1631. r'Enumerable|FancyEnumerable|Block|TrueClass|NilClass|'
  1632. r'FalseClass|Tuple|Symbol|Stack|Set|FancySpec|Method|Package|'
  1633. r'Range)\b', Name.Builtin),
  1634. # functions
  1635. (r'[a-zA-Z]([a-zA-Z0-9_]|[-+?!=*/^><%])*:', Name.Function),
  1636. # operators, must be below functions
  1637. (r'[-+*/~,<>=&!?%^\[\]\.$]+', Operator),
  1638. ('[A-Z][a-zA-Z0-9_]*', Name.Constant),
  1639. ('@[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable.Instance),
  1640. ('@@[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable.Class),
  1641. ('@@?', Operator),
  1642. ('[a-zA-Z_][a-zA-Z0-9_]*', Name),
  1643. # numbers - / checks are necessary to avoid mismarking regexes,
  1644. # see comment in RubyLexer
  1645. (r'(0[oO]?[0-7]+(?:_[0-7]+)*)(\s*)([/?])?',
  1646. bygroups(Number.Oct, Text, Operator)),
  1647. (r'(0[xX][0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*)(\s*)([/?])?',
  1648. bygroups(Number.Hex, Text, Operator)),
  1649. (r'(0[bB][01]+(?:_[01]+)*)(\s*)([/?])?',
  1650. bygroups(Number.Bin, Text, Operator)),
  1651. (r'([\d]+(?:_\d+)*)(\s*)([/?])?',
  1652. bygroups(Number.Integer, Text, Operator)),
  1653. (r'\d+([eE][+-]?[0-9]+)|\d+\.\d+([eE][+-]?[0-9]+)?', Number.Float),
  1654. (r'\d+', Number.Integer)
  1655. ]
  1656. }