diff options
| author | Robert Dodier <robert.dodier@gmail.com> | 2021-09-04 07:18:28 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-09-04 16:18:28 +0200 |
| commit | 27553980170fcaa02bcd87a02a1954b0ec09242b (patch) | |
| tree | 8b8100d3bf1cf9e1305de40c0a2edf290370e7ea | |
| parent | 1df7fd71dad01c939da89d70947d2d606d7c21fa (diff) | |
| download | pygments-git-27553980170fcaa02bcd87a02a1954b0ec09242b.tar.gz | |
Lexer for new language Maxima (#1885)
* New lexer for Maxima computer algebra system
* New lexer class MaximaLexer
* Update _mapping.py to include Maxima lexer
* New test input file maxima/foo.mac
I find that the commands
$ python3 -m pygments -O full -f html -o /tmp/foo.html tests/examplefiles/maxima/foo.mac
$ python3 -m pygments -x -l pygments/lexers/maxima.py:MaximaLexer tests/examplefiles/maxima/foo.mac
both produce expected output.
* Commit output from pytest --update-goldens for Maxima example file
Commit output from pytest tests/examplefiles/maxima --update-goldens
as obtained by Cameron Smith.
* Rename output file for test of Maxima lexer.
* In Maxima lexer, capture content of comment
all at once, instead of capturing each character separately.
Update expected output for example input file, as produce by:
$ pytest tests/examplefiles/maxima --update-goldens
* In lexer for Maxima language, identify whitespace characters as such
instead of just calling them Text.
* In lexer for Maxima language, identify comma, semicolon, and dollar sign
as Punctuation instead of Text.
* In lexer for Maxima language, cut encoding comment, and put in license statement.
* In lexer for Maxima language, identify keywords and other fixed strings such as operators
via the words function, instead of a long regex with alternation.
Incidentally update the example output, for which one symbol
(namely "done") has changed classification.
* In lexer for Maxima language, include additional test input and update output accordingly.
* In lexer for Maxima language, relax pattern for integers,
so integers are more accurately identified.
Update test example output accordingly.
* In lexer for Maxima language, adjust pattern for float numbers.
Include additional test input for floats and update expected output.
* In lexer for Maxima language, define analyse_text function.
* In lexer for Maxima language, correct errors identified by make check
(1) adjust package name underline
(2) put in copyright notice
Co-authored-by: Robert Dodier <robert_dodier@users.sourceforge.net>
| -rw-r--r-- | pygments/lexers/_mapping.py | 1 | ||||
| -rw-r--r-- | pygments/lexers/maxima.py | 82 | ||||
| -rw-r--r-- | tests/examplefiles/maxima/foo.mac | 40 | ||||
| -rw-r--r-- | tests/examplefiles/maxima/foo.mac.output | 481 |
4 files changed, 604 insertions, 0 deletions
diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py index 24e3668d..2ad7467e 100644 --- a/pygments/lexers/_mapping.py +++ b/pygments/lexers/_mapping.py @@ -286,6 +286,7 @@ LEXERS = { 'MathematicaLexer': ('pygments.lexers.algebra', 'Mathematica', ('mathematica', 'mma', 'nb'), ('*.nb', '*.cdf', '*.nbp', '*.ma'), ('application/mathematica', 'application/vnd.wolfram.mathematica', 'application/vnd.wolfram.mathematica.package', 'application/vnd.wolfram.cdf')), 'MatlabLexer': ('pygments.lexers.matlab', 'Matlab', ('matlab',), ('*.m',), ('text/matlab',)), 'MatlabSessionLexer': ('pygments.lexers.matlab', 'Matlab session', ('matlabsession',), (), ()), + 'MaximaLexer': ('pygments.lexers.maxima', 'Maxima', ('maxima', 'macsyma'), ('*.mac', '*.max'), ()), 'MesonLexer': ('pygments.lexers.meson', 'Meson', ('meson', 'meson.build'), ('meson.build', 'meson_options.txt'), ('text/x-meson',)), 'MiniDLexer': ('pygments.lexers.d', 'MiniD', ('minid',), (), ('text/x-minidsrc',)), 'MiniScriptLexer': ('pygments.lexers.scripting', 'MiniScript', ('miniscript', 'ms'), ('*.ms',), ('text/x-minicript', 'application/x-miniscript')), diff --git a/pygments/lexers/maxima.py b/pygments/lexers/maxima.py new file mode 100644 index 00000000..4c76df36 --- /dev/null +++ b/pygments/lexers/maxima.py @@ -0,0 +1,82 @@ +""" + pygments.lexers.maxima + ~~~~~~~~~~~~~~~~~~~~~~ + + Lexer for the computer algebra system Maxima. + + Derived from pygments/lexers/algebra.py. + + :copyright: Copyright 2006-2021 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.lexer import RegexLexer, bygroups, words +from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ + Number, Punctuation + +__all__ = ['MaximaLexer'] + +class MaximaLexer(RegexLexer): + """ + A `Maxima <http://maxima.sourceforge.net>`_ lexer. + Derived from pygments.lexers.MuPADLexer. + """ + name = 'Maxima' + aliases = ['maxima', 'macsyma'] + filenames = ['*.mac', '*.max'] + + keywords = ('if', 'then', 'else', 'elseif', + 'do', 'while', 'repeat', 'until', + 'for', 'from', 'to', 'downto', 'step', 'thru') + + constants = ('%pi', '%e', '%phi', '%gamma', '%i', + 'und', 'ind', 'infinity', 'inf', 'minf', + 'true', 'false', 'unknown', 'done') + + operators = (r'.', r':', r'=', r'#', + r'+', r'-', r'*', r'/', r'^', + r'@', r'>', r'<', r'|', r'!', r"'") + + operator_words = ('and', 'or', 'not') + + tokens = { + 'root': [ + (r'/\*', Comment.Multiline, 'comment'), + (r'"(?:[^"\\]|\\.)*"', String), + (r'\(|\)|\[|\]|\{|\}', Punctuation), + (r'[,;$]', Punctuation), + (words (constants), Name.Constant), + (words (keywords), Keyword), + (words (operators), Operator), + (words (operator_words), Operator.Word), + (r'''(?x) + ((?:[a-zA-Z_#][\w#]*|`[^`]*`) + (?:::[a-zA-Z_#][\w#]*|`[^`]*`)*)(\s*)([(])''', + bygroups(Name.Function, Text.Whitespace, Punctuation)), + (r'''(?x) + (?:[a-zA-Z_#%][\w#%]*|`[^`]*`) + (?:::[a-zA-Z_#%][\w#%]*|`[^`]*`)*''', Name.Variable), + (r'[-+]?(\d*\.\d+([bdefls][-+]?\d+)?|\d+(\.\d*)?[bdefls][-+]?\d+)', Number.Float), + (r'[-+]?\d+', Number.Integer), + (r'\s+', Text.Whitespace), + (r'.', Text) + ], + 'comment': [ + (r'[^*/]+', Comment.Multiline), + (r'/\*', Comment.Multiline, '#push'), + (r'\*/', Comment.Multiline, '#pop'), + (r'[*/]', Comment.Multiline) + ] + } + + def analyse_text (text): + strength = 0.0 + # Input expression terminator. + if re.search (r'\$\s*$', text, re.MULTILINE): + strength += 0.05 + # Function definition operator. + if ':=' in text: + strength += 0.02 + return strength diff --git a/tests/examplefiles/maxima/foo.mac b/tests/examplefiles/maxima/foo.mac new file mode 100644 index 00000000..f3b1060f --- /dev/null +++ b/tests/examplefiles/maxima/foo.mac @@ -0,0 +1,40 @@ +/* SF bug #3826: "limit returns temp variable expression" */ + +(kill (q, a, x), + ctxt: newcontext (), + assume (q > 0), + limit(x^q/(a*x^q- 1),x,inf)); +'limit(1/(a- 1/x^q),x,inf); + +tlimit(x^q/(a*x^q- 1),x,inf); +'limit(1/(a- 1/x^q),x,inf); + +(assume (a > 0), + declare (q, integer), + limit(x^q/(a*x^q- 1),x,inf)); +1/a; + +(remove (q, integer), + declare (q, noninteger), + limit(x^q/(a*x^q- 1),x,inf)); +1/a; + +(remove (q, noninteger), + killcontext (ctxt)); +done; + +/* additional code to test lexer */ + +xyz: expand ((u - h*v)^4); +print ("foo.mac: xyz =", xyz); +'integrate (xyz, u, minf, inf); +LL: [1234, 5678, 9012]; +for x:2 thru n - 3 + do while (L: readline (S)) # false + do push (L, LL); +if abc < 123 and (def > -123 or zyx < 234) + then X[k]: Y[j, k]*%pi - gamma; + +print ("foo.mac: test different kinds of floats") $ +blurf (a, b, c) := + mumble (a*123.45/b, b*0.12345e6/c, c*1.2345b-8/a)) $ diff --git a/tests/examplefiles/maxima/foo.mac.output b/tests/examplefiles/maxima/foo.mac.output new file mode 100644 index 00000000..e63fda83 --- /dev/null +++ b/tests/examplefiles/maxima/foo.mac.output @@ -0,0 +1,481 @@ +'/*' Comment.Multiline +' SF bug #3826: "limit returns temp variable expression" ' Comment.Multiline +'*/' Comment.Multiline +'\n\n' Text.Whitespace + +'(' Punctuation +'kill' Name.Function +' ' Text.Whitespace +'(' Punctuation +'q' Name.Variable +',' Punctuation +' ' Text.Whitespace +'a' Name.Variable +',' Punctuation +' ' Text.Whitespace +'x' Name.Variable +')' Punctuation +',' Punctuation +'\n ' Text.Whitespace +'ctxt' Name.Variable +':' Operator +' ' Text.Whitespace +'newcontext' Name.Function +' ' Text.Whitespace +'(' Punctuation +')' Punctuation +',' Punctuation +'\n ' Text.Whitespace +'assume' Name.Function +' ' Text.Whitespace +'(' Punctuation +'q' Name.Variable +' ' Text.Whitespace +'>' Operator +' ' Text.Whitespace +'0' Literal.Number.Integer +')' Punctuation +',' Punctuation +'\n ' Text.Whitespace +'limit' Name.Function +'(' Punctuation +'x' Name.Variable +'^' Operator +'q' Name.Variable +'/' Operator +'(' Punctuation +'a' Name.Variable +'*' Operator +'x' Name.Variable +'^' Operator +'q' Name.Variable +'-' Operator +' ' Text.Whitespace +'1' Literal.Number.Integer +')' Punctuation +',' Punctuation +'x' Name.Variable +',' Punctuation +'inf' Name.Constant +')' Punctuation +')' Punctuation +';' Punctuation +'\n' Text.Whitespace + +"'" Operator +'limit' Name.Function +'(' Punctuation +'1' Literal.Number.Integer +'/' Operator +'(' Punctuation +'a' Name.Variable +'-' Operator +' ' Text.Whitespace +'1' Literal.Number.Integer +'/' Operator +'x' Name.Variable +'^' Operator +'q' Name.Variable +')' Punctuation +',' Punctuation +'x' Name.Variable +',' Punctuation +'inf' Name.Constant +')' Punctuation +';' Punctuation +'\n\n' Text.Whitespace + +'tlimit' Name.Function +'(' Punctuation +'x' Name.Variable +'^' Operator +'q' Name.Variable +'/' Operator +'(' Punctuation +'a' Name.Variable +'*' Operator +'x' Name.Variable +'^' Operator +'q' Name.Variable +'-' Operator +' ' Text.Whitespace +'1' Literal.Number.Integer +')' Punctuation +',' Punctuation +'x' Name.Variable +',' Punctuation +'inf' Name.Constant +')' Punctuation +';' Punctuation +'\n' Text.Whitespace + +"'" Operator +'limit' Name.Function +'(' Punctuation +'1' Literal.Number.Integer +'/' Operator +'(' Punctuation +'a' Name.Variable +'-' Operator +' ' Text.Whitespace +'1' Literal.Number.Integer +'/' Operator +'x' Name.Variable +'^' Operator +'q' Name.Variable +')' Punctuation +',' Punctuation +'x' Name.Variable +',' Punctuation +'inf' Name.Constant +')' Punctuation +';' Punctuation +'\n\n' Text.Whitespace + +'(' Punctuation +'assume' Name.Function +' ' Text.Whitespace +'(' Punctuation +'a' Name.Variable +' ' Text.Whitespace +'>' Operator +' ' Text.Whitespace +'0' Literal.Number.Integer +')' Punctuation +',' Punctuation +'\n ' Text.Whitespace +'declare' Name.Function +' ' Text.Whitespace +'(' Punctuation +'q' Name.Variable +',' Punctuation +' ' Text.Whitespace +'integer' Name.Variable +')' Punctuation +',' Punctuation +'\n ' Text.Whitespace +'limit' Name.Function +'(' Punctuation +'x' Name.Variable +'^' Operator +'q' Name.Variable +'/' Operator +'(' Punctuation +'a' Name.Variable +'*' Operator +'x' Name.Variable +'^' Operator +'q' Name.Variable +'-' Operator +' ' Text.Whitespace +'1' Literal.Number.Integer +')' Punctuation +',' Punctuation +'x' Name.Variable +',' Punctuation +'inf' Name.Constant +')' Punctuation +')' Punctuation +';' Punctuation +'\n' Text.Whitespace + +'1' Literal.Number.Integer +'/' Operator +'a' Name.Variable +';' Punctuation +'\n\n' Text.Whitespace + +'(' Punctuation +'remove' Name.Function +' ' Text.Whitespace +'(' Punctuation +'q' Name.Variable +',' Punctuation +' ' Text.Whitespace +'integer' Name.Variable +')' Punctuation +',' Punctuation +'\n ' Text.Whitespace +'declare' Name.Function +' ' Text.Whitespace +'(' Punctuation +'q' Name.Variable +',' Punctuation +' ' Text.Whitespace +'noninteger' Name.Variable +')' Punctuation +',' Punctuation +'\n ' Text.Whitespace +'limit' Name.Function +'(' Punctuation +'x' Name.Variable +'^' Operator +'q' Name.Variable +'/' Operator +'(' Punctuation +'a' Name.Variable +'*' Operator +'x' Name.Variable +'^' Operator +'q' Name.Variable +'-' Operator +' ' Text.Whitespace +'1' Literal.Number.Integer +')' Punctuation +',' Punctuation +'x' Name.Variable +',' Punctuation +'inf' Name.Constant +')' Punctuation +')' Punctuation +';' Punctuation +'\n' Text.Whitespace + +'1' Literal.Number.Integer +'/' Operator +'a' Name.Variable +';' Punctuation +'\n\n' Text.Whitespace + +'(' Punctuation +'remove' Name.Function +' ' Text.Whitespace +'(' Punctuation +'q' Name.Variable +',' Punctuation +' ' Text.Whitespace +'noninteger' Name.Variable +')' Punctuation +',' Punctuation +'\n ' Text.Whitespace +'killcontext' Name.Function +' ' Text.Whitespace +'(' Punctuation +'ctxt' Name.Variable +')' Punctuation +')' Punctuation +';' Punctuation +'\n' Text.Whitespace + +'done' Name.Constant +';' Punctuation +'\n\n' Text.Whitespace + +'/*' Comment.Multiline +' additional code to test lexer ' Comment.Multiline +'*/' Comment.Multiline +'\n\n' Text.Whitespace + +'xyz' Name.Variable +':' Operator +' ' Text.Whitespace +'expand' Name.Function +' ' Text.Whitespace +'(' Punctuation +'(' Punctuation +'u' Name.Variable +' ' Text.Whitespace +'-' Operator +' ' Text.Whitespace +'h' Name.Variable +'*' Operator +'v' Name.Variable +')' Punctuation +'^' Operator +'4' Literal.Number.Integer +')' Punctuation +';' Punctuation +'\n' Text.Whitespace + +'print' Name.Function +' ' Text.Whitespace +'(' Punctuation +'"foo.mac: xyz ="' Literal.String +',' Punctuation +' ' Text.Whitespace +'xyz' Name.Variable +')' Punctuation +';' Punctuation +'\n' Text.Whitespace + +"'" Operator +'integrate' Name.Function +' ' Text.Whitespace +'(' Punctuation +'xyz' Name.Variable +',' Punctuation +' ' Text.Whitespace +'u' Name.Variable +',' Punctuation +' ' Text.Whitespace +'minf' Name.Constant +',' Punctuation +' ' Text.Whitespace +'inf' Name.Constant +')' Punctuation +';' Punctuation +'\n' Text.Whitespace + +'LL' Name.Variable +':' Operator +' ' Text.Whitespace +'[' Punctuation +'1234' Literal.Number.Integer +',' Punctuation +' ' Text.Whitespace +'5678' Literal.Number.Integer +',' Punctuation +' ' Text.Whitespace +'9012' Literal.Number.Integer +']' Punctuation +';' Punctuation +'\n' Text.Whitespace + +'for' Keyword +' ' Text.Whitespace +'x' Name.Variable +':' Operator +'2' Literal.Number.Integer +' ' Text.Whitespace +'thru' Keyword +' ' Text.Whitespace +'n' Name.Variable +' ' Text.Whitespace +'-' Operator +' ' Text.Whitespace +'3' Literal.Number.Integer +'\n ' Text.Whitespace +'do' Keyword +' ' Text.Whitespace +'while' Keyword +' ' Text.Whitespace +'(' Punctuation +'L' Name.Variable +':' Operator +' ' Text.Whitespace +'readline' Name.Function +' ' Text.Whitespace +'(' Punctuation +'S' Name.Variable +')' Punctuation +')' Punctuation +' ' Text.Whitespace +'#' Operator +' ' Text.Whitespace +'false' Name.Constant +'\n ' Text.Whitespace +'do' Keyword +' ' Text.Whitespace +'push' Name.Function +' ' Text.Whitespace +'(' Punctuation +'L' Name.Variable +',' Punctuation +' ' Text.Whitespace +'LL' Name.Variable +')' Punctuation +';' Punctuation +'\n' Text.Whitespace + +'if' Keyword +' ' Text.Whitespace +'abc' Name.Variable +' ' Text.Whitespace +'<' Operator +' ' Text.Whitespace +'123' Literal.Number.Integer +' ' Text.Whitespace +'and' Operator.Word +' ' Text.Whitespace +'(' Punctuation +'def' Name.Variable +' ' Text.Whitespace +'>' Operator +' ' Text.Whitespace +'-' Operator +'123' Literal.Number.Integer +' ' Text.Whitespace +'or' Operator.Word +' ' Text.Whitespace +'zyx' Name.Variable +' ' Text.Whitespace +'<' Operator +' ' Text.Whitespace +'234' Literal.Number.Integer +')' Punctuation +'\n ' Text.Whitespace +'then' Keyword +' ' Text.Whitespace +'X' Name.Variable +'[' Punctuation +'k' Name.Variable +']' Punctuation +':' Operator +' ' Text.Whitespace +'Y' Name.Variable +'[' Punctuation +'j' Name.Variable +',' Punctuation +' ' Text.Whitespace +'k' Name.Variable +']' Punctuation +'*' Operator +'%pi' Name.Constant +' ' Text.Whitespace +'-' Operator +' ' Text.Whitespace +'gamma' Name.Variable +';' Punctuation +'\n\n' Text.Whitespace + +'print' Name.Function +' ' Text.Whitespace +'(' Punctuation +'"foo.mac: test different kinds of floats"' Literal.String +')' Punctuation +' ' Text.Whitespace +'$' Punctuation +'\n' Text.Whitespace + +'blurf' Name.Function +' ' Text.Whitespace +'(' Punctuation +'a' Name.Variable +',' Punctuation +' ' Text.Whitespace +'b' Name.Variable +',' Punctuation +' ' Text.Whitespace +'c' Name.Variable +')' Punctuation +' ' Text.Whitespace +':' Operator +'=' Operator +'\n ' Text.Whitespace +'mumble' Name.Function +' ' Text.Whitespace +'(' Punctuation +'a' Name.Variable +'*' Operator +'123.45' Literal.Number.Float +'/' Operator +'b' Name.Variable +',' Punctuation +' ' Text.Whitespace +'b' Name.Variable +'*' Operator +'0.12345e6' Literal.Number.Float +'/' Operator +'c' Name.Variable +',' Punctuation +' ' Text.Whitespace +'c' Name.Variable +'*' Operator +'1.2345b-8' Literal.Number.Float +'/' Operator +'a' Name.Variable +')' Punctuation +')' Punctuation +' ' Text.Whitespace +'$' Punctuation +'\n' Text.Whitespace |
