|
1 # -*- coding: utf-8 -*- |
|
2 """ |
|
3 pygments.lexers.tcl |
|
4 ~~~~~~~~~~~~~~~~~~~ |
|
5 |
|
6 Lexers for Tcl and related languages. |
|
7 |
|
8 :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS. |
|
9 :license: BSD, see LICENSE for details. |
|
10 """ |
|
11 |
|
12 from pygments.lexer import RegexLexer, include, words |
|
13 from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ |
|
14 Number |
|
15 from pygments.util import shebang_matches |
|
16 |
|
17 __all__ = ['TclLexer'] |
|
18 |
|
19 |
|
20 class TclLexer(RegexLexer): |
|
21 """ |
|
22 For Tcl source code. |
|
23 |
|
24 .. versionadded:: 0.10 |
|
25 """ |
|
26 |
|
27 keyword_cmds_re = words(( |
|
28 'after', 'apply', 'array', 'break', 'catch', 'continue', 'elseif', 'else', 'error', |
|
29 'eval', 'expr', 'for', 'foreach', 'global', 'if', 'namespace', 'proc', 'rename', 'return', |
|
30 'set', 'switch', 'then', 'trace', 'unset', 'update', 'uplevel', 'upvar', 'variable', |
|
31 'vwait', 'while'), prefix=r'\b', suffix=r'\b') |
|
32 |
|
33 builtin_cmds_re = words(( |
|
34 'append', 'bgerror', 'binary', 'cd', 'chan', 'clock', 'close', 'concat', 'dde', 'dict', |
|
35 'encoding', 'eof', 'exec', 'exit', 'fblocked', 'fconfigure', 'fcopy', 'file', |
|
36 'fileevent', 'flush', 'format', 'gets', 'glob', 'history', 'http', 'incr', 'info', 'interp', |
|
37 'join', 'lappend', 'lassign', 'lindex', 'linsert', 'list', 'llength', 'load', 'loadTk', |
|
38 'lrange', 'lrepeat', 'lreplace', 'lreverse', 'lsearch', 'lset', 'lsort', 'mathfunc', |
|
39 'mathop', 'memory', 'msgcat', 'open', 'package', 'pid', 'pkg::create', 'pkg_mkIndex', |
|
40 'platform', 'platform::shell', 'puts', 'pwd', 're_syntax', 'read', 'refchan', |
|
41 'regexp', 'registry', 'regsub', 'scan', 'seek', 'socket', 'source', 'split', 'string', |
|
42 'subst', 'tell', 'time', 'tm', 'unknown', 'unload'), prefix=r'\b', suffix=r'\b') |
|
43 |
|
44 name = 'Tcl' |
|
45 aliases = ['tcl'] |
|
46 filenames = ['*.tcl', '*.rvt'] |
|
47 mimetypes = ['text/x-tcl', 'text/x-script.tcl', 'application/x-tcl'] |
|
48 |
|
49 def _gen_command_rules(keyword_cmds_re, builtin_cmds_re, context=""): |
|
50 return [ |
|
51 (keyword_cmds_re, Keyword, 'params' + context), |
|
52 (builtin_cmds_re, Name.Builtin, 'params' + context), |
|
53 (r'([\w.-]+)', Name.Variable, 'params' + context), |
|
54 (r'#', Comment, 'comment'), |
|
55 ] |
|
56 |
|
57 tokens = { |
|
58 'root': [ |
|
59 include('command'), |
|
60 include('basic'), |
|
61 include('data'), |
|
62 (r'\}', Keyword), # HACK: somehow we miscounted our braces |
|
63 ], |
|
64 'command': _gen_command_rules(keyword_cmds_re, builtin_cmds_re), |
|
65 'command-in-brace': _gen_command_rules(keyword_cmds_re, |
|
66 builtin_cmds_re, |
|
67 "-in-brace"), |
|
68 'command-in-bracket': _gen_command_rules(keyword_cmds_re, |
|
69 builtin_cmds_re, |
|
70 "-in-bracket"), |
|
71 'command-in-paren': _gen_command_rules(keyword_cmds_re, |
|
72 builtin_cmds_re, |
|
73 "-in-paren"), |
|
74 'basic': [ |
|
75 (r'\(', Keyword, 'paren'), |
|
76 (r'\[', Keyword, 'bracket'), |
|
77 (r'\{', Keyword, 'brace'), |
|
78 (r'"', String.Double, 'string'), |
|
79 (r'(eq|ne|in|ni)\b', Operator.Word), |
|
80 (r'!=|==|<<|>>|<=|>=|&&|\|\||\*\*|[-+~!*/%<>&^|?:]', Operator), |
|
81 ], |
|
82 'data': [ |
|
83 (r'\s+', Text), |
|
84 (r'0x[a-fA-F0-9]+', Number.Hex), |
|
85 (r'0[0-7]+', Number.Oct), |
|
86 (r'\d+\.\d+', Number.Float), |
|
87 (r'\d+', Number.Integer), |
|
88 (r'\$([\w.:-]+)', Name.Variable), |
|
89 (r'([\w.:-]+)', Text), |
|
90 ], |
|
91 'params': [ |
|
92 (r';', Keyword, '#pop'), |
|
93 (r'\n', Text, '#pop'), |
|
94 (r'(else|elseif|then)\b', Keyword), |
|
95 include('basic'), |
|
96 include('data'), |
|
97 ], |
|
98 'params-in-brace': [ |
|
99 (r'\}', Keyword, ('#pop', '#pop')), |
|
100 include('params') |
|
101 ], |
|
102 'params-in-paren': [ |
|
103 (r'\)', Keyword, ('#pop', '#pop')), |
|
104 include('params') |
|
105 ], |
|
106 'params-in-bracket': [ |
|
107 (r'\]', Keyword, ('#pop', '#pop')), |
|
108 include('params') |
|
109 ], |
|
110 'string': [ |
|
111 (r'\[', String.Double, 'string-square'), |
|
112 (r'(?s)(\\\\|\\[0-7]+|\\.|[^"\\])', String.Double), |
|
113 (r'"', String.Double, '#pop') |
|
114 ], |
|
115 'string-square': [ |
|
116 (r'\[', String.Double, 'string-square'), |
|
117 (r'(?s)(\\\\|\\[0-7]+|\\.|\\\n|[^\]\\])', String.Double), |
|
118 (r'\]', String.Double, '#pop') |
|
119 ], |
|
120 'brace': [ |
|
121 (r'\}', Keyword, '#pop'), |
|
122 include('command-in-brace'), |
|
123 include('basic'), |
|
124 include('data'), |
|
125 ], |
|
126 'paren': [ |
|
127 (r'\)', Keyword, '#pop'), |
|
128 include('command-in-paren'), |
|
129 include('basic'), |
|
130 include('data'), |
|
131 ], |
|
132 'bracket': [ |
|
133 (r'\]', Keyword, '#pop'), |
|
134 include('command-in-bracket'), |
|
135 include('basic'), |
|
136 include('data'), |
|
137 ], |
|
138 'comment': [ |
|
139 (r'.*[^\\]\n', Comment, '#pop'), |
|
140 (r'.*\\\n', Comment), |
|
141 ], |
|
142 } |
|
143 |
|
144 def analyse_text(text): |
|
145 return shebang_matches(text, r'(tcl)') |