|
""" |
|
pygments.lexers.julia |
|
~~~~~~~~~~~~~~~~~~~~~ |
|
|
|
Lexers for the Julia language. |
|
|
|
:copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. |
|
:license: BSD, see LICENSE for details. |
|
""" |
|
|
|
from pygments.lexer import Lexer, RegexLexer, bygroups, do_insertions, \ |
|
words, include |
|
from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ |
|
Number, Punctuation, Generic, Whitespace |
|
from pygments.util import shebang_matches |
|
from pygments.lexers._julia_builtins import OPERATORS_LIST, DOTTED_OPERATORS_LIST, \ |
|
KEYWORD_LIST, BUILTIN_LIST, LITERAL_LIST |
|
|
|
__all__ = ['JuliaLexer', 'JuliaConsoleLexer'] |
|
|
|
|
|
allowed_variable = \ |
|
'(?:[a-zA-Z_\u00A1-\U0010ffff][a-zA-Z_0-9!\u00A1-\U0010ffff]*)' |
|
|
|
operator_suffixes = r'[²³¹ʰʲʳʷʸˡˢˣᴬᴮᴰᴱᴳᴴᴵᴶᴷᴸᴹᴺᴼᴾᴿᵀᵁᵂᵃᵇᵈᵉᵍᵏᵐᵒᵖᵗᵘᵛᵝᵞᵟᵠᵡᵢᵣᵤᵥᵦᵧᵨᵩᵪᶜᶠᶥᶦᶫᶰᶸᶻᶿ′″‴‵‶‷⁗⁰ⁱ⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ⁿ₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎ₐₑₒₓₕₖₗₘₙₚₛₜⱼⱽ]*' |
|
|
|
class JuliaLexer(RegexLexer): |
|
""" |
|
For Julia source code. |
|
""" |
|
|
|
name = 'Julia' |
|
url = 'https://julialang.org/' |
|
aliases = ['julia', 'jl'] |
|
filenames = ['*.jl'] |
|
mimetypes = ['text/x-julia', 'application/x-julia'] |
|
version_added = '1.6' |
|
|
|
tokens = { |
|
'root': [ |
|
(r'\n', Whitespace), |
|
(r'[^\S\n]+', Whitespace), |
|
(r'#=', Comment.Multiline, "blockcomment"), |
|
(r'#.*$', Comment), |
|
(r'[\[\](),;]', Punctuation), |
|
|
|
|
|
|
|
(r'(' + allowed_variable + r')(\s*)(:)(' + allowed_variable + ')', |
|
bygroups(Name, Whitespace, Operator, Name)), |
|
|
|
|
|
(r'(?<![\]):<>\d.])(:' + allowed_variable + ')', String.Symbol), |
|
|
|
|
|
(r'(?<=::)(\s*)(' + allowed_variable + r')\b(?![(\[])', |
|
bygroups(Whitespace, Keyword.Type)), |
|
|
|
|
|
('(' + allowed_variable + r')(\s*)([<>]:)(\s*)(' + allowed_variable + r')\b(?![(\[])', |
|
bygroups(Keyword.Type, Whitespace, Operator, Whitespace, Keyword.Type)), |
|
|
|
(r'([<>]:)(\s*)(' + allowed_variable + r')\b(?![(\[])', |
|
bygroups(Operator, Whitespace, Keyword.Type)), |
|
|
|
(r'\b(' + allowed_variable + r')(\s*)([<>]:)', |
|
bygroups(Keyword.Type, Whitespace, Operator)), |
|
|
|
|
|
|
|
|
|
(words([*OPERATORS_LIST, *DOTTED_OPERATORS_LIST], |
|
suffix=operator_suffixes), Operator), |
|
(words(['.' + o for o in DOTTED_OPERATORS_LIST], |
|
suffix=operator_suffixes), Operator), |
|
(words(['...', '..']), Operator), |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(r"'(\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,3}|\\u[a-fA-F0-9]{1,4}|" |
|
r"\\U[a-fA-F0-9]{1,6}|[^\\\'\n])'", String.Char), |
|
|
|
|
|
(r'(?<=[.\w)\]])(\'' + operator_suffixes + ')+', Operator), |
|
|
|
|
|
(r'(raw)(""")', bygroups(String.Affix, String), 'tqrawstring'), |
|
(r'(raw)(")', bygroups(String.Affix, String), 'rawstring'), |
|
|
|
(r'(r)(""")', bygroups(String.Affix, String.Regex), 'tqregex'), |
|
(r'(r)(")', bygroups(String.Affix, String.Regex), 'regex'), |
|
|
|
(r'(' + allowed_variable + ')?(""")', |
|
bygroups(String.Affix, String), 'tqstring'), |
|
(r'(' + allowed_variable + ')?(")', |
|
bygroups(String.Affix, String), 'string'), |
|
|
|
|
|
(r'(' + allowed_variable + ')?(```)', |
|
bygroups(String.Affix, String.Backtick), 'tqcommand'), |
|
(r'(' + allowed_variable + ')?(`)', |
|
bygroups(String.Affix, String.Backtick), 'command'), |
|
|
|
|
|
|
|
('(' + allowed_variable + r')(\{)', |
|
bygroups(Keyword.Type, Punctuation), 'curly'), |
|
|
|
(r'(where)(\s+)(' + allowed_variable + ')', |
|
bygroups(Keyword, Whitespace, Keyword.Type)), |
|
|
|
(r'(\{)', Punctuation, 'curly'), |
|
|
|
(r'(abstract|primitive)([ \t]+)(type\b)([\s()]+)(' + |
|
allowed_variable + r')', |
|
bygroups(Keyword, Whitespace, Keyword, Text, Keyword.Type)), |
|
(r'(mutable(?=[ \t]))?([ \t]+)?(struct\b)([\s()]+)(' + |
|
allowed_variable + r')', |
|
bygroups(Keyword, Whitespace, Keyword, Text, Keyword.Type)), |
|
|
|
|
|
(r'@' + allowed_variable, Name.Decorator), |
|
(words([*OPERATORS_LIST, '..', '.', *DOTTED_OPERATORS_LIST], |
|
prefix='@', suffix=operator_suffixes), Name.Decorator), |
|
|
|
|
|
(words(KEYWORD_LIST, suffix=r'\b'), Keyword), |
|
|
|
(words(BUILTIN_LIST, suffix=r'\b'), Keyword.Type), |
|
|
|
(words(LITERAL_LIST, suffix=r'\b'), Name.Builtin), |
|
|
|
|
|
(allowed_variable, Name), |
|
|
|
|
|
(r'(\d+((_\d+)+)?\.(?!\.)(\d+((_\d+)+)?)?|\.\d+((_\d+)+)?)([eEf][+-]?[0-9]+)?', Number.Float), |
|
(r'\d+((_\d+)+)?[eEf][+-]?[0-9]+', Number.Float), |
|
(r'0x[a-fA-F0-9]+((_[a-fA-F0-9]+)+)?(\.([a-fA-F0-9]+((_[a-fA-F0-9]+)+)?)?)?p[+-]?\d+', Number.Float), |
|
(r'0b[01]+((_[01]+)+)?', Number.Bin), |
|
(r'0o[0-7]+((_[0-7]+)+)?', Number.Oct), |
|
(r'0x[a-fA-F0-9]+((_[a-fA-F0-9]+)+)?', Number.Hex), |
|
(r'\d+((_\d+)+)?', Number.Integer), |
|
|
|
|
|
(words(['.']), Operator), |
|
], |
|
|
|
"blockcomment": [ |
|
(r'[^=#]', Comment.Multiline), |
|
(r'#=', Comment.Multiline, '#push'), |
|
(r'=#', Comment.Multiline, '#pop'), |
|
(r'[=#]', Comment.Multiline), |
|
], |
|
|
|
'curly': [ |
|
(r'\{', Punctuation, '#push'), |
|
(r'\}', Punctuation, '#pop'), |
|
(allowed_variable, Keyword.Type), |
|
include('root'), |
|
], |
|
|
|
'tqrawstring': [ |
|
(r'"""', String, '#pop'), |
|
(r'([^"]|"[^"][^"])+', String), |
|
], |
|
'rawstring': [ |
|
(r'"', String, '#pop'), |
|
(r'\\"', String.Escape), |
|
(r'([^"\\]|\\[^"])+', String), |
|
], |
|
|
|
|
|
|
|
|
|
'interp': [ |
|
(r'\$' + allowed_variable, String.Interpol), |
|
(r'(\$)(\()', bygroups(String.Interpol, Punctuation), 'in-intp'), |
|
], |
|
'in-intp': [ |
|
(r'\(', Punctuation, '#push'), |
|
(r'\)', Punctuation, '#pop'), |
|
include('root'), |
|
], |
|
|
|
'string': [ |
|
(r'(")(' + allowed_variable + r'|\d+)?', |
|
bygroups(String, String.Affix), '#pop'), |
|
|
|
(r'\\([\\"\'$nrbtfav]|(x|u|U)[a-fA-F0-9]+|\d+)', String.Escape), |
|
include('interp'), |
|
|
|
(r'%[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?[hlL]?[E-GXc-giorsux%]', |
|
String.Interpol), |
|
(r'[^"$%\\]+', String), |
|
(r'.', String), |
|
], |
|
'tqstring': [ |
|
(r'(""")(' + allowed_variable + r'|\d+)?', |
|
bygroups(String, String.Affix), '#pop'), |
|
(r'\\([\\"\'$nrbtfav]|(x|u|U)[a-fA-F0-9]+|\d+)', String.Escape), |
|
include('interp'), |
|
(r'[^"$%\\]+', String), |
|
(r'.', String), |
|
], |
|
|
|
'regex': [ |
|
(r'(")([imsxa]*)?', bygroups(String.Regex, String.Affix), '#pop'), |
|
(r'\\"', String.Regex), |
|
(r'[^\\"]+', String.Regex), |
|
], |
|
|
|
'tqregex': [ |
|
(r'(""")([imsxa]*)?', bygroups(String.Regex, String.Affix), '#pop'), |
|
(r'[^"]+', String.Regex), |
|
], |
|
|
|
'command': [ |
|
(r'(`)(' + allowed_variable + r'|\d+)?', |
|
bygroups(String.Backtick, String.Affix), '#pop'), |
|
(r'\\[`$]', String.Escape), |
|
include('interp'), |
|
(r'[^\\`$]+', String.Backtick), |
|
(r'.', String.Backtick), |
|
], |
|
'tqcommand': [ |
|
(r'(```)(' + allowed_variable + r'|\d+)?', |
|
bygroups(String.Backtick, String.Affix), '#pop'), |
|
(r'\\\$', String.Escape), |
|
include('interp'), |
|
(r'[^\\`$]+', String.Backtick), |
|
(r'.', String.Backtick), |
|
], |
|
} |
|
|
|
def analyse_text(text): |
|
return shebang_matches(text, r'julia') |
|
|
|
|
|
class JuliaConsoleLexer(Lexer): |
|
""" |
|
For Julia console sessions. Modeled after MatlabSessionLexer. |
|
""" |
|
name = 'Julia console' |
|
aliases = ['jlcon', 'julia-repl'] |
|
url = 'https://julialang.org/' |
|
version_added = '1.6' |
|
_example = "jlcon/console" |
|
|
|
def get_tokens_unprocessed(self, text): |
|
jllexer = JuliaLexer(**self.options) |
|
start = 0 |
|
curcode = '' |
|
insertions = [] |
|
output = False |
|
error = False |
|
|
|
for line in text.splitlines(keepends=True): |
|
if line.startswith('julia>'): |
|
insertions.append((len(curcode), [(0, Generic.Prompt, line[:6])])) |
|
curcode += line[6:] |
|
output = False |
|
error = False |
|
elif line.startswith('help?>') or line.startswith('shell>'): |
|
yield start, Generic.Prompt, line[:6] |
|
yield start + 6, Text, line[6:] |
|
output = False |
|
error = False |
|
elif line.startswith(' ') and not output: |
|
insertions.append((len(curcode), [(0, Whitespace, line[:6])])) |
|
curcode += line[6:] |
|
else: |
|
if curcode: |
|
yield from do_insertions( |
|
insertions, jllexer.get_tokens_unprocessed(curcode)) |
|
curcode = '' |
|
insertions = [] |
|
if line.startswith('ERROR: ') or error: |
|
yield start, Generic.Error, line |
|
error = True |
|
else: |
|
yield start, Generic.Output, line |
|
output = True |
|
start += len(line) |
|
|
|
if curcode: |
|
yield from do_insertions( |
|
insertions, jllexer.get_tokens_unprocessed(curcode)) |
|
|