1# -*- coding: utf-8 -*-
2"""
3    pygments.lexers.matlab
4    ~~~~~~~~~~~~~~~~~~~~~~
5
6    Lexers for Matlab and related languages.
7
8    :copyright: Copyright 2006-2019 by the Pygments team, see AUTHORS.
9    :license: BSD, see LICENSE for details.
10"""
11
12import re
13
14from pygments.lexer import Lexer, RegexLexer, bygroups, words, do_insertions
15from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
16    Number, Punctuation, Generic, Whitespace
17
18from pygments.lexers import _scilab_builtins
19
20__all__ = ['MatlabLexer', 'MatlabSessionLexer', 'OctaveLexer', 'ScilabLexer']
21
22
23class MatlabLexer(RegexLexer):
24    """
25    For Matlab source code.
26
27    .. versionadded:: 0.10
28    """
29    name = 'Matlab'
30    aliases = ['matlab']
31    filenames = ['*.m']
32    mimetypes = ['text/matlab']
33
34    #
35    # These lists are generated automatically.
36    # Run the following in bash shell:
37    #
38    # for f in elfun specfun elmat; do
39    #   echo -n "$f = "
40    #   matlab -nojvm -r "help $f;exit;" | perl -ne \
41    #   'push(@c,$1) if /^    (\w+)\s+-/; END {print q{["}.join(q{","},@c).qq{"]\n};}'
42    # done
43    #
44    # elfun: Elementary math functions
45    # specfun: Special Math functions
46    # elmat: Elementary matrices and matrix manipulation
47    #
48    # taken from Matlab version 7.4.0.336 (R2007a)
49    #
50    elfun = ("sin", "sind", "sinh", "asin", "asind", "asinh", "cos", "cosd", "cosh",
51             "acos", "acosd", "acosh", "tan", "tand", "tanh", "atan", "atand", "atan2",
52             "atanh", "sec", "secd", "sech", "asec", "asecd", "asech", "csc", "cscd",
53             "csch", "acsc", "acscd", "acsch", "cot", "cotd", "coth", "acot", "acotd",
54             "acoth", "hypot", "exp", "expm1", "log", "log1p", "log10", "log2", "pow2",
55             "realpow", "reallog", "realsqrt", "sqrt", "nthroot", "nextpow2", "abs",
56             "angle", "complex", "conj", "imag", "real", "unwrap", "isreal", "cplxpair",
57             "fix", "floor", "ceil", "round", "mod", "rem", "sign")
58    specfun = ("airy", "besselj", "bessely", "besselh", "besseli", "besselk", "beta",
59               "betainc", "betaln", "ellipj", "ellipke", "erf", "erfc", "erfcx",
60               "erfinv", "expint", "gamma", "gammainc", "gammaln", "psi", "legendre",
61               "cross", "dot", "factor", "isprime", "primes", "gcd", "lcm", "rat",
62               "rats", "perms", "nchoosek", "factorial", "cart2sph", "cart2pol",
63               "pol2cart", "sph2cart", "hsv2rgb", "rgb2hsv")
64    elmat = ("zeros", "ones", "eye", "repmat", "rand", "randn", "linspace", "logspace",
65             "freqspace", "meshgrid", "accumarray", "size", "length", "ndims", "numel",
66             "disp", "isempty", "isequal", "isequalwithequalnans", "cat", "reshape",
67             "diag", "blkdiag", "tril", "triu", "fliplr", "flipud", "flipdim", "rot90",
68             "find", "end", "sub2ind", "ind2sub", "bsxfun", "ndgrid", "permute",
69             "ipermute", "shiftdim", "circshift", "squeeze", "isscalar", "isvector",
70             "ans", "eps", "realmax", "realmin", "pi", "i", "inf", "nan", "isnan",
71             "isinf", "isfinite", "j", "why", "compan", "gallery", "hadamard", "hankel",
72             "hilb", "invhilb", "magic", "pascal", "rosser", "toeplitz", "vander",
73             "wilkinson")
74
75    _operators = r'-|==|~=|<=|>=|<|>|&&|&|~|\|\|?|\.\*|\*|\+|\.\^|\.\\|\.\/|\/|\\'
76
77    tokens = {
78        'root': [
79            # line starting with '!' is sent as a system command.  not sure what
80            # label to use...
81            (r'^!.*', String.Other),
82            (r'%\{\s*\n', Comment.Multiline, 'blockcomment'),
83            (r'%.*$', Comment),
84            (r'^\s*function\b', Keyword, 'deffunc'),
85
86            # from 'iskeyword' on version 7.11 (R2010):
87            # Check that there is no preceding dot, as keywords are valid field
88            # names.
89            (words(('break', 'case', 'catch', 'classdef', 'continue', 'else',
90                    'elseif', 'end', 'enumerated', 'events', 'for', 'function',
91                    'global', 'if', 'methods', 'otherwise', 'parfor',
92                    'persistent', 'properties', 'return', 'spmd', 'switch',
93                    'try', 'while'),
94                   prefix=r'(?<!\.)', suffix=r'\b'),
95             Keyword),
96
97            ("(" + "|".join(elfun + specfun + elmat) + r')\b',  Name.Builtin),
98
99            # line continuation with following comment:
100            (r'\.\.\..*$', Comment),
101
102            # command form:
103            # "How MATLAB Recognizes Command Syntax" specifies that an operator
104            # is recognized if it is either surrounded by spaces or by no
105            # spaces on both sides; only the former case matters for us.  (This
106            # allows distinguishing `cd ./foo` from `cd ./ foo`.)
107            (r'(?:^|(?<=;))\s*\w+\s+(?!=|\(|(%s)\s+)' % _operators, Name,
108             'commandargs'),
109
110            # operators:
111            (_operators, Operator),
112
113            # numbers (must come before punctuation to handle `.5`; cannot use
114            # `\b` due to e.g. `5. + .5`).
115            (r'(?<!\w)((\d+\.\d*)|(\d*\.\d+))([eEf][+-]?\d+)?(?!\w)', Number.Float),
116            (r'\b\d+[eEf][+-]?[0-9]+\b', Number.Float),
117            (r'\b\d+\b', Number.Integer),
118
119            # punctuation:
120            (r'\[|\]|\(|\)|\{|\}|:|@|\.|,', Punctuation),
121            (r'=|:|;', Punctuation),
122
123            # quote can be transpose, instead of string:
124            # (not great, but handles common cases...)
125            (r'(?<=[\w)\].])\'+', Operator),
126
127            (r'"(""|[^"])*"', String),
128
129            (r'(?<![\w)\].])\'', String, 'string'),
130            (r'[a-zA-Z_]\w*', Name),
131            (r'.', Text),
132        ],
133        'blockcomment': [
134            (r'^\s*%\}', Comment.Multiline, '#pop'),
135            (r'^.*\n', Comment.Multiline),
136            (r'.', Comment.Multiline),
137        ],
138        'deffunc': [
139            (r'(\s*)(?:(.+)(\s*)(=)(\s*))?(.+)(\()(.*)(\))(\s*)',
140             bygroups(Whitespace, Text, Whitespace, Punctuation,
141                      Whitespace, Name.Function, Punctuation, Text,
142                      Punctuation, Whitespace), '#pop'),
143            # function with no args
144            (r'(\s*)([a-zA-Z_]\w*)', bygroups(Text, Name.Function), '#pop'),
145        ],
146        'string': [
147            (r"[^']*'", String, '#pop'),
148        ],
149        'commandargs': [
150            ("'[^']*'", String),
151            ("[^';\n]+", String),
152            (";?\n?", Punctuation, '#pop'),
153        ]
154    }
155
156    def analyse_text(text):
157        # function declaration.
158        first_non_comment = next((line for line in text.splitlines()
159                                  if not re.match(r'^\s*%', text)), '').strip()
160        if (first_non_comment.startswith('function')
161                and '{' not in first_non_comment):
162            return 1.
163        # comment
164        elif re.match(r'^\s*%', text, re.M):
165            return 0.2
166        # system cmd
167        elif re.match(r'^!\w+', text, re.M):
168            return 0.2
169
170
171line_re  = re.compile('.*?\n')
172
173
174class MatlabSessionLexer(Lexer):
175    """
176    For Matlab sessions.  Modeled after PythonConsoleLexer.
177    Contributed by Ken Schutte <kschutte@csail.mit.edu>.
178
179    .. versionadded:: 0.10
180    """
181    name = 'Matlab session'
182    aliases = ['matlabsession']
183
184    def get_tokens_unprocessed(self, text):
185        mlexer = MatlabLexer(**self.options)
186
187        curcode = ''
188        insertions = []
189
190        for match in line_re.finditer(text):
191            line = match.group()
192
193            if line.startswith('>> '):
194                insertions.append((len(curcode),
195                                   [(0, Generic.Prompt, line[:3])]))
196                curcode += line[3:]
197
198            elif line.startswith('>>'):
199                insertions.append((len(curcode),
200                                   [(0, Generic.Prompt, line[:2])]))
201                curcode += line[2:]
202
203            elif line.startswith('???'):
204
205                idx = len(curcode)
206
207                # without is showing error on same line as before...?
208                # line = "\n" + line
209                token = (0, Generic.Traceback, line)
210                insertions.append((idx, [token]))
211
212            else:
213                if curcode:
214                    for item in do_insertions(
215                            insertions, mlexer.get_tokens_unprocessed(curcode)):
216                        yield item
217                    curcode = ''
218                    insertions = []
219
220                yield match.start(), Generic.Output, line
221
222        if curcode:  # or item:
223            for item in do_insertions(
224                    insertions, mlexer.get_tokens_unprocessed(curcode)):
225                yield item
226
227
228class OctaveLexer(RegexLexer):
229    """
230    For GNU Octave source code.
231
232    .. versionadded:: 1.5
233    """
234    name = 'Octave'
235    aliases = ['octave']
236    filenames = ['*.m']
237    mimetypes = ['text/octave']
238
239    # These lists are generated automatically.
240    # Run the following in bash shell:
241    #
242    # First dump all of the Octave manual into a plain text file:
243    #
244    #   $ info octave --subnodes -o octave-manual
245    #
246    # Now grep through it:
247
248    # for i in \
249    #     "Built-in Function" "Command" "Function File" \
250    #     "Loadable Function" "Mapping Function";
251    # do
252    #     perl -e '@name = qw('"$i"');
253    #              print lc($name[0]),"_kw = [\n"';
254    #
255    #     perl -n -e 'print "\"$1\",\n" if /-- '"$i"': .* (\w*) \(/;' \
256    #         octave-manual | sort | uniq ;
257    #     echo "]" ;
258    #     echo;
259    # done
260
261    # taken from Octave Mercurial changeset 8cc154f45e37 (30-jan-2011)
262
263    builtin_kw = (
264        "addlistener", "addpath", "addproperty", "all",
265        "and", "any", "argnames", "argv", "assignin",
266        "atexit", "autoload",
267        "available_graphics_toolkits", "beep_on_error",
268        "bitand", "bitmax", "bitor", "bitshift", "bitxor",
269        "cat", "cell", "cellstr", "char", "class", "clc",
270        "columns", "command_line_path",
271        "completion_append_char", "completion_matches",
272        "complex", "confirm_recursive_rmdir", "cputime",
273        "crash_dumps_octave_core", "ctranspose", "cumprod",
274        "cumsum", "debug_on_error", "debug_on_interrupt",
275        "debug_on_warning", "default_save_options",
276        "dellistener", "diag", "diff", "disp",
277        "doc_cache_file", "do_string_escapes", "double",
278        "drawnow", "e", "echo_executing_commands", "eps",
279        "eq", "errno", "errno_list", "error", "eval",
280        "evalin", "exec", "exist", "exit", "eye", "false",
281        "fclear", "fclose", "fcntl", "fdisp", "feof",
282        "ferror", "feval", "fflush", "fgetl", "fgets",
283        "fieldnames", "file_in_loadpath", "file_in_path",
284        "filemarker", "filesep", "find_dir_in_path",
285        "fixed_point_format", "fnmatch", "fopen", "fork",
286        "formula", "fprintf", "fputs", "fread", "freport",
287        "frewind", "fscanf", "fseek", "fskipl", "ftell",
288        "functions", "fwrite", "ge", "genpath", "get",
289        "getegid", "getenv", "geteuid", "getgid",
290        "getpgrp", "getpid", "getppid", "getuid", "glob",
291        "gt", "gui_mode", "history_control",
292        "history_file", "history_size",
293        "history_timestamp_format_string", "home",
294        "horzcat", "hypot", "ifelse",
295        "ignore_function_time_stamp", "inferiorto",
296        "info_file", "info_program", "inline", "input",
297        "intmax", "intmin", "ipermute",
298        "is_absolute_filename", "isargout", "isbool",
299        "iscell", "iscellstr", "ischar", "iscomplex",
300        "isempty", "isfield", "isfloat", "isglobal",
301        "ishandle", "isieee", "isindex", "isinteger",
302        "islogical", "ismatrix", "ismethod", "isnull",
303        "isnumeric", "isobject", "isreal",
304        "is_rooted_relative_filename", "issorted",
305        "isstruct", "isvarname", "kbhit", "keyboard",
306        "kill", "lasterr", "lasterror", "lastwarn",
307        "ldivide", "le", "length", "link", "linspace",
308        "logical", "lstat", "lt", "make_absolute_filename",
309        "makeinfo_program", "max_recursion_depth", "merge",
310        "methods", "mfilename", "minus", "mislocked",
311        "mkdir", "mkfifo", "mkstemp", "mldivide", "mlock",
312        "mouse_wheel_zoom", "mpower", "mrdivide", "mtimes",
313        "munlock", "nargin", "nargout",
314        "native_float_format", "ndims", "ne", "nfields",
315        "nnz", "norm", "not", "numel", "nzmax",
316        "octave_config_info", "octave_core_file_limit",
317        "octave_core_file_name",
318        "octave_core_file_options", "ones", "or",
319        "output_max_field_width", "output_precision",
320        "page_output_immediately", "page_screen_output",
321        "path", "pathsep", "pause", "pclose", "permute",
322        "pi", "pipe", "plus", "popen", "power",
323        "print_empty_dimensions", "printf",
324        "print_struct_array_contents", "prod",
325        "program_invocation_name", "program_name",
326        "putenv", "puts", "pwd", "quit", "rats", "rdivide",
327        "readdir", "readlink", "read_readline_init_file",
328        "realmax", "realmin", "rehash", "rename",
329        "repelems", "re_read_readline_init_file", "reset",
330        "reshape", "resize", "restoredefaultpath",
331        "rethrow", "rmdir", "rmfield", "rmpath", "rows",
332        "save_header_format_string", "save_precision",
333        "saving_history", "scanf", "set", "setenv",
334        "shell_cmd", "sighup_dumps_octave_core",
335        "sigterm_dumps_octave_core", "silent_functions",
336        "single", "size", "size_equal", "sizemax",
337        "sizeof", "sleep", "source", "sparse_auto_mutate",
338        "split_long_rows", "sprintf", "squeeze", "sscanf",
339        "stat", "stderr", "stdin", "stdout", "strcmp",
340        "strcmpi", "string_fill_char", "strncmp",
341        "strncmpi", "struct", "struct_levels_to_print",
342        "strvcat", "subsasgn", "subsref", "sum", "sumsq",
343        "superiorto", "suppress_verbose_help_message",
344        "symlink", "system", "tic", "tilde_expand",
345        "times", "tmpfile", "tmpnam", "toc", "toupper",
346        "transpose", "true", "typeinfo", "umask", "uminus",
347        "uname", "undo_string_escapes", "unlink", "uplus",
348        "upper", "usage", "usleep", "vec", "vectorize",
349        "vertcat", "waitpid", "warning", "warranty",
350        "whos_line_format", "yes_or_no", "zeros",
351        "inf", "Inf", "nan", "NaN")
352
353    command_kw = ("close", "load", "who", "whos")
354
355    function_kw = (
356        "accumarray", "accumdim", "acosd", "acotd",
357        "acscd", "addtodate", "allchild", "ancestor",
358        "anova", "arch_fit", "arch_rnd", "arch_test",
359        "area", "arma_rnd", "arrayfun", "ascii", "asctime",
360        "asecd", "asind", "assert", "atand",
361        "autoreg_matrix", "autumn", "axes", "axis", "bar",
362        "barh", "bartlett", "bartlett_test", "beep",
363        "betacdf", "betainv", "betapdf", "betarnd",
364        "bicgstab", "bicubic", "binary", "binocdf",
365        "binoinv", "binopdf", "binornd", "bitcmp",
366        "bitget", "bitset", "blackman", "blanks",
367        "blkdiag", "bone", "box", "brighten", "calendar",
368        "cast", "cauchy_cdf", "cauchy_inv", "cauchy_pdf",
369        "cauchy_rnd", "caxis", "celldisp", "center", "cgs",
370        "chisquare_test_homogeneity",
371        "chisquare_test_independence", "circshift", "cla",
372        "clabel", "clf", "clock", "cloglog", "closereq",
373        "colon", "colorbar", "colormap", "colperm",
374        "comet", "common_size", "commutation_matrix",
375        "compan", "compare_versions", "compass",
376        "computer", "cond", "condest", "contour",
377        "contourc", "contourf", "contrast", "conv",
378        "convhull", "cool", "copper", "copyfile", "cor",
379        "corrcoef", "cor_test", "cosd", "cotd", "cov",
380        "cplxpair", "cross", "cscd", "cstrcat", "csvread",
381        "csvwrite", "ctime", "cumtrapz", "curl", "cut",
382        "cylinder", "date", "datenum", "datestr",
383        "datetick", "datevec", "dblquad", "deal",
384        "deblank", "deconv", "delaunay", "delaunayn",
385        "delete", "demo", "detrend", "diffpara", "diffuse",
386        "dir", "discrete_cdf", "discrete_inv",
387        "discrete_pdf", "discrete_rnd", "display",
388        "divergence", "dlmwrite", "dos", "dsearch",
389        "dsearchn", "duplication_matrix", "durbinlevinson",
390        "ellipsoid", "empirical_cdf", "empirical_inv",
391        "empirical_pdf", "empirical_rnd", "eomday",
392        "errorbar", "etime", "etreeplot", "example",
393        "expcdf", "expinv", "expm", "exppdf", "exprnd",
394        "ezcontour", "ezcontourf", "ezmesh", "ezmeshc",
395        "ezplot", "ezpolar", "ezsurf", "ezsurfc", "factor",
396        "factorial", "fail", "fcdf", "feather", "fftconv",
397        "fftfilt", "fftshift", "figure", "fileattrib",
398        "fileparts", "fill", "findall", "findobj",
399        "findstr", "finv", "flag", "flipdim", "fliplr",
400        "flipud", "fpdf", "fplot", "fractdiff", "freqz",
401        "freqz_plot", "frnd", "fsolve",
402        "f_test_regression", "ftp", "fullfile", "fzero",
403        "gamcdf", "gaminv", "gampdf", "gamrnd", "gca",
404        "gcbf", "gcbo", "gcf", "genvarname", "geocdf",
405        "geoinv", "geopdf", "geornd", "getfield", "ginput",
406        "glpk", "gls", "gplot", "gradient",
407        "graphics_toolkit", "gray", "grid", "griddata",
408        "griddatan", "gtext", "gunzip", "gzip", "hadamard",
409        "hamming", "hankel", "hanning", "hggroup",
410        "hidden", "hilb", "hist", "histc", "hold", "hot",
411        "hotelling_test", "housh", "hsv", "hurst",
412        "hygecdf", "hygeinv", "hygepdf", "hygernd",
413        "idivide", "ifftshift", "image", "imagesc",
414        "imfinfo", "imread", "imshow", "imwrite", "index",
415        "info", "inpolygon", "inputname", "interpft",
416        "interpn", "intersect", "invhilb", "iqr", "isa",
417        "isdefinite", "isdir", "is_duplicate_entry",
418        "isequal", "isequalwithequalnans", "isfigure",
419        "ishermitian", "ishghandle", "is_leap_year",
420        "isletter", "ismac", "ismember", "ispc", "isprime",
421        "isprop", "isscalar", "issquare", "isstrprop",
422        "issymmetric", "isunix", "is_valid_file_id",
423        "isvector", "jet", "kendall",
424        "kolmogorov_smirnov_cdf",
425        "kolmogorov_smirnov_test", "kruskal_wallis_test",
426        "krylov", "kurtosis", "laplace_cdf", "laplace_inv",
427        "laplace_pdf", "laplace_rnd", "legend", "legendre",
428        "license", "line", "linkprop", "list_primes",
429        "loadaudio", "loadobj", "logistic_cdf",
430        "logistic_inv", "logistic_pdf", "logistic_rnd",
431        "logit", "loglog", "loglogerr", "logm", "logncdf",
432        "logninv", "lognpdf", "lognrnd", "logspace",
433        "lookfor", "ls_command", "lsqnonneg", "magic",
434        "mahalanobis", "manova", "matlabroot",
435        "mcnemar_test", "mean", "meansq", "median", "menu",
436        "mesh", "meshc", "meshgrid", "meshz", "mexext",
437        "mget", "mkpp", "mode", "moment", "movefile",
438        "mpoles", "mput", "namelengthmax", "nargchk",
439        "nargoutchk", "nbincdf", "nbininv", "nbinpdf",
440        "nbinrnd", "nchoosek", "ndgrid", "newplot", "news",
441        "nonzeros", "normcdf", "normest", "norminv",
442        "normpdf", "normrnd", "now", "nthroot", "null",
443        "ocean", "ols", "onenormest", "optimget",
444        "optimset", "orderfields", "orient", "orth",
445        "pack", "pareto", "parseparams", "pascal", "patch",
446        "pathdef", "pcg", "pchip", "pcolor", "pcr",
447        "peaks", "periodogram", "perl", "perms", "pie",
448        "pink", "planerot", "playaudio", "plot",
449        "plotmatrix", "plotyy", "poisscdf", "poissinv",
450        "poisspdf", "poissrnd", "polar", "poly",
451        "polyaffine", "polyarea", "polyderiv", "polyfit",
452        "polygcd", "polyint", "polyout", "polyreduce",
453        "polyval", "polyvalm", "postpad", "powerset",
454        "ppder", "ppint", "ppjumps", "ppplot", "ppval",
455        "pqpnonneg", "prepad", "primes", "print",
456        "print_usage", "prism", "probit", "qp", "qqplot",
457        "quadcc", "quadgk", "quadl", "quadv", "quiver",
458        "qzhess", "rainbow", "randi", "range", "rank",
459        "ranks", "rat", "reallog", "realpow", "realsqrt",
460        "record", "rectangle_lw", "rectangle_sw",
461        "rectint", "refresh", "refreshdata",
462        "regexptranslate", "repmat", "residue", "ribbon",
463        "rindex", "roots", "rose", "rosser", "rotdim",
464        "rref", "run", "run_count", "rundemos", "run_test",
465        "runtests", "saveas", "saveaudio", "saveobj",
466        "savepath", "scatter", "secd", "semilogx",
467        "semilogxerr", "semilogy", "semilogyerr",
468        "setaudio", "setdiff", "setfield", "setxor",
469        "shading", "shift", "shiftdim", "sign_test",
470        "sinc", "sind", "sinetone", "sinewave", "skewness",
471        "slice", "sombrero", "sortrows", "spaugment",
472        "spconvert", "spdiags", "spearman", "spectral_adf",
473        "spectral_xdf", "specular", "speed", "spencer",
474        "speye", "spfun", "sphere", "spinmap", "spline",
475        "spones", "sprand", "sprandn", "sprandsym",
476        "spring", "spstats", "spy", "sqp", "stairs",
477        "statistics", "std", "stdnormal_cdf",
478        "stdnormal_inv", "stdnormal_pdf", "stdnormal_rnd",
479        "stem", "stft", "strcat", "strchr", "strjust",
480        "strmatch", "strread", "strsplit", "strtok",
481        "strtrim", "strtrunc", "structfun", "studentize",
482        "subplot", "subsindex", "subspace", "substr",
483        "substruct", "summer", "surf", "surface", "surfc",
484        "surfl", "surfnorm", "svds", "swapbytes",
485        "sylvester_matrix", "symvar", "synthesis", "table",
486        "tand", "tar", "tcdf", "tempdir", "tempname",
487        "test", "text", "textread", "textscan", "tinv",
488        "title", "toeplitz", "tpdf", "trace", "trapz",
489        "treelayout", "treeplot", "triangle_lw",
490        "triangle_sw", "tril", "trimesh", "triplequad",
491        "triplot", "trisurf", "triu", "trnd", "tsearchn",
492        "t_test", "t_test_regression", "type", "unidcdf",
493        "unidinv", "unidpdf", "unidrnd", "unifcdf",
494        "unifinv", "unifpdf", "unifrnd", "union", "unique",
495        "unix", "unmkpp", "unpack", "untabify", "untar",
496        "unwrap", "unzip", "u_test", "validatestring",
497        "vander", "var", "var_test", "vech", "ver",
498        "version", "view", "voronoi", "voronoin",
499        "waitforbuttonpress", "wavread", "wavwrite",
500        "wblcdf", "wblinv", "wblpdf", "wblrnd", "weekday",
501        "welch_test", "what", "white", "whitebg",
502        "wienrnd", "wilcoxon_test", "wilkinson", "winter",
503        "xlabel", "xlim", "ylabel", "yulewalker", "zip",
504        "zlabel", "z_test")
505
506    loadable_kw = (
507        "airy", "amd", "balance", "besselh", "besseli",
508        "besselj", "besselk", "bessely", "bitpack",
509        "bsxfun", "builtin", "ccolamd", "cellfun",
510        "cellslices", "chol", "choldelete", "cholinsert",
511        "cholinv", "cholshift", "cholupdate", "colamd",
512        "colloc", "convhulln", "convn", "csymamd",
513        "cummax", "cummin", "daspk", "daspk_options",
514        "dasrt", "dasrt_options", "dassl", "dassl_options",
515        "dbclear", "dbdown", "dbstack", "dbstatus",
516        "dbstop", "dbtype", "dbup", "dbwhere", "det",
517        "dlmread", "dmperm", "dot", "eig", "eigs",
518        "endgrent", "endpwent", "etree", "fft", "fftn",
519        "fftw", "filter", "find", "full", "gcd",
520        "getgrent", "getgrgid", "getgrnam", "getpwent",
521        "getpwnam", "getpwuid", "getrusage", "givens",
522        "gmtime", "gnuplot_binary", "hess", "ifft",
523        "ifftn", "inv", "isdebugmode", "issparse", "kron",
524        "localtime", "lookup", "lsode", "lsode_options",
525        "lu", "luinc", "luupdate", "matrix_type", "max",
526        "min", "mktime", "pinv", "qr", "qrdelete",
527        "qrinsert", "qrshift", "qrupdate", "quad",
528        "quad_options", "qz", "rand", "rande", "randg",
529        "randn", "randp", "randperm", "rcond", "regexp",
530        "regexpi", "regexprep", "schur", "setgrent",
531        "setpwent", "sort", "spalloc", "sparse", "spparms",
532        "sprank", "sqrtm", "strfind", "strftime",
533        "strptime", "strrep", "svd", "svd_driver", "syl",
534        "symamd", "symbfact", "symrcm", "time", "tsearch",
535        "typecast", "urlread", "urlwrite")
536
537    mapping_kw = (
538        "abs", "acos", "acosh", "acot", "acoth", "acsc",
539        "acsch", "angle", "arg", "asec", "asech", "asin",
540        "asinh", "atan", "atanh", "beta", "betainc",
541        "betaln", "bincoeff", "cbrt", "ceil", "conj", "cos",
542        "cosh", "cot", "coth", "csc", "csch", "erf", "erfc",
543        "erfcx", "erfinv", "exp", "finite", "fix", "floor",
544        "fmod", "gamma", "gammainc", "gammaln", "imag",
545        "isalnum", "isalpha", "isascii", "iscntrl",
546        "isdigit", "isfinite", "isgraph", "isinf",
547        "islower", "isna", "isnan", "isprint", "ispunct",
548        "isspace", "isupper", "isxdigit", "lcm", "lgamma",
549        "log", "lower", "mod", "real", "rem", "round",
550        "roundb", "sec", "sech", "sign", "sin", "sinh",
551        "sqrt", "tan", "tanh", "toascii", "tolower", "xor")
552
553    builtin_consts = (
554        "EDITOR", "EXEC_PATH", "I", "IMAGE_PATH", "NA",
555        "OCTAVE_HOME", "OCTAVE_VERSION", "PAGER",
556        "PAGER_FLAGS", "SEEK_CUR", "SEEK_END", "SEEK_SET",
557        "SIG", "S_ISBLK", "S_ISCHR", "S_ISDIR", "S_ISFIFO",
558        "S_ISLNK", "S_ISREG", "S_ISSOCK", "WCONTINUE",
559        "WCOREDUMP", "WEXITSTATUS", "WIFCONTINUED",
560        "WIFEXITED", "WIFSIGNALED", "WIFSTOPPED", "WNOHANG",
561        "WSTOPSIG", "WTERMSIG", "WUNTRACED")
562
563    tokens = {
564        'root': [
565            # We should look into multiline comments
566            (r'[%#].*$', Comment),
567            (r'^\s*function\b', Keyword, 'deffunc'),
568
569            # from 'iskeyword' on hg changeset 8cc154f45e37
570            (words((
571                '__FILE__', '__LINE__', 'break', 'case', 'catch', 'classdef', 'continue', 'do', 'else',
572                'elseif', 'end', 'end_try_catch', 'end_unwind_protect', 'endclassdef',
573                'endevents', 'endfor', 'endfunction', 'endif', 'endmethods', 'endproperties',
574                'endswitch', 'endwhile', 'events', 'for', 'function', 'get', 'global', 'if', 'methods',
575                'otherwise', 'persistent', 'properties', 'return', 'set', 'static', 'switch', 'try',
576                'until', 'unwind_protect', 'unwind_protect_cleanup', 'while'), suffix=r'\b'),
577             Keyword),
578
579            (words(builtin_kw + command_kw + function_kw + loadable_kw + mapping_kw,
580                   suffix=r'\b'),  Name.Builtin),
581
582            (words(builtin_consts, suffix=r'\b'), Name.Constant),
583
584            # operators in Octave but not Matlab:
585            (r'-=|!=|!|/=|--', Operator),
586            # operators:
587            (r'-|==|~=|<|>|<=|>=|&&|&|~|\|\|?', Operator),
588            # operators in Octave but not Matlab requiring escape for re:
589            (r'\*=|\+=|\^=|\/=|\\=|\*\*|\+\+|\.\*\*', Operator),
590            # operators requiring escape for re:
591            (r'\.\*|\*|\+|\.\^|\.\\|\.\/|\/|\\', Operator),
592
593
594            # punctuation:
595            (r'[\[\](){}:@.,]', Punctuation),
596            (r'=|:|;', Punctuation),
597
598            (r'"[^"]*"', String),
599
600            (r'(\d+\.\d*|\d*\.\d+)([eEf][+-]?[0-9]+)?', Number.Float),
601            (r'\d+[eEf][+-]?[0-9]+', Number.Float),
602            (r'\d+', Number.Integer),
603
604            # quote can be transpose, instead of string:
605            # (not great, but handles common cases...)
606            (r'(?<=[\w)\].])\'+', Operator),
607            (r'(?<![\w)\].])\'', String, 'string'),
608
609            (r'[a-zA-Z_]\w*', Name),
610            (r'.', Text),
611        ],
612        'string': [
613            (r"[^']*'", String, '#pop'),
614        ],
615        'deffunc': [
616            (r'(\s*)(?:(.+)(\s*)(=)(\s*))?(.+)(\()(.*)(\))(\s*)',
617             bygroups(Whitespace, Text, Whitespace, Punctuation,
618                      Whitespace, Name.Function, Punctuation, Text,
619                      Punctuation, Whitespace), '#pop'),
620            # function with no args
621            (r'(\s*)([a-zA-Z_]\w*)', bygroups(Text, Name.Function), '#pop'),
622        ],
623    }
624
625
626class ScilabLexer(RegexLexer):
627    """
628    For Scilab source code.
629
630    .. versionadded:: 1.5
631    """
632    name = 'Scilab'
633    aliases = ['scilab']
634    filenames = ['*.sci', '*.sce', '*.tst']
635    mimetypes = ['text/scilab']
636
637    tokens = {
638        'root': [
639            (r'//.*?$', Comment.Single),
640            (r'^\s*function\b', Keyword, 'deffunc'),
641
642            (words((
643                '__FILE__', '__LINE__', 'break', 'case', 'catch', 'classdef', 'continue', 'do', 'else',
644                'elseif', 'end', 'end_try_catch', 'end_unwind_protect', 'endclassdef',
645                'endevents', 'endfor', 'endfunction', 'endif', 'endmethods', 'endproperties',
646                'endswitch', 'endwhile', 'events', 'for', 'function', 'get', 'global', 'if', 'methods',
647                'otherwise', 'persistent', 'properties', 'return', 'set', 'static', 'switch', 'try',
648                'until', 'unwind_protect', 'unwind_protect_cleanup', 'while'), suffix=r'\b'),
649             Keyword),
650
651            (words(_scilab_builtins.functions_kw +
652                   _scilab_builtins.commands_kw +
653                   _scilab_builtins.macros_kw, suffix=r'\b'), Name.Builtin),
654
655            (words(_scilab_builtins.variables_kw, suffix=r'\b'), Name.Constant),
656
657            # operators:
658            (r'-|==|~=|<|>|<=|>=|&&|&|~|\|\|?', Operator),
659            # operators requiring escape for re:
660            (r'\.\*|\*|\+|\.\^|\.\\|\.\/|\/|\\', Operator),
661
662            # punctuation:
663            (r'[\[\](){}@.,=:;]', Punctuation),
664
665            (r'"[^"]*"', String),
666
667            # quote can be transpose, instead of string:
668            # (not great, but handles common cases...)
669            (r'(?<=[\w)\].])\'+', Operator),
670            (r'(?<![\w)\].])\'', String, 'string'),
671
672            (r'(\d+\.\d*|\d*\.\d+)([eEf][+-]?[0-9]+)?', Number.Float),
673            (r'\d+[eEf][+-]?[0-9]+', Number.Float),
674            (r'\d+', Number.Integer),
675
676            (r'[a-zA-Z_]\w*', Name),
677            (r'.', Text),
678        ],
679        'string': [
680            (r"[^']*'", String, '#pop'),
681            (r'.', String, '#pop'),
682        ],
683        'deffunc': [
684            (r'(\s*)(?:(.+)(\s*)(=)(\s*))?(.+)(\()(.*)(\))(\s*)',
685             bygroups(Whitespace, Text, Whitespace, Punctuation,
686                      Whitespace, Name.Function, Punctuation, Text,
687                      Punctuation, Whitespace), '#pop'),
688            # function with no args
689            (r'(\s*)([a-zA-Z_]\w*)', bygroups(Text, Name.Function), '#pop'),
690        ],
691    }
692