24 |
25 |
25 .. versionadded:: 2.2 |
26 .. versionadded:: 2.2 |
26 """ |
27 """ |
27 # Syntax based on |
28 # Syntax based on |
28 # - http://fmwww.bc.edu/RePEc/bocode/s/synlightlist.ado |
29 # - http://fmwww.bc.edu/RePEc/bocode/s/synlightlist.ado |
29 # - http://github.com/isagalaev/highlight.js/blob/master/src/languages/stata.js |
30 # - https://github.com/isagalaev/highlight.js/blob/master/src/languages/stata.js |
30 # - http://github.com/jpitblado/vim-stata/blob/master/syntax/stata.vim |
31 # - https://github.com/jpitblado/vim-stata/blob/master/syntax/stata.vim |
31 |
32 |
32 name = 'Stata' |
33 name = 'Stata' |
33 aliases = ['stata', 'do'] |
34 aliases = ['stata', 'do'] |
34 filenames = ['*.do', '*.ado'] |
35 filenames = ['*.do', '*.ado'] |
35 mimetypes = ['text/x-stata', 'text/stata', 'application/x-stata'] |
36 mimetypes = ['text/x-stata', 'text/stata', 'application/x-stata'] |
|
37 flags = re.MULTILINE | re.DOTALL |
36 |
38 |
37 tokens = { |
39 tokens = { |
38 'root': [ |
40 'root': [ |
39 include('comments'), |
41 include('comments'), |
40 include('vars-strings'), |
42 include('strings'), |
|
43 include('macros'), |
41 include('numbers'), |
44 include('numbers'), |
42 include('keywords'), |
45 include('keywords'), |
|
46 include('operators'), |
|
47 include('format'), |
43 (r'.', Text), |
48 (r'.', Text), |
44 ], |
49 ], |
45 # Global and local macros; regular and special strings |
50 # Comments are a complicated beast in Stata because they can be |
46 'vars-strings': [ |
51 # nested and there are a few corner cases with that. See: |
47 (r'\$[\w{]', Name.Variable.Global, 'var_validglobal'), |
52 # - github.com/kylebarron/language-stata/issues/90 |
48 (r'`\w{0,31}\'', Name.Variable), |
53 # - statalist.org/forums/forum/general-stata-discussion/general/1448244 |
49 (r'"', String, 'string_dquote'), |
54 'comments': [ |
50 (r'`"', String, 'string_mquote'), |
55 (r'(^//|(?<=\s)//)(?!/)', Comment.Single, 'comments-double-slash'), |
|
56 (r'^\s*\*', Comment.Single, 'comments-star'), |
|
57 (r'/\*', Comment.Multiline, 'comments-block'), |
|
58 (r'(^///|(?<=\s)///)', Comment.Special, 'comments-triple-slash') |
51 ], |
59 ], |
52 # For either string type, highlight macros as macros |
60 'comments-block': [ |
53 'string_dquote': [ |
61 (r'/\*', Comment.Multiline, '#push'), |
54 (r'"', String, '#pop'), |
62 # this ends and restarts a comment block. but need to catch this so |
55 (r'\\\\|\\"|\\\n', String.Escape), |
63 # that it doesn\'t start _another_ level of comment blocks |
56 (r'\$', Name.Variable.Global, 'var_validglobal'), |
64 (r'\*/\*', Comment.Multiline), |
57 (r'`', Name.Variable, 'var_validlocal'), |
65 (r'(\*/\s+\*(?!/)[^\n]*)|(\*/)', Comment.Multiline, '#pop'), |
58 (r'[^$`"\\]+', String), |
66 # Match anything else as a character inside the comment |
59 (r'[$"\\]', String), |
67 (r'.', Comment.Multiline), |
60 ], |
68 ], |
61 'string_mquote': [ |
69 'comments-star': [ |
|
70 (r'///.*?\n', Comment.Single, |
|
71 ('#pop', 'comments-triple-slash')), |
|
72 (r'(^//|(?<=\s)//)(?!/)', Comment.Single, |
|
73 ('#pop', 'comments-double-slash')), |
|
74 (r'/\*', Comment.Multiline, 'comments-block'), |
|
75 (r'.(?=\n)', Comment.Single, '#pop'), |
|
76 (r'.', Comment.Single), |
|
77 ], |
|
78 'comments-triple-slash': [ |
|
79 (r'\n', Comment.Special, '#pop'), |
|
80 # A // breaks out of a comment for the rest of the line |
|
81 (r'//.*?(?=\n)', Comment.Single, '#pop'), |
|
82 (r'.', Comment.Special), |
|
83 ], |
|
84 'comments-double-slash': [ |
|
85 (r'\n', Text, '#pop'), |
|
86 (r'.', Comment.Single), |
|
87 ], |
|
88 # `"compound string"' and regular "string"; note the former are |
|
89 # nested. |
|
90 'strings': [ |
|
91 (r'`"', String, 'string-compound'), |
|
92 (r'(?<!`)"', String, 'string-regular'), |
|
93 ], |
|
94 'string-compound': [ |
|
95 (r'`"', String, '#push'), |
62 (r'"\'', String, '#pop'), |
96 (r'"\'', String, '#pop'), |
63 (r'\\\\|\\"|\\\n', String.Escape), |
97 (r'\\\\|\\"|\\\$|\\`|\\\n', String.Escape), |
64 (r'\$', Name.Variable.Global, 'var_validglobal'), |
98 include('macros'), |
65 (r'`', Name.Variable, 'var_validlocal'), |
99 (r'.', String) |
66 (r'[^$`"\\]+', String), |
|
67 (r'[$"\\]', String), |
|
68 ], |
100 ], |
69 'var_validglobal': [ |
101 'string-regular': [ |
70 (r'\{\w{0,32}\}', Name.Variable.Global, '#pop'), |
102 (r'(")(?!\')|(?=\n)', String, '#pop'), |
|
103 (r'\\\\|\\"|\\\$|\\`|\\\n', String.Escape), |
|
104 include('macros'), |
|
105 (r'.', String) |
|
106 ], |
|
107 # A local is usually |
|
108 # `\w{0,31}' |
|
109 # `:extended macro' |
|
110 # `=expression' |
|
111 # `[rsen](results)' |
|
112 # `(++--)scalar(++--)' |
|
113 # |
|
114 # However, there are all sorts of weird rules wrt edge |
|
115 # cases. Instead of writing 27 exceptions, anything inside |
|
116 # `' is a local. |
|
117 # |
|
118 # A global is more restricted, so we do follow rules. Note only |
|
119 # locals explicitly enclosed ${} can be nested. |
|
120 'macros': [ |
|
121 (r'\$(\{|(?=[\$`]))', Name.Variable.Global, 'macro-global-nested'), |
|
122 (r'\$', Name.Variable.Global, 'macro-global-name'), |
|
123 (r'`', Name.Variable, 'macro-local'), |
|
124 ], |
|
125 'macro-local': [ |
|
126 (r'`', Name.Variable, '#push'), |
|
127 (r"'", Name.Variable, '#pop'), |
|
128 (r'\$(\{|(?=[\$`]))', Name.Variable.Global, 'macro-global-nested'), |
|
129 (r'\$', Name.Variable.Global, 'macro-global-name'), |
|
130 (r'.', Name.Variable), # fallback |
|
131 ], |
|
132 'macro-global-nested': [ |
|
133 (r'\$(\{|(?=[\$`]))', Name.Variable.Global, '#push'), |
|
134 (r'\}', Name.Variable.Global, '#pop'), |
|
135 (r'\$', Name.Variable.Global, 'macro-global-name'), |
|
136 (r'`', Name.Variable, 'macro-local'), |
|
137 (r'\w', Name.Variable.Global), # fallback |
|
138 (r'(?!\w)', Name.Variable.Global, '#pop'), |
|
139 ], |
|
140 'macro-global-name': [ |
|
141 (r'\$(\{|(?=[\$`]))', Name.Variable.Global, 'macro-global-nested', '#pop'), |
|
142 (r'\$', Name.Variable.Global, 'macro-global-name', '#pop'), |
|
143 (r'`', Name.Variable, 'macro-local', '#pop'), |
71 (r'\w{1,32}', Name.Variable.Global, '#pop'), |
144 (r'\w{1,32}', Name.Variable.Global, '#pop'), |
72 ], |
|
73 'var_validlocal': [ |
|
74 (r'\w{0,31}\'', Name.Variable, '#pop'), |
|
75 ], |
|
76 # * only OK at line start, // OK anywhere |
|
77 'comments': [ |
|
78 (r'^\s*\*.*$', Comment), |
|
79 (r'//.*', Comment.Single), |
|
80 (r'/\*.*?\*/', Comment.Multiline), |
|
81 (r'/[*](.|\n)*?[*]/', Comment.Multiline), |
|
82 ], |
145 ], |
83 # Built in functions and statements |
146 # Built in functions and statements |
84 'keywords': [ |
147 'keywords': [ |
85 (words(builtins_functions, prefix = r'\b', suffix = r'\('), |
148 (words(builtins_functions, prefix = r'\b', suffix = r'(?=\()'), |
86 Name.Function), |
149 Name.Function), |
87 (words(builtins_base, prefix = r'(^\s*|\s)', suffix = r'\b'), |
150 (words(builtins_base, prefix = r'(^\s*|\s)', suffix = r'\b'), |
88 Keyword), |
151 Keyword), |
89 ], |
152 ], |
90 # http://www.stata.com/help.cgi?operators |
153 # http://www.stata.com/help.cgi?operators |