ThirdParty/Pygments/pygments/lexers/csound.py

changeset 6651
e8f3b5568b21
parent 5713
6762afd9f963
equal deleted inserted replaced
6650:1dd52aa8897c 6651:e8f3b5568b21
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 """ 2 """
3 pygments.lexers.csound 3 pygments.lexers.csound
4 ~~~~~~~~~~~~~~~~~~~~~~ 4 ~~~~~~~~~~~~~~~~~~~~~~
5 5
6 Lexers for CSound languages. 6 Lexers for Csound languages.
7 7
8 :copyright: Copyright 2006-2017 by the Pygments team, see AUTHORS. 8 :copyright: Copyright 2006-2017 by the Pygments team, see AUTHORS.
9 :license: BSD, see LICENSE for details. 9 :license: BSD, see LICENSE for details.
10 """ 10 """
11 11
12 import re 12 import re
13 13
14 from pygments.lexer import RegexLexer, bygroups, default, include, using, words 14 from pygments.lexer import RegexLexer, bygroups, default, include, using, words
15 from pygments.token import Comment, Keyword, Name, Number, Operator, Punctuation, \ 15 from pygments.token import Comment, Error, Keyword, Name, Number, Operator, Punctuation, \
16 String, Text 16 String, Text, Whitespace
17 from pygments.lexers._csound_builtins import OPCODES 17 from pygments.lexers._csound_builtins import OPCODES, DEPRECATED_OPCODES
18 from pygments.lexers.html import HtmlLexer 18 from pygments.lexers.html import HtmlLexer
19 from pygments.lexers.python import PythonLexer 19 from pygments.lexers.python import PythonLexer
20 from pygments.lexers.scripting import LuaLexer 20 from pygments.lexers.scripting import LuaLexer
21 21
22 __all__ = ['CsoundScoreLexer', 'CsoundOrchestraLexer', 'CsoundDocumentLexer'] 22 __all__ = ['CsoundScoreLexer', 'CsoundOrchestraLexer', 'CsoundDocumentLexer']
23 23
24 newline = (r'((?:(?:;|//).*)*)(\n)', bygroups(Comment.Single, Text)) 24 newline = (r'((?:(?:;|//).*)*)(\n)', bygroups(Comment.Single, Text))
25 25
26 26
27 class CsoundLexer(RegexLexer): 27 class CsoundLexer(RegexLexer):
28 # Subclasses must define a 'single-line string' state.
29 tokens = { 28 tokens = {
30 'whitespace': [ 29 'whitespace': [
31 (r'[ \t]+', Text), 30 (r'[ \t]+', Text),
32 (r'\\\n', Text), 31 (r'/[*](?:.|\n)*?[*]/', Comment.Multiline),
33 (r'/[*](.|\n)*?[*]/', Comment.Multiline) 32 (r'(?:;|//).*$', Comment.Single),
34 ], 33 (r'(\\)(\n)', bygroups(Whitespace, Text))
35
36 'macro call': [
37 (r'(\$\w+\.?)(\()', bygroups(Comment.Preproc, Punctuation),
38 'function macro call'),
39 (r'\$\w+(\.|\b)', Comment.Preproc)
40 ],
41 'function macro call': [
42 (r"((?:\\['\)]|[^'\)])+)(')", bygroups(Comment.Preproc, Punctuation)),
43 (r"([^'\)]+)(\))", bygroups(Comment.Preproc, Punctuation), '#pop')
44 ],
45
46 'whitespace or macro call': [
47 include('whitespace'),
48 include('macro call')
49 ], 34 ],
50 35
51 'preprocessor directives': [ 36 'preprocessor directives': [
52 (r'#(e(nd(if)?|lse)|ifn?def|undef)\b|##', Comment.Preproc), 37 (r'#(?:e(?:nd(?:if)?|lse)\b|##)|@@?[ \t]*\d+', Comment.Preproc),
53 (r'#include\b', Comment.Preproc, 'include'), 38 (r'#include', Comment.Preproc, 'include directive'),
54 (r'#[ \t]*define\b', Comment.Preproc, 'macro name'), 39 (r'#[ \t]*define', Comment.Preproc, 'define directive'),
55 (r'@+[ \t]*\d*', Comment.Preproc) 40 (r'#(?:ifn?def|undef)\b', Comment.Preproc, 'macro directive')
56 ], 41 ],
57 42
58 'include': [ 43 'include directive': [
59 include('whitespace'), 44 include('whitespace'),
60 (r'"', String, 'single-line string') 45 (r'([^ \t]).*?\1', String, '#pop')
61 ], 46 ],
62 47
63 'macro name': [ 48 'define directive': [
64 include('whitespace'), 49 (r'\n', Text),
65 (r'(\w+)(\()', bygroups(Comment.Preproc, Text), 50 include('whitespace'),
66 'function macro argument list'), 51 (r'([A-Z_a-z]\w*)(\()', bygroups(Comment.Preproc, Punctuation),
67 (r'\w+', Comment.Preproc, 'object macro definition after name') 52 ('#pop', 'macro parameter name list')),
68 ], 53 (r'[A-Z_a-z]\w*', Comment.Preproc, ('#pop', 'before macro body'))
69 'object macro definition after name': [ 54 ],
70 include('whitespace'), 55 'macro parameter name list': [
71 (r'#', Punctuation, 'object macro replacement text') 56 include('whitespace'),
72 ], 57 (r'[A-Z_a-z]\w*', Comment.Preproc),
73 'object macro replacement text': [ 58 (r"['#]", Punctuation),
74 (r'(\\#|[^#])+', Comment.Preproc), 59 (r'\)', Punctuation, ('#pop', 'before macro body'))
75 (r'#', Punctuation, '#pop:3') 60 ],
76 ], 61 'before macro body': [
77 'function macro argument list': [ 62 (r'\n', Text),
78 (r"(\w+)(['#])", bygroups(Comment.Preproc, Punctuation)), 63 include('whitespace'),
79 (r'(\w+)(\))', bygroups(Comment.Preproc, Punctuation), 64 (r'#', Punctuation, ('#pop', 'macro body'))
80 'function macro definition after name') 65 ],
81 ], 66 'macro body': [
82 'function macro definition after name': [ 67 (r'(?:\\(?!#)|[^#\\]|\n)+', Comment.Preproc),
83 (r'[ \t]+', Text), 68 (r'\\#', Comment.Preproc),
84 (r'#', Punctuation, 'function macro replacement text') 69 (r'(?<!\\)#', Punctuation, '#pop')
85 ], 70 ],
86 'function macro replacement text': [ 71
87 (r'(\\#|[^#])+', Comment.Preproc), 72 'macro directive': [
88 (r'#', Punctuation, '#pop:4') 73 include('whitespace'),
74 (r'[A-Z_a-z]\w*', Comment.Preproc, '#pop')
75 ],
76
77 'macro uses': [
78 (r'(\$[A-Z_a-z]\w*\.?)(\()', bygroups(Comment.Preproc, Punctuation),
79 'macro parameter value list'),
80 (r'\$[A-Z_a-z]\w*(?:\.|\b)', Comment.Preproc)
81 ],
82 'macro parameter value list': [
83 (r'(?:[^\'#"{()]|\{(?!\{))+', Comment.Preproc),
84 (r"['#]", Punctuation),
85 (r'"', String, 'macro parameter value quoted string'),
86 (r'\{\{', String, 'macro parameter value braced string'),
87 (r'\(', Comment.Preproc, 'macro parameter value parenthetical'),
88 (r'\)', Punctuation, '#pop')
89 ],
90 'macro parameter value quoted string': [
91 (r"\\[#'()]", Comment.Preproc),
92 (r"[#'()]", Error),
93 include('quoted string')
94 ],
95 'macro parameter value braced string': [
96 (r"\\[#'()]", Comment.Preproc),
97 (r"[#'()]", Error),
98 include('braced string')
99 ],
100 'macro parameter value parenthetical': [
101 (r'(?:[^\\()]|\\\))+', Comment.Preproc),
102 (r'\(', Comment.Preproc, '#push'),
103 (r'\)', Comment.Preproc, '#pop')
104 ],
105
106 'whitespace and macro uses': [
107 include('whitespace'),
108 include('macro uses')
109 ],
110
111 'numbers': [
112 (r'\d+[Ee][+-]?\d+|(\d+\.\d*|\d*\.\d+)([Ee][+-]?\d+)?', Number.Float),
113 (r'(0[Xx])([0-9A-Fa-f]+)', bygroups(Keyword.Type, Number.Hex)),
114 (r'\d+', Number.Integer)
115 ],
116
117 'braced string': [
118 # Do nothing. This must be defined in subclasses.
89 ] 119 ]
90 } 120 }
91 121
92 122
93 class CsoundScoreLexer(CsoundLexer): 123 class CsoundScoreLexer(CsoundLexer):
94 """ 124 """
95 For `Csound <http://csound.github.io>`_ scores. 125 For `Csound <https://csound.github.io>`_ scores.
96 126
97 .. versionadded:: 2.1 127 .. versionadded:: 2.1
98 """ 128 """
99 129
100 name = 'Csound Score' 130 name = 'Csound Score'
101 aliases = ['csound-score', 'csound-sco'] 131 aliases = ['csound-score', 'csound-sco']
102 filenames = ['*.sco'] 132 filenames = ['*.sco']
103 133
104 tokens = { 134 tokens = {
105 'partial statement': [ 135 'root': [
136 (r'\n', Text),
137 include('whitespace and macro uses'),
106 include('preprocessor directives'), 138 include('preprocessor directives'),
107 (r'\d+e[+-]?\d+|(\d+\.\d*|\d*\.\d+)(e[+-]?\d+)?', Number.Float), 139
108 (r'0[xX][a-fA-F0-9]+', Number.Hex), 140 (r'[abCdefiqstvxy]', Keyword),
109 (r'\d+', Number.Integer), 141 # There is also a w statement that is generated internally and should not be
110 (r'"', String, 'single-line string'), 142 # used; see https://github.com/csound/csound/issues/750.
111 (r'[+\-*/%^!=<>|&#~.]', Operator), 143
112 (r'[]()[]', Punctuation), 144 (r'z', Keyword.Constant),
113 (r'\w+', Comment.Preproc) 145 # z is a constant equal to 800,000,000,000. 800 billion seconds is about
114 ], 146 # 25,367.8 years. See also
115 147 # https://csound.github.io/docs/manual/ScoreTop.html and
116 'statement': [ 148 # https://github.com/csound/csound/search?q=stof+path%3AEngine+filename%3Asread.c.
117 include('whitespace or macro call'), 149
118 newline + ('#pop',), 150 (r'([nNpP][pP])(\d+)', bygroups(Keyword, Number.Integer)),
119 include('partial statement') 151
120 ], 152 (r'[mn]', Keyword, 'mark statement'),
121 153
122 'root': [ 154 include('numbers'),
123 newline, 155 (r'[!+\-*/^%&|<>#~.]', Operator),
124 include('whitespace or macro call'), 156 (r'[()\[\]]', Punctuation),
125 (r'[{}]', Punctuation, 'statement'), 157 (r'"', String, 'quoted string'),
126 (r'[abefimq-tv-z]|[nN][pP]?', Keyword, 'statement') 158 (r'\{', Comment.Preproc, 'loop after left brace'),
127 ], 159 ],
128 160
129 'single-line string': [ 161 'mark statement': [
162 include('whitespace and macro uses'),
163 (r'[A-Z_a-z]\w*', Name.Label),
164 (r'\n', Text, '#pop')
165 ],
166
167 'quoted string': [
130 (r'"', String, '#pop'), 168 (r'"', String, '#pop'),
131 (r'[^\\"]+', String) 169 (r'[^"$]+', String),
170 include('macro uses'),
171 (r'[$]', String)
172 ],
173
174 'loop after left brace': [
175 include('whitespace and macro uses'),
176 (r'\d+', Number.Integer, ('#pop', 'loop after repeat count')),
177 ],
178 'loop after repeat count': [
179 include('whitespace and macro uses'),
180 (r'[A-Z_a-z]\w*', Comment.Preproc, ('#pop', 'loop'))
181 ],
182 'loop': [
183 (r'\}', Comment.Preproc, '#pop'),
184 include('root')
185 ],
186
187 # Braced strings are not allowed in Csound scores, but this is needed
188 # because the superclass includes it.
189 'braced string': [
190 (r'\}\}', String, '#pop'),
191 (r'[^}]|\}(?!\})', String)
132 ] 192 ]
133 } 193 }
134 194
135 195
136 class CsoundOrchestraLexer(CsoundLexer): 196 class CsoundOrchestraLexer(CsoundLexer):
137 """ 197 """
138 For `Csound <http://csound.github.io>`_ orchestras. 198 For `Csound <https://csound.github.io>`_ orchestras.
139 199
140 .. versionadded:: 2.1 200 .. versionadded:: 2.1
141 """ 201 """
142 202
143 name = 'Csound Orchestra' 203 name = 'Csound Orchestra'
144 aliases = ['csound', 'csound-orc'] 204 aliases = ['csound', 'csound-orc']
145 filenames = ['*.orc'] 205 filenames = ['*.orc', '*.udo']
146 206
147 user_defined_opcodes = set() 207 user_defined_opcodes = set()
148 208
149 def opcode_name_callback(lexer, match): 209 def opcode_name_callback(lexer, match):
150 opcode = match.group(0) 210 opcode = match.group(0)
151 lexer.user_defined_opcodes.add(opcode) 211 lexer.user_defined_opcodes.add(opcode)
152 yield match.start(), Name.Function, opcode 212 yield match.start(), Name.Function, opcode
153 213
154 def name_callback(lexer, match): 214 def name_callback(lexer, match):
155 name = match.group(0) 215 name = match.group(1)
156 if re.match('p\d+$', name) or name in OPCODES: 216 if name in OPCODES or name in DEPRECATED_OPCODES:
157 yield match.start(), Name.Builtin, name 217 yield match.start(), Name.Builtin, name
218 if match.group(2):
219 yield match.start(2), Punctuation, match.group(2)
220 yield match.start(3), Keyword.Type, match.group(3)
158 elif name in lexer.user_defined_opcodes: 221 elif name in lexer.user_defined_opcodes:
159 yield match.start(), Name.Function, name 222 yield match.start(), Name.Function, name
160 else: 223 else:
161 nameMatch = re.search(r'^(g?[aikSw])(\w+)', name) 224 nameMatch = re.search(r'^(g?[afikSw])(\w+)', name)
162 if nameMatch: 225 if nameMatch:
163 yield nameMatch.start(1), Keyword.Type, nameMatch.group(1) 226 yield nameMatch.start(1), Keyword.Type, nameMatch.group(1)
164 yield nameMatch.start(2), Name, nameMatch.group(2) 227 yield nameMatch.start(2), Name, nameMatch.group(2)
165 else: 228 else:
166 yield match.start(), Name, name 229 yield match.start(), Name, name
230 if match.group(2):
231 yield match.start(2), Punctuation, match.group(2)
232 yield match.start(3), Name, match.group(3)
167 233
168 tokens = { 234 tokens = {
169 'label': [ 235 'root': [
170 (r'\b(\w+)(:)', bygroups(Name.Label, Punctuation)) 236 (r'\n', Text),
171 ], 237
172 238 (r'^([ \t]*)(\w+)(:)(?:[ \t]+|$)', bygroups(Text, Name.Label, Punctuation)),
173 'partial expression': [ 239
240 include('whitespace and macro uses'),
174 include('preprocessor directives'), 241 include('preprocessor directives'),
175 (r'\b(0dbfs|k(r|smps)|nchnls(_i)?|sr)\b', Name.Variable.Global), 242
176 (r'\d+e[+-]?\d+|(\d+\.\d*|\d*\.\d+)(e[+-]?\d+)?', Number.Float), 243 (r'\binstr\b', Keyword.Declaration, 'instrument numbers and identifiers'),
177 (r'0[xX][a-fA-F0-9]+', Number.Hex), 244 (r'\bopcode\b', Keyword.Declaration, 'after opcode keyword'),
178 (r'\d+', Number.Integer), 245 (r'\b(?:end(?:in|op))\b', Keyword.Declaration),
179 (r'"', String, 'single-line string'), 246
180 (r'\{\{', String, 'multi-line string'), 247 include('partial statements')
181 (r'[+\-*/%^!=&|<>#~¬]', Operator), 248 ],
182 (r'[](),?:[]', Punctuation), 249
250 'partial statements': [
251 (r'\b(?:0dbfs|A4|k(?:r|smps)|nchnls(?:_i)?|sr)\b', Name.Variable.Global),
252
253 include('numbers'),
254
255 (r'\+=|-=|\*=|/=|<<|>>|<=|>=|==|!=|&&|\|\||[~¬]|[=!+\-*/^%&|<>#?:]', Operator),
256 (r'[(),\[\]]', Punctuation),
257
258 (r'"', String, 'quoted string'),
259 (r'\{\{', String, 'braced string'),
260
183 (words(( 261 (words((
184 # Keywords
185 'do', 'else', 'elseif', 'endif', 'enduntil', 'fi', 'if', 'ithen', 'kthen', 262 'do', 'else', 'elseif', 'endif', 'enduntil', 'fi', 'if', 'ithen', 'kthen',
186 'od', 'then', 'until', 'while', 263 'od', 'then', 'until', 'while',
187 # Opcodes that act as control structures
188 'return', 'timout'
189 ), prefix=r'\b', suffix=r'\b'), Keyword), 264 ), prefix=r'\b', suffix=r'\b'), Keyword),
190 (words(('goto', 'igoto', 'kgoto', 'rigoto', 'tigoto'), 265 (words(('return', 'rireturn'), prefix=r'\b', suffix=r'\b'), Keyword.Pseudo),
191 prefix=r'\b', suffix=r'\b'), Keyword, 'goto label'), 266
192 (words(('cggoto', 'cigoto', 'cingoto', 'ckgoto', 'cngoto'), 267 (r'\b[ik]?goto\b', Keyword, 'goto label'),
193 prefix=r'\b', suffix=r'\b'), Keyword, 268 (r'\b(r(?:einit|igoto)|tigoto)(\(|\b)', bygroups(Keyword.Pseudo, Punctuation),
194 ('goto label', 'goto expression')), 269 'goto label'),
195 (words(('loop_ge', 'loop_gt', 'loop_le', 'loop_lt'), 270 (r'\b(c(?:g|in?|k|nk?)goto)(\(|\b)', bygroups(Keyword.Pseudo, Punctuation),
196 prefix=r'\b', suffix=r'\b'), Keyword, 271 ('goto label', 'goto argument')),
197 ('goto label', 'goto expression', 'goto expression', 'goto expression')), 272 (r'\b(timout)(\(|\b)', bygroups(Keyword.Pseudo, Punctuation),
198 (r'\bscoreline(_i)?\b', Name.Builtin, 'scoreline opcode'), 273 ('goto label', 'goto argument', 'goto argument')),
199 (r'\bpyl?run[it]?\b', Name.Builtin, 'python opcode'), 274 (r'\b(loop_[gl][et])(\(|\b)', bygroups(Keyword.Pseudo, Punctuation),
200 (r'\blua_(exec|opdef)\b', Name.Builtin, 'lua opcode'), 275 ('goto label', 'goto argument', 'goto argument', 'goto argument')),
201 (r'\b[a-zA-Z_]\w*\b', name_callback) 276
202 ], 277 (r'\bprintk?s\b', Name.Builtin, 'prints opcode'),
203 278 (r'\b(?:readscore|scoreline(?:_i)?)\b', Name.Builtin, 'Csound score opcode'),
204 'expression': [ 279 (r'\bpyl?run[it]?\b', Name.Builtin, 'Python opcode'),
205 include('whitespace or macro call'), 280 (r'\blua_(?:exec|opdef)\b', Name.Builtin, 'Lua opcode'),
206 newline + ('#pop',), 281 (r'\bp\d+\b', Name.Variable.Instance),
207 include('partial expression') 282 (r'\b([A-Z_a-z]\w*)(?:(:)([A-Za-z]))?\b', name_callback)
208 ], 283 ],
209 284
210 'root': [ 285 'instrument numbers and identifiers': [
211 newline, 286 include('whitespace and macro uses'),
212 include('whitespace or macro call'), 287 (r'\d+|[A-Z_a-z]\w*', Name.Function),
213 (r'\binstr\b', Keyword, ('instrument block', 'instrument name list')), 288 (r'[+,]', Punctuation),
214 (r'\bopcode\b', Keyword, ('opcode block', 'opcode parameter list', 289 (r'\n', Text, '#pop')
215 'opcode types', 'opcode types', 'opcode name')), 290 ],
216 include('label'), 291
217 default('expression') 292 'after opcode keyword': [
218 ], 293 include('whitespace and macro uses'),
219 294 (r'[A-Z_a-z]\w*', opcode_name_callback, ('#pop', 'opcode type signatures')),
220 'instrument name list': [ 295 (r'\n', Text, '#pop')
221 include('whitespace or macro call'), 296 ],
222 (r'\d+|\+?[a-zA-Z_]\w*', Name.Function), 297 'opcode type signatures': [
298 include('whitespace and macro uses'),
299
300 # https://github.com/csound/csound/search?q=XIDENT+path%3AEngine+filename%3Acsound_orc.lex
301 (r'0|[afijkKoOpPStV\[\]]+', Keyword.Type),
302
223 (r',', Punctuation), 303 (r',', Punctuation),
224 newline + ('#pop',) 304 (r'\n', Text, '#pop')
225 ], 305 ],
226 'instrument block': [ 306
227 newline, 307 'quoted string': [
228 include('whitespace or macro call'), 308 (r'"', String, '#pop'),
229 (r'\bendin\b', Keyword, '#pop'), 309 (r'[^\\"$%)]+', String),
230 include('label'), 310 include('macro uses'),
231 default('expression') 311 include('escape sequences'),
232 ], 312 include('format specifiers'),
233 313 (r'[\\$%)]', String)
234 'opcode name': [ 314 ],
235 include('whitespace or macro call'), 315 'braced string': [
236 (r'[a-zA-Z_]\w*', opcode_name_callback, '#pop') 316 (r'\}\}', String, '#pop'),
237 ], 317 (r'(?:[^\\%)}]|\}(?!\}))+', String),
238 'opcode types': [ 318 include('escape sequences'),
239 include('whitespace or macro call'), 319 include('format specifiers'),
240 (r'0|[]afijkKoOpPStV[]+', Keyword.Type, '#pop'), 320 (r'[\\%)]', String)
241 (r',', Punctuation) 321 ],
242 ], 322 'escape sequences': [
243 'opcode parameter list': [ 323 # https://github.com/csound/csound/search?q=unquote_string+path%3AEngine+filename%3Acsound_orc_compile.c
244 include('whitespace or macro call'), 324 (r'\\(?:[\\abnrt"]|[0-7]{1,3})', String.Escape)
245 newline + ('#pop',) 325 ],
246 ], 326 # Format specifiers are highlighted in all strings, even though only
247 'opcode block': [ 327 # fprintks https://csound.github.io/docs/manual/fprintks.html
248 newline, 328 # fprints https://csound.github.io/docs/manual/fprints.html
249 include('whitespace or macro call'), 329 # printf/printf_i https://csound.github.io/docs/manual/printf.html
250 (r'\bendop\b', Keyword, '#pop'), 330 # printks https://csound.github.io/docs/manual/printks.html
251 include('label'), 331 # prints https://csound.github.io/docs/manual/prints.html
252 default('expression') 332 # sprintf https://csound.github.io/docs/manual/sprintf.html
253 ], 333 # sprintfk https://csound.github.io/docs/manual/sprintfk.html
254 334 # work with strings that contain format specifiers. In addition, these
335 # opcodes’ handling of format specifiers is inconsistent:
336 # - fprintks, fprints, printks, and prints do accept %a and %A
337 # specifiers, but can’t accept %s specifiers.
338 # - printf, printf_i, sprintf, and sprintfk don’t accept %a and %A
339 # specifiers, but can accept %s specifiers.
340 # See https://github.com/csound/csound/issues/747 for more information.
341 'format specifiers': [
342 (r'%[#0\- +]*\d*(?:\.\d+)?[diuoxXfFeEgGaAcs]', String.Interpol),
343 (r'%%', String.Escape)
344 ],
345
346 'goto argument': [
347 include('whitespace and macro uses'),
348 (r',', Punctuation, '#pop'),
349 include('partial statements')
350 ],
255 'goto label': [ 351 'goto label': [
256 include('whitespace or macro call'), 352 include('whitespace and macro uses'),
257 (r'\w+', Name.Label, '#pop'), 353 (r'\w+', Name.Label, '#pop'),
258 default('#pop') 354 default('#pop')
259 ], 355 ],
260 'goto expression': [ 356
261 include('whitespace or macro call'), 357 'prints opcode': [
262 (r',', Punctuation, '#pop'), 358 include('whitespace and macro uses'),
263 include('partial expression') 359 (r'"', String, 'prints quoted string'),
264 ],
265
266 'single-line string': [
267 include('macro call'),
268 (r'"', String, '#pop'),
269 # From https://github.com/csound/csound/blob/develop/Opcodes/fout.c#L1405
270 (r'%\d*(\.\d+)?[cdhilouxX]', String.Interpol),
271 (r'%[!%nNrRtT]|[~^]|\\([\\aAbBnNrRtT"]|[0-7]{1,3})', String.Escape),
272 (r'[^\\"~$%\^\n]+', String),
273 (r'[\\"~$%\^\n]', String)
274 ],
275 'multi-line string': [
276 (r'\}\}', String, '#pop'),
277 (r'[^}]+|\}(?!\})', String)
278 ],
279
280 'scoreline opcode': [
281 include('whitespace or macro call'),
282 (r'\{\{', String, 'scoreline'),
283 default('#pop') 360 default('#pop')
284 ], 361 ],
285 'scoreline': [ 362 'prints quoted string': [
363 (r'\\\\[aAbBnNrRtT]', String.Escape),
364 (r'%[!nNrRtT]|[~^]{1,2}', String.Escape),
365 include('quoted string')
366 ],
367
368 'Csound score opcode': [
369 include('whitespace and macro uses'),
370 (r'\{\{', String, 'Csound score'),
371 (r'\n', Text, '#pop')
372 ],
373 'Csound score': [
286 (r'\}\}', String, '#pop'), 374 (r'\}\}', String, '#pop'),
287 (r'([^}]+)|\}(?!\})', using(CsoundScoreLexer)) 375 (r'([^}]+)|\}(?!\})', using(CsoundScoreLexer))
288 ], 376 ],
289 377
290 'python opcode': [ 378 'Python opcode': [
291 include('whitespace or macro call'), 379 include('whitespace and macro uses'),
292 (r'\{\{', String, 'python'), 380 (r'\{\{', String, 'Python'),
293 default('#pop') 381 (r'\n', Text, '#pop')
294 ], 382 ],
295 'python': [ 383 'Python': [
296 (r'\}\}', String, '#pop'), 384 (r'\}\}', String, '#pop'),
297 (r'([^}]+)|\}(?!\})', using(PythonLexer)) 385 (r'([^}]+)|\}(?!\})', using(PythonLexer))
298 ], 386 ],
299 387
300 'lua opcode': [ 388 'Lua opcode': [
301 include('whitespace or macro call'), 389 include('whitespace and macro uses'),
302 (r'"', String, 'single-line string'), 390 (r'\{\{', String, 'Lua'),
303 (r'\{\{', String, 'lua'), 391 (r'\n', Text, '#pop')
304 (r',', Punctuation), 392 ],
305 default('#pop') 393 'Lua': [
306 ],
307 'lua': [
308 (r'\}\}', String, '#pop'), 394 (r'\}\}', String, '#pop'),
309 (r'([^}]+)|\}(?!\})', using(LuaLexer)) 395 (r'([^}]+)|\}(?!\})', using(LuaLexer))
310 ] 396 ]
311 } 397 }
312 398
313 399
314 class CsoundDocumentLexer(RegexLexer): 400 class CsoundDocumentLexer(RegexLexer):
315 """ 401 """
316 For `Csound <http://csound.github.io>`_ documents. 402 For `Csound <https://csound.github.io>`_ documents.
317 403
318 .. versionadded:: 2.1 404 .. versionadded:: 2.1
319 """ 405 """
320 406
321 name = 'Csound Document' 407 name = 'Csound Document'
329 # after the root element, unescaped bitwise AND & and less than < operators, etc. In 415 # after the root element, unescaped bitwise AND & and less than < operators, etc. In
330 # other words, while Csound Document files look like XML files, they may not actually 416 # other words, while Csound Document files look like XML files, they may not actually
331 # be XML files. 417 # be XML files.
332 tokens = { 418 tokens = {
333 'root': [ 419 'root': [
334 newline,
335 (r'/[*](.|\n)*?[*]/', Comment.Multiline), 420 (r'/[*](.|\n)*?[*]/', Comment.Multiline),
336 (r'[^<&;/]+', Text), 421 (r'(?:;|//).*$', Comment.Single),
422 (r'[^/;<]+|/(?!/)', Text),
423
337 (r'<\s*CsInstruments', Name.Tag, ('orchestra', 'tag')), 424 (r'<\s*CsInstruments', Name.Tag, ('orchestra', 'tag')),
338 (r'<\s*CsScore', Name.Tag, ('score', 'tag')), 425 (r'<\s*CsScore', Name.Tag, ('score', 'tag')),
339 (r'<\s*[hH][tT][mM][lL]', Name.Tag, ('HTML', 'tag')), 426 (r'<\s*[Hh][Tt][Mm][Ll]', Name.Tag, ('HTML', 'tag')),
427
340 (r'<\s*[\w:.-]+', Name.Tag, 'tag'), 428 (r'<\s*[\w:.-]+', Name.Tag, 'tag'),
341 (r'<\s*/\s*[\w:.-]+\s*>', Name.Tag) 429 (r'<\s*/\s*[\w:.-]+\s*>', Name.Tag)
342 ], 430 ],
431
343 'orchestra': [ 432 'orchestra': [
344 (r'<\s*/\s*CsInstruments\s*>', Name.Tag, '#pop'), 433 (r'<\s*/\s*CsInstruments\s*>', Name.Tag, '#pop'),
345 (r'(.|\n)+?(?=<\s*/\s*CsInstruments\s*>)', using(CsoundOrchestraLexer)) 434 (r'(.|\n)+?(?=<\s*/\s*CsInstruments\s*>)', using(CsoundOrchestraLexer))
346 ], 435 ],
347 'score': [ 436 'score': [
348 (r'<\s*/\s*CsScore\s*>', Name.Tag, '#pop'), 437 (r'<\s*/\s*CsScore\s*>', Name.Tag, '#pop'),
349 (r'(.|\n)+?(?=<\s*/\s*CsScore\s*>)', using(CsoundScoreLexer)) 438 (r'(.|\n)+?(?=<\s*/\s*CsScore\s*>)', using(CsoundScoreLexer))
350 ], 439 ],
351 'HTML': [ 440 'HTML': [
352 (r'<\s*/\s*[hH][tT][mM][lL]\s*>', Name.Tag, '#pop'), 441 (r'<\s*/\s*[Hh][Tt][Mm][Ll]\s*>', Name.Tag, '#pop'),
353 (r'(.|\n)+?(?=<\s*/\s*[hH][tT][mM][lL]\s*>)', using(HtmlLexer)) 442 (r'(.|\n)+?(?=<\s*/\s*[Hh][Tt][Mm][Ll]\s*>)', using(HtmlLexer))
354 ], 443 ],
444
355 'tag': [ 445 'tag': [
356 (r'\s+', Text), 446 (r'\s+', Text),
357 (r'[\w.:-]+\s*=', Name.Attribute, 'attr'), 447 (r'[\w.:-]+\s*=', Name.Attribute, 'attr'),
358 (r'/?\s*>', Name.Tag, '#pop') 448 (r'/?\s*>', Name.Tag, '#pop')
359 ], 449 ],

eric ide

mercurial