1# -*- coding: utf-8 -*-
2"""
3    pygments.lexers.scripting
4    ~~~~~~~~~~~~~~~~~~~~~~~~~
5
6    Lexer for scripting and embedded languages.
7
8    :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS.
9    :license: BSD, see LICENSE for details.
10"""
11
12import re
13
14from pygments.lexer import RegexLexer, include, bygroups, default, combined, \
15    words
16from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
17    Number, Punctuation, Error, Whitespace, Other
18from pygments.util import get_bool_opt, get_list_opt
19
20__all__ = ['LuaLexer', 'MoonScriptLexer', 'ChaiscriptLexer', 'LSLLexer',
21           'AppleScriptLexer', 'RexxLexer', 'MOOCodeLexer', 'HybrisLexer',
22           'EasytrieveLexer', 'JclLexer', 'MiniScriptLexer']
23
24
25class LuaLexer(RegexLexer):
26    """
27    For `Lua <http://www.lua.org>`_ source code.
28
29    Additional options accepted:
30
31    `func_name_highlighting`
32        If given and ``True``, highlight builtin function names
33        (default: ``True``).
34    `disabled_modules`
35        If given, must be a list of module names whose function names
36        should not be highlighted. By default all modules are highlighted.
37
38        To get a list of allowed modules have a look into the
39        `_lua_builtins` module:
40
41        .. sourcecode:: pycon
42
43            >>> from pygments.lexers._lua_builtins import MODULES
44            >>> MODULES.keys()
45            ['string', 'coroutine', 'modules', 'io', 'basic', ...]
46    """
47
48    name = 'Lua'
49    aliases = ['lua']
50    filenames = ['*.lua', '*.wlua']
51    mimetypes = ['text/x-lua', 'application/x-lua']
52
53    _comment_multiline = r'(?:--\[(?P<level>=*)\[[\w\W]*?\](?P=level)\])'
54    _comment_single = r'(?:--.*$)'
55    _space = r'(?:\s+)'
56    _s = r'(?:%s|%s|%s)' % (_comment_multiline, _comment_single, _space)
57    _name = r'(?:[^\W\d]\w*)'
58
59    tokens = {
60        'root': [
61            # Lua allows a file to start with a shebang.
62            (r'#!.*', Comment.Preproc),
63            default('base'),
64        ],
65        'ws': [
66            (_comment_multiline, Comment.Multiline),
67            (_comment_single, Comment.Single),
68            (_space, Text),
69        ],
70        'base': [
71            include('ws'),
72
73            (r'(?i)0x[\da-f]*(\.[\da-f]*)?(p[+-]?\d+)?', Number.Hex),
74            (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float),
75            (r'(?i)\d+e[+-]?\d+', Number.Float),
76            (r'\d+', Number.Integer),
77
78            # multiline strings
79            (r'(?s)\[(=*)\[.*?\]\1\]', String),
80
81            (r'::', Punctuation, 'label'),
82            (r'\.{3}', Punctuation),
83            (r'[=<>|~&+\-*/%#^]+|\.\.', Operator),
84            (r'[\[\]{}().,:;]', Punctuation),
85            (r'(and|or|not)\b', Operator.Word),
86
87            ('(break|do|else|elseif|end|for|if|in|repeat|return|then|until|'
88             r'while)\b', Keyword.Reserved),
89            (r'goto\b', Keyword.Reserved, 'goto'),
90            (r'(local)\b', Keyword.Declaration),
91            (r'(true|false|nil)\b', Keyword.Constant),
92
93            (r'(function)\b', Keyword.Reserved, 'funcname'),
94
95            (r'[A-Za-z_]\w*(\.[A-Za-z_]\w*)?', Name),
96
97            ("'", String.Single, combined('stringescape', 'sqs')),
98            ('"', String.Double, combined('stringescape', 'dqs'))
99        ],
100
101        'funcname': [
102            include('ws'),
103            (r'[.:]', Punctuation),
104            (r'%s(?=%s*[.:])' % (_name, _s), Name.Class),
105            (_name, Name.Function, '#pop'),
106            # inline function
107            (r'\(', Punctuation, '#pop'),
108        ],
109
110        'goto': [
111            include('ws'),
112            (_name, Name.Label, '#pop'),
113        ],
114
115        'label': [
116            include('ws'),
117            (r'::', Punctuation, '#pop'),
118            (_name, Name.Label),
119        ],
120
121        'stringescape': [
122            (r'\\([abfnrtv\\"\']|[\r\n]{1,2}|z\s*|x[0-9a-fA-F]{2}|\d{1,3}|'
123             r'u\{[0-9a-fA-F]+\})', String.Escape),
124        ],
125
126        'sqs': [
127            (r"'", String.Single, '#pop'),
128            (r"[^\\']+", String.Single),
129        ],
130
131        'dqs': [
132            (r'"', String.Double, '#pop'),
133            (r'[^\\"]+', String.Double),
134        ]
135    }
136
137    def __init__(self, **options):
138        self.func_name_highlighting = get_bool_opt(
139            options, 'func_name_highlighting', True)
140        self.disabled_modules = get_list_opt(options, 'disabled_modules', [])
141
142        self._functions = set()
143        if self.func_name_highlighting:
144            from pygments.lexers._lua_builtins import MODULES
145            for mod, func in MODULES.items():
146                if mod not in self.disabled_modules:
147                    self._functions.update(func)
148        RegexLexer.__init__(self, **options)
149
150    def get_tokens_unprocessed(self, text):
151        for index, token, value in \
152                RegexLexer.get_tokens_unprocessed(self, text):
153            if token is Name:
154                if value in self._functions:
155                    yield index, Name.Builtin, value
156                    continue
157                elif '.' in value:
158                    a, b = value.split('.')
159                    yield index, Name, a
160                    yield index + len(a), Punctuation, '.'
161                    yield index + len(a) + 1, Name, b
162                    continue
163            yield index, token, value
164
165class MoonScriptLexer(LuaLexer):
166    """
167    For `MoonScript <http://moonscript.org>`_ source code.
168
169    .. versionadded:: 1.5
170    """
171
172    name = "MoonScript"
173    aliases = ["moon", "moonscript"]
174    filenames = ["*.moon"]
175    mimetypes = ['text/x-moonscript', 'application/x-moonscript']
176
177    tokens = {
178        'root': [
179            (r'#!(.*?)$', Comment.Preproc),
180            default('base'),
181        ],
182        'base': [
183            ('--.*$', Comment.Single),
184            (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float),
185            (r'(?i)\d+e[+-]?\d+', Number.Float),
186            (r'(?i)0x[0-9a-f]*', Number.Hex),
187            (r'\d+', Number.Integer),
188            (r'\n', Text),
189            (r'[^\S\n]+', Text),
190            (r'(?s)\[(=*)\[.*?\]\1\]', String),
191            (r'(->|=>)', Name.Function),
192            (r':[a-zA-Z_]\w*', Name.Variable),
193            (r'(==|!=|~=|<=|>=|\.\.\.|\.\.|[=+\-*/%^<>#!.\\:])', Operator),
194            (r'[;,]', Punctuation),
195            (r'[\[\]{}()]', Keyword.Type),
196            (r'[a-zA-Z_]\w*:', Name.Variable),
197            (words((
198                'class', 'extends', 'if', 'then', 'super', 'do', 'with',
199                'import', 'export', 'while', 'elseif', 'return', 'for', 'in',
200                'from', 'when', 'using', 'else', 'and', 'or', 'not', 'switch',
201                'break'), suffix=r'\b'),
202             Keyword),
203            (r'(true|false|nil)\b', Keyword.Constant),
204            (r'(and|or|not)\b', Operator.Word),
205            (r'(self)\b', Name.Builtin.Pseudo),
206            (r'@@?([a-zA-Z_]\w*)?', Name.Variable.Class),
207            (r'[A-Z]\w*', Name.Class),  # proper name
208            (r'[A-Za-z_]\w*(\.[A-Za-z_]\w*)?', Name),
209            ("'", String.Single, combined('stringescape', 'sqs')),
210            ('"', String.Double, combined('stringescape', 'dqs'))
211        ],
212        'stringescape': [
213            (r'''\\([abfnrtv\\"']|\d{1,3})''', String.Escape)
214        ],
215        'sqs': [
216            ("'", String.Single, '#pop'),
217            (".", String)
218        ],
219        'dqs': [
220            ('"', String.Double, '#pop'),
221            (".", String)
222        ]
223    }
224
225    def get_tokens_unprocessed(self, text):
226        # set . as Operator instead of Punctuation
227        for index, token, value in LuaLexer.get_tokens_unprocessed(self, text):
228            if token == Punctuation and value == ".":
229                token = Operator
230            yield index, token, value
231
232
233class ChaiscriptLexer(RegexLexer):
234    """
235    For `ChaiScript <http://chaiscript.com/>`_ source code.
236
237    .. versionadded:: 2.0
238    """
239
240    name = 'ChaiScript'
241    aliases = ['chai', 'chaiscript']
242    filenames = ['*.chai']
243    mimetypes = ['text/x-chaiscript', 'application/x-chaiscript']
244
245    flags = re.DOTALL | re.MULTILINE
246
247    tokens = {
248        'commentsandwhitespace': [
249            (r'\s+', Text),
250            (r'//.*?\n', Comment.Single),
251            (r'/\*.*?\*/', Comment.Multiline),
252            (r'^\#.*?\n', Comment.Single)
253        ],
254        'slashstartsregex': [
255            include('commentsandwhitespace'),
256            (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
257             r'([gim]+\b|\B)', String.Regex, '#pop'),
258            (r'(?=/)', Text, ('#pop', 'badregex')),
259            default('#pop')
260        ],
261        'badregex': [
262            (r'\n', Text, '#pop')
263        ],
264        'root': [
265            include('commentsandwhitespace'),
266            (r'\n', Text),
267            (r'[^\S\n]+', Text),
268            (r'\+\+|--|~|&&|\?|:|\|\||\\(?=\n)|\.\.'
269             r'(<<|>>>?|==?|!=?|[-<>+*%&|^/])=?', Operator, 'slashstartsregex'),
270            (r'[{(\[;,]', Punctuation, 'slashstartsregex'),
271            (r'[})\].]', Punctuation),
272            (r'[=+\-*/]', Operator),
273            (r'(for|in|while|do|break|return|continue|if|else|'
274             r'throw|try|catch'
275             r')\b', Keyword, 'slashstartsregex'),
276            (r'(var)\b', Keyword.Declaration, 'slashstartsregex'),
277            (r'(attr|def|fun)\b', Keyword.Reserved),
278            (r'(true|false)\b', Keyword.Constant),
279            (r'(eval|throw)\b', Name.Builtin),
280            (r'`\S+`', Name.Builtin),
281            (r'[$a-zA-Z_]\w*', Name.Other),
282            (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
283            (r'0x[0-9a-fA-F]+', Number.Hex),
284            (r'[0-9]+', Number.Integer),
285            (r'"', String.Double, 'dqstring'),
286            (r"'(\\\\|\\'|[^'])*'", String.Single),
287        ],
288        'dqstring': [
289            (r'\$\{[^"}]+?\}', String.Interpol),
290            (r'\$', String.Double),
291            (r'\\\\', String.Double),
292            (r'\\"', String.Double),
293            (r'[^\\"$]+', String.Double),
294            (r'"', String.Double, '#pop'),
295        ],
296    }
297
298
299class LSLLexer(RegexLexer):
300    """
301    For Second Life's Linden Scripting Language source code.
302
303    .. versionadded:: 2.0
304    """
305
306    name = 'LSL'
307    aliases = ['lsl']
308    filenames = ['*.lsl']
309    mimetypes = ['text/x-lsl']
310
311    flags = re.MULTILINE
312
313    lsl_keywords = r'\b(?:do|else|for|if|jump|return|while)\b'
314    lsl_types = r'\b(?:float|integer|key|list|quaternion|rotation|string|vector)\b'
315    lsl_states = r'\b(?:(?:state)\s+\w+|default)\b'
316    lsl_events = r'\b(?:state_(?:entry|exit)|touch(?:_(?:start|end))?|(?:land_)?collision(?:_(?:start|end))?|timer|listen|(?:no_)?sensor|control|(?:not_)?at_(?:rot_)?target|money|email|run_time_permissions|changed|attach|dataserver|moving_(?:start|end)|link_message|(?:on|object)_rez|remote_data|http_re(?:sponse|quest)|path_update|transaction_result)\b'
317    lsl_functions_builtin = r'\b(?:ll(?:ReturnObjectsBy(?:ID|Owner)|Json(?:2List|[GS]etValue|ValueType)|Sin|Cos|Tan|Atan2|Sqrt|Pow|Abs|Fabs|Frand|Floor|Ceil|Round|Vec(?:Mag|Norm|Dist)|Rot(?:Between|2(?:Euler|Fwd|Left|Up))|(?:Euler|Axes)2Rot|Whisper|(?:Region|Owner)?Say|Shout|Listen(?:Control|Remove)?|Sensor(?:Repeat|Remove)?|Detected(?:Name|Key|Owner|Type|Pos|Vel|Grab|Rot|Group|LinkNumber)|Die|Ground|Wind|(?:[GS]et)(?:AnimationOverride|MemoryLimit|PrimMediaParams|ParcelMusicURL|Object(?:Desc|Name)|PhysicsMaterial|Status|Scale|Color|Alpha|Texture|Pos|Rot|Force|Torque)|ResetAnimationOverride|(?:Scale|Offset|Rotate)Texture|(?:Rot)?Target(?:Remove)?|(?:Stop)?MoveToTarget|Apply(?:Rotational)?Impulse|Set(?:KeyframedMotion|ContentType|RegionPos|(?:Angular)?Velocity|Buoyancy|HoverHeight|ForceAndTorque|TimerEvent|ScriptState|Damage|TextureAnim|Sound(?:Queueing|Radius)|Vehicle(?:Type|(?:Float|Vector|Rotation)Param)|(?:Touch|Sit)?Text|Camera(?:Eye|At)Offset|PrimitiveParams|ClickAction|Link(?:Alpha|Color|PrimitiveParams(?:Fast)?|Texture(?:Anim)?|Camera|Media)|RemoteScriptAccessPin|PayPrice|LocalRot)|ScaleByFactor|Get(?:(?:Max|Min)ScaleFactor|ClosestNavPoint|StaticPath|SimStats|Env|PrimitiveParams|Link(?:PrimitiveParams|Number(?:OfSides)?|Key|Name|Media)|HTTPHeader|FreeURLs|Object(?:Details|PermMask|PrimCount)|Parcel(?:MaxPrims|Details|Prim(?:Count|Owners))|Attached|(?:SPMax|Free|Used)Memory|Region(?:Name|TimeDilation|FPS|Corner|AgentCount)|Root(?:Position|Rotation)|UnixTime|(?:Parcel|Region)Flags|(?:Wall|GMT)clock|SimulatorHostname|BoundingBox|GeometricCenter|Creator|NumberOf(?:Prims|NotecardLines|Sides)|Animation(?:List)?|(?:Camera|Local)(?:Pos|Rot)|Vel|Accel|Omega|Time(?:stamp|OfDay)|(?:Object|CenterOf)?Mass|MassMKS|Energy|Owner|(?:Owner)?Key|SunDirection|Texture(?:Offset|Scale|Rot)|Inventory(?:Number|Name|Key|Type|Creator|PermMask)|Permissions(?:Key)?|StartParameter|List(?:Length|EntryType)|Date|Agent(?:Size|Info|Language|List)|LandOwnerAt|NotecardLine|Script(?:Name|State))|(?:Get|Reset|GetAndReset)Time|PlaySound(?:Slave)?|LoopSound(?:Master|Slave)?|(?:Trigger|Stop|Preload)Sound|(?:(?:Get|Delete)Sub|Insert)String|To(?:Upper|Lower)|Give(?:InventoryList|Money)|RezObject|(?:Stop)?LookAt|Sleep|CollisionFilter|(?:Take|Release)Controls|DetachFromAvatar|AttachToAvatar(?:Temp)?|InstantMessage|(?:GetNext)?Email|StopHover|MinEventDelay|RotLookAt|String(?:Length|Trim)|(?:Start|Stop)Animation|TargetOmega|RequestPermissions|(?:Create|Break)Link|BreakAllLinks|(?:Give|Remove)Inventory|Water|PassTouches|Request(?:Agent|Inventory)Data|TeleportAgent(?:Home|GlobalCoords)?|ModifyLand|CollisionSound|ResetScript|MessageLinked|PushObject|PassCollisions|AxisAngle2Rot|Rot2(?:Axis|Angle)|A(?:cos|sin)|AngleBetween|AllowInventoryDrop|SubStringIndex|List2(?:CSV|Integer|Json|Float|String|Key|Vector|Rot|List(?:Strided)?)|DeleteSubList|List(?:Statistics|Sort|Randomize|(?:Insert|Find|Replace)List)|EdgeOfWorld|AdjustSoundVolume|Key2Name|TriggerSoundLimited|EjectFromLand|(?:CSV|ParseString)2List|OverMyLand|SameGroup|UnSit|Ground(?:Slope|Normal|Contour)|GroundRepel|(?:Set|Remove)VehicleFlags|(?:AvatarOn)?(?:Link)?SitTarget|Script(?:Danger|Profiler)|Dialog|VolumeDetect|ResetOtherScript|RemoteLoadScriptPin|(?:Open|Close)RemoteDataChannel|SendRemoteData|RemoteDataReply|(?:Integer|String)ToBase64|XorBase64|Log(?:10)?|Base64To(?:String|Integer)|ParseStringKeepNulls|RezAtRoot|RequestSimulatorData|ForceMouselook|(?:Load|Release|(?:E|Une)scape)URL|ParcelMedia(?:CommandList|Query)|ModPow|MapDestination|(?:RemoveFrom|AddTo|Reset)Land(?:Pass|Ban)List|(?:Set|Clear)CameraParams|HTTP(?:Request|Response)|TextBox|DetectedTouch(?:UV|Face|Pos|(?:N|Bin)ormal|ST)|(?:MD5|SHA1|DumpList2)String|Request(?:Secure)?URL|Clear(?:Prim|Link)Media|(?:Link)?ParticleSystem|(?:Get|Request)(?:Username|DisplayName)|RegionSayTo|CastRay|GenerateKey|TransferLindenDollars|ManageEstateAccess|(?:Create|Delete)Character|ExecCharacterCmd|Evade|FleeFrom|NavigateTo|PatrolPoints|Pursue|UpdateCharacter|WanderWithin))\b'
318    lsl_constants_float = r'\b(?:DEG_TO_RAD|PI(?:_BY_TWO)?|RAD_TO_DEG|SQRT2|TWO_PI)\b'
319    lsl_constants_integer = r'\b(?:JSON_APPEND|STATUS_(?:PHYSICS|ROTATE_[XYZ]|PHANTOM|SANDBOX|BLOCK_GRAB(?:_OBJECT)?|(?:DIE|RETURN)_AT_EDGE|CAST_SHADOWS|OK|MALFORMED_PARAMS|TYPE_MISMATCH|BOUNDS_ERROR|NOT_(?:FOUND|SUPPORTED)|INTERNAL_ERROR|WHITELIST_FAILED)|AGENT(?:_(?:BY_(?:LEGACY_|USER)NAME|FLYING|ATTACHMENTS|SCRIPTED|MOUSELOOK|SITTING|ON_OBJECT|AWAY|WALKING|IN_AIR|TYPING|CROUCHING|BUSY|ALWAYS_RUN|AUTOPILOT|LIST_(?:PARCEL(?:_OWNER)?|REGION)))?|CAMERA_(?:PITCH|DISTANCE|BEHINDNESS_(?:ANGLE|LAG)|(?:FOCUS|POSITION)(?:_(?:THRESHOLD|LOCKED|LAG))?|FOCUS_OFFSET|ACTIVE)|ANIM_ON|LOOP|REVERSE|PING_PONG|SMOOTH|ROTATE|SCALE|ALL_SIDES|LINK_(?:ROOT|SET|ALL_(?:OTHERS|CHILDREN)|THIS)|ACTIVE|PASSIVE|SCRIPTED|CONTROL_(?:FWD|BACK|(?:ROT_)?(?:LEFT|RIGHT)|UP|DOWN|(?:ML_)?LBUTTON)|PERMISSION_(?:RETURN_OBJECTS|DEBIT|OVERRIDE_ANIMATIONS|SILENT_ESTATE_MANAGEMENT|TAKE_CONTROLS|TRIGGER_ANIMATION|ATTACH|CHANGE_LINKS|(?:CONTROL|TRACK)_CAMERA|TELEPORT)|INVENTORY_(?:TEXTURE|SOUND|OBJECT|SCRIPT|LANDMARK|CLOTHING|NOTECARD|BODYPART|ANIMATION|GESTURE|ALL|NONE)|CHANGED_(?:INVENTORY|COLOR|SHAPE|SCALE|TEXTURE|LINK|ALLOWED_DROP|OWNER|REGION(?:_START)?|TELEPORT|MEDIA)|OBJECT_(?:(?:PHYSICS|SERVER|STREAMING)_COST|UNKNOWN_DETAIL|CHARACTER_TIME|PHANTOM|PHYSICS|TEMP_ON_REZ|NAME|DESC|POS|PRIM_EQUIVALENCE|RETURN_(?:PARCEL(?:_OWNER)?|REGION)|ROO?T|VELOCITY|OWNER|GROUP|CREATOR|ATTACHED_POINT|RENDER_WEIGHT|PATHFINDING_TYPE|(?:RUNNING|TOTAL)_SCRIPT_COUNT|SCRIPT_(?:MEMORY|TIME))|TYPE_(?:INTEGER|FLOAT|STRING|KEY|VECTOR|ROTATION|INVALID)|(?:DEBUG|PUBLIC)_CHANNEL|ATTACH_(?:AVATAR_CENTER|CHEST|HEAD|BACK|PELVIS|MOUTH|CHIN|NECK|NOSE|BELLY|[LR](?:SHOULDER|HAND|FOOT|EAR|EYE|[UL](?:ARM|LEG)|HIP)|(?:LEFT|RIGHT)_PEC|HUD_(?:CENTER_[12]|TOP_(?:RIGHT|CENTER|LEFT)|BOTTOM(?:_(?:RIGHT|LEFT))?))|LAND_(?:LEVEL|RAISE|LOWER|SMOOTH|NOISE|REVERT)|DATA_(?:ONLINE|NAME|BORN|SIM_(?:POS|STATUS|RATING)|PAYINFO)|PAYMENT_INFO_(?:ON_FILE|USED)|REMOTE_DATA_(?:CHANNEL|REQUEST|REPLY)|PSYS_(?:PART_(?:BF_(?:ZERO|ONE(?:_MINUS_(?:DEST_COLOR|SOURCE_(ALPHA|COLOR)))?|DEST_COLOR|SOURCE_(ALPHA|COLOR))|BLEND_FUNC_(DEST|SOURCE)|FLAGS|(?:START|END)_(?:COLOR|ALPHA|SCALE|GLOW)|MAX_AGE|(?:RIBBON|WIND|INTERP_(?:COLOR|SCALE)|BOUNCE|FOLLOW_(?:SRC|VELOCITY)|TARGET_(?:POS|LINEAR)|EMISSIVE)_MASK)|SRC_(?:MAX_AGE|PATTERN|ANGLE_(?:BEGIN|END)|BURST_(?:RATE|PART_COUNT|RADIUS|SPEED_(?:MIN|MAX))|ACCEL|TEXTURE|TARGET_KEY|OMEGA|PATTERN_(?:DROP|EXPLODE|ANGLE(?:_CONE(?:_EMPTY)?)?)))|VEHICLE_(?:REFERENCE_FRAME|TYPE_(?:NONE|SLED|CAR|BOAT|AIRPLANE|BALLOON)|(?:LINEAR|ANGULAR)_(?:FRICTION_TIMESCALE|MOTOR_DIRECTION)|LINEAR_MOTOR_OFFSET|HOVER_(?:HEIGHT|EFFICIENCY|TIMESCALE)|BUOYANCY|(?:LINEAR|ANGULAR)_(?:DEFLECTION_(?:EFFICIENCY|TIMESCALE)|MOTOR_(?:DECAY_)?TIMESCALE)|VERTICAL_ATTRACTION_(?:EFFICIENCY|TIMESCALE)|BANKING_(?:EFFICIENCY|MIX|TIMESCALE)|FLAG_(?:NO_DEFLECTION_UP|LIMIT_(?:ROLL_ONLY|MOTOR_UP)|HOVER_(?:(?:WATER|TERRAIN|UP)_ONLY|GLOBAL_HEIGHT)|MOUSELOOK_(?:STEER|BANK)|CAMERA_DECOUPLED))|PRIM_(?:TYPE(?:_(?:BOX|CYLINDER|PRISM|SPHERE|TORUS|TUBE|RING|SCULPT))?|HOLE_(?:DEFAULT|CIRCLE|SQUARE|TRIANGLE)|MATERIAL(?:_(?:STONE|METAL|GLASS|WOOD|FLESH|PLASTIC|RUBBER))?|SHINY_(?:NONE|LOW|MEDIUM|HIGH)|BUMP_(?:NONE|BRIGHT|DARK|WOOD|BARK|BRICKS|CHECKER|CONCRETE|TILE|STONE|DISKS|GRAVEL|BLOBS|SIDING|LARGETILE|STUCCO|SUCTION|WEAVE)|TEXGEN_(?:DEFAULT|PLANAR)|SCULPT_(?:TYPE_(?:SPHERE|TORUS|PLANE|CYLINDER|MASK)|FLAG_(?:MIRROR|INVERT))|PHYSICS(?:_(?:SHAPE_(?:CONVEX|NONE|PRIM|TYPE)))?|(?:POS|ROT)_LOCAL|SLICE|TEXT|FLEXIBLE|POINT_LIGHT|TEMP_ON_REZ|PHANTOM|POSITION|SIZE|ROTATION|TEXTURE|NAME|OMEGA|DESC|LINK_TARGET|COLOR|BUMP_SHINY|FULLBRIGHT|TEXGEN|GLOW|MEDIA_(?:ALT_IMAGE_ENABLE|CONTROLS|(?:CURRENT|HOME)_URL|AUTO_(?:LOOP|PLAY|SCALE|ZOOM)|FIRST_CLICK_INTERACT|(?:WIDTH|HEIGHT)_PIXELS|WHITELIST(?:_ENABLE)?|PERMS_(?:INTERACT|CONTROL)|PARAM_MAX|CONTROLS_(?:STANDARD|MINI)|PERM_(?:NONE|OWNER|GROUP|ANYONE)|MAX_(?:URL_LENGTH|WHITELIST_(?:SIZE|COUNT)|(?:WIDTH|HEIGHT)_PIXELS)))|MASK_(?:BASE|OWNER|GROUP|EVERYONE|NEXT)|PERM_(?:TRANSFER|MODIFY|COPY|MOVE|ALL)|PARCEL_(?:MEDIA_COMMAND_(?:STOP|PAUSE|PLAY|LOOP|TEXTURE|URL|TIME|AGENT|UNLOAD|AUTO_ALIGN|TYPE|SIZE|DESC|LOOP_SET)|FLAG_(?:ALLOW_(?:FLY|(?:GROUP_)?SCRIPTS|LANDMARK|TERRAFORM|DAMAGE|CREATE_(?:GROUP_)?OBJECTS)|USE_(?:ACCESS_(?:GROUP|LIST)|BAN_LIST|LAND_PASS_LIST)|LOCAL_SOUND_ONLY|RESTRICT_PUSHOBJECT|ALLOW_(?:GROUP|ALL)_OBJECT_ENTRY)|COUNT_(?:TOTAL|OWNER|GROUP|OTHER|SELECTED|TEMP)|DETAILS_(?:NAME|DESC|OWNER|GROUP|AREA|ID|SEE_AVATARS))|LIST_STAT_(?:MAX|MIN|MEAN|MEDIAN|STD_DEV|SUM(?:_SQUARES)?|NUM_COUNT|GEOMETRIC_MEAN|RANGE)|PAY_(?:HIDE|DEFAULT)|REGION_FLAG_(?:ALLOW_DAMAGE|FIXED_SUN|BLOCK_TERRAFORM|SANDBOX|DISABLE_(?:COLLISIONS|PHYSICS)|BLOCK_FLY|ALLOW_DIRECT_TELEPORT|RESTRICT_PUSHOBJECT)|HTTP_(?:METHOD|MIMETYPE|BODY_(?:MAXLENGTH|TRUNCATED)|CUSTOM_HEADER|PRAGMA_NO_CACHE|VERBOSE_THROTTLE|VERIFY_CERT)|STRING_(?:TRIM(?:_(?:HEAD|TAIL))?)|CLICK_ACTION_(?:NONE|TOUCH|SIT|BUY|PAY|OPEN(?:_MEDIA)?|PLAY|ZOOM)|TOUCH_INVALID_FACE|PROFILE_(?:NONE|SCRIPT_MEMORY)|RC_(?:DATA_FLAGS|DETECT_PHANTOM|GET_(?:LINK_NUM|NORMAL|ROOT_KEY)|MAX_HITS|REJECT_(?:TYPES|AGENTS|(?:NON)?PHYSICAL|LAND))|RCERR_(?:CAST_TIME_EXCEEDED|SIM_PERF_LOW|UNKNOWN)|ESTATE_ACCESS_(?:ALLOWED_(?:AGENT|GROUP)_(?:ADD|REMOVE)|BANNED_AGENT_(?:ADD|REMOVE))|DENSITY|FRICTION|RESTITUTION|GRAVITY_MULTIPLIER|KFM_(?:COMMAND|CMD_(?:PLAY|STOP|PAUSE|SET_MODE)|MODE|FORWARD|LOOP|PING_PONG|REVERSE|DATA|ROTATION|TRANSLATION)|ERR_(?:GENERIC|PARCEL_PERMISSIONS|MALFORMED_PARAMS|RUNTIME_PERMISSIONS|THROTTLED)|CHARACTER_(?:CMD_(?:(?:SMOOTH_)?STOP|JUMP)|DESIRED_(?:TURN_)?SPEED|RADIUS|STAY_WITHIN_PARCEL|LENGTH|ORIENTATION|ACCOUNT_FOR_SKIPPED_FRAMES|AVOIDANCE_MODE|TYPE(?:_(?:[A-D]|NONE))?|MAX_(?:DECEL|TURN_RADIUS|(?:ACCEL|SPEED)))|PURSUIT_(?:OFFSET|FUZZ_FACTOR|GOAL_TOLERANCE|INTERCEPT)|REQUIRE_LINE_OF_SIGHT|FORCE_DIRECT_PATH|VERTICAL|HORIZONTAL|AVOID_(?:CHARACTERS|DYNAMIC_OBSTACLES|NONE)|PU_(?:EVADE_(?:HIDDEN|SPOTTED)|FAILURE_(?:DYNAMIC_PATHFINDING_DISABLED|INVALID_(?:GOAL|START)|NO_(?:NAVMESH|VALID_DESTINATION)|OTHER|TARGET_GONE|(?:PARCEL_)?UNREACHABLE)|(?:GOAL|SLOWDOWN_DISTANCE)_REACHED)|TRAVERSAL_TYPE(?:_(?:FAST|NONE|SLOW))?|CONTENT_TYPE_(?:ATOM|FORM|HTML|JSON|LLSD|RSS|TEXT|XHTML|XML)|GCNP_(?:RADIUS|STATIC)|(?:PATROL|WANDER)_PAUSE_AT_WAYPOINTS|OPT_(?:AVATAR|CHARACTER|EXCLUSION_VOLUME|LEGACY_LINKSET|MATERIAL_VOLUME|OTHER|STATIC_OBSTACLE|WALKABLE)|SIM_STAT_PCT_CHARS_STEPPED)\b'
320    lsl_constants_integer_boolean = r'\b(?:FALSE|TRUE)\b'
321    lsl_constants_rotation = r'\b(?:ZERO_ROTATION)\b'
322    lsl_constants_string = r'\b(?:EOF|JSON_(?:ARRAY|DELETE|FALSE|INVALID|NULL|NUMBER|OBJECT|STRING|TRUE)|NULL_KEY|TEXTURE_(?:BLANK|DEFAULT|MEDIA|PLYWOOD|TRANSPARENT)|URL_REQUEST_(?:GRANTED|DENIED))\b'
323    lsl_constants_vector = r'\b(?:TOUCH_INVALID_(?:TEXCOORD|VECTOR)|ZERO_VECTOR)\b'
324    lsl_invalid_broken = r'\b(?:LAND_(?:LARGE|MEDIUM|SMALL)_BRUSH)\b'
325    lsl_invalid_deprecated = r'\b(?:ATTACH_[LR]PEC|DATA_RATING|OBJECT_ATTACHMENT_(?:GEOMETRY_BYTES|SURFACE_AREA)|PRIM_(?:CAST_SHADOWS|MATERIAL_LIGHT|TYPE_LEGACY)|PSYS_SRC_(?:INNER|OUTER)ANGLE|VEHICLE_FLAG_NO_FLY_UP|ll(?:Cloud|Make(?:Explosion|Fountain|Smoke|Fire)|RemoteDataSetRegion|Sound(?:Preload)?|XorBase64Strings(?:Correct)?))\b'
326    lsl_invalid_illegal = r'\b(?:event)\b'
327    lsl_invalid_unimplemented = r'\b(?:CHARACTER_(?:MAX_ANGULAR_(?:ACCEL|SPEED)|TURN_SPEED_MULTIPLIER)|PERMISSION_(?:CHANGE_(?:JOINTS|PERMISSIONS)|RELEASE_OWNERSHIP|REMAP_CONTROLS)|PRIM_PHYSICS_MATERIAL|PSYS_SRC_OBJ_REL_MASK|ll(?:CollisionSprite|(?:Stop)?PointAt|(?:(?:Refresh|Set)Prim)URL|(?:Take|Release)Camera|RemoteLoadScript))\b'
328    lsl_reserved_godmode = r'\b(?:ll(?:GodLikeRezObject|Set(?:Inventory|Object)PermMask))\b'
329    lsl_reserved_log = r'\b(?:print)\b'
330    lsl_operators = r'\+\+|\-\-|<<|>>|&&?|\|\|?|\^|~|[!%<>=*+\-/]=?'
331
332    tokens = {
333        'root':
334        [
335            (r'//.*?\n',                          Comment.Single),
336            (r'/\*',                              Comment.Multiline, 'comment'),
337            (r'"',                                String.Double, 'string'),
338            (lsl_keywords,                        Keyword),
339            (lsl_types,                           Keyword.Type),
340            (lsl_states,                          Name.Class),
341            (lsl_events,                          Name.Builtin),
342            (lsl_functions_builtin,               Name.Function),
343            (lsl_constants_float,                 Keyword.Constant),
344            (lsl_constants_integer,               Keyword.Constant),
345            (lsl_constants_integer_boolean,       Keyword.Constant),
346            (lsl_constants_rotation,              Keyword.Constant),
347            (lsl_constants_string,                Keyword.Constant),
348            (lsl_constants_vector,                Keyword.Constant),
349            (lsl_invalid_broken,                  Error),
350            (lsl_invalid_deprecated,              Error),
351            (lsl_invalid_illegal,                 Error),
352            (lsl_invalid_unimplemented,           Error),
353            (lsl_reserved_godmode,                Keyword.Reserved),
354            (lsl_reserved_log,                    Keyword.Reserved),
355            (r'\b([a-zA-Z_]\w*)\b',     Name.Variable),
356            (r'(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d*', Number.Float),
357            (r'(\d+\.\d*|\.\d+)',                 Number.Float),
358            (r'0[xX][0-9a-fA-F]+',                Number.Hex),
359            (r'\d+',                              Number.Integer),
360            (lsl_operators,                       Operator),
361            (r':=?',                              Error),
362            (r'[,;{}()\[\]]',                     Punctuation),
363            (r'\n+',                              Whitespace),
364            (r'\s+',                              Whitespace)
365        ],
366        'comment':
367        [
368            (r'[^*/]+',                           Comment.Multiline),
369            (r'/\*',                              Comment.Multiline, '#push'),
370            (r'\*/',                              Comment.Multiline, '#pop'),
371            (r'[*/]',                             Comment.Multiline)
372        ],
373        'string':
374        [
375            (r'\\([nt"\\])',                      String.Escape),
376            (r'"',                                String.Double, '#pop'),
377            (r'\\.',                              Error),
378            (r'[^"\\]+',                          String.Double),
379        ]
380    }
381
382
383class AppleScriptLexer(RegexLexer):
384    """
385    For `AppleScript source code
386    <http://developer.apple.com/documentation/AppleScript/
387    Conceptual/AppleScriptLangGuide>`_,
388    including `AppleScript Studio
389    <http://developer.apple.com/documentation/AppleScript/
390    Reference/StudioReference>`_.
391    Contributed by Andreas Amann <aamann@mac.com>.
392
393    .. versionadded:: 1.0
394    """
395
396    name = 'AppleScript'
397    aliases = ['applescript']
398    filenames = ['*.applescript']
399
400    flags = re.MULTILINE | re.DOTALL
401
402    Identifiers = r'[a-zA-Z]\w*'
403
404    # XXX: use words() for all of these
405    Literals = ('AppleScript', 'current application', 'false', 'linefeed',
406                'missing value', 'pi', 'quote', 'result', 'return', 'space',
407                'tab', 'text item delimiters', 'true', 'version')
408    Classes = ('alias ', 'application ', 'boolean ', 'class ', 'constant ',
409               'date ', 'file ', 'integer ', 'list ', 'number ', 'POSIX file ',
410               'real ', 'record ', 'reference ', 'RGB color ', 'script ',
411               'text ', 'unit types', '(?:Unicode )?text', 'string')
412    BuiltIn = ('attachment', 'attribute run', 'character', 'day', 'month',
413               'paragraph', 'word', 'year')
414    HandlerParams = ('about', 'above', 'against', 'apart from', 'around',
415                     'aside from', 'at', 'below', 'beneath', 'beside',
416                     'between', 'for', 'given', 'instead of', 'on', 'onto',
417                     'out of', 'over', 'since')
418    Commands = ('ASCII (character|number)', 'activate', 'beep', 'choose URL',
419                'choose application', 'choose color', 'choose file( name)?',
420                'choose folder', 'choose from list',
421                'choose remote application', 'clipboard info',
422                'close( access)?', 'copy', 'count', 'current date', 'delay',
423                'delete', 'display (alert|dialog)', 'do shell script',
424                'duplicate', 'exists', 'get eof', 'get volume settings',
425                'info for', 'launch', 'list (disks|folder)', 'load script',
426                'log', 'make', 'mount volume', 'new', 'offset',
427                'open( (for access|location))?', 'path to', 'print', 'quit',
428                'random number', 'read', 'round', 'run( script)?',
429                'say', 'scripting components',
430                'set (eof|the clipboard to|volume)', 'store script',
431                'summarize', 'system attribute', 'system info',
432                'the clipboard', 'time to GMT', 'write', 'quoted form')
433    References = ('(in )?back of', '(in )?front of', '[0-9]+(st|nd|rd|th)',
434                  'first', 'second', 'third', 'fourth', 'fifth', 'sixth',
435                  'seventh', 'eighth', 'ninth', 'tenth', 'after', 'back',
436                  'before', 'behind', 'every', 'front', 'index', 'last',
437                  'middle', 'some', 'that', 'through', 'thru', 'where', 'whose')
438    Operators = ("and", "or", "is equal", "equals", "(is )?equal to", "is not",
439                 "isn't", "isn't equal( to)?", "is not equal( to)?",
440                 "doesn't equal", "does not equal", "(is )?greater than",
441                 "comes after", "is not less than or equal( to)?",
442                 "isn't less than or equal( to)?", "(is )?less than",
443                 "comes before", "is not greater than or equal( to)?",
444                 "isn't greater than or equal( to)?",
445                 "(is  )?greater than or equal( to)?", "is not less than",
446                 "isn't less than", "does not come before",
447                 "doesn't come before", "(is )?less than or equal( to)?",
448                 "is not greater than", "isn't greater than",
449                 "does not come after", "doesn't come after", "starts? with",
450                 "begins? with", "ends? with", "contains?", "does not contain",
451                 "doesn't contain", "is in", "is contained by", "is not in",
452                 "is not contained by", "isn't contained by", "div", "mod",
453                 "not", "(a  )?(ref( to)?|reference to)", "is", "does")
454    Control = ('considering', 'else', 'error', 'exit', 'from', 'if',
455               'ignoring', 'in', 'repeat', 'tell', 'then', 'times', 'to',
456               'try', 'until', 'using terms from', 'while', 'whith',
457               'with timeout( of)?', 'with transaction', 'by', 'continue',
458               'end', 'its?', 'me', 'my', 'return', 'of', 'as')
459    Declarations = ('global', 'local', 'prop(erty)?', 'set', 'get')
460    Reserved = ('but', 'put', 'returning', 'the')
461    StudioClasses = ('action cell', 'alert reply', 'application', 'box',
462                     'browser( cell)?', 'bundle', 'button( cell)?', 'cell',
463                     'clip view', 'color well', 'color-panel',
464                     'combo box( item)?', 'control',
465                     'data( (cell|column|item|row|source))?', 'default entry',
466                     'dialog reply', 'document', 'drag info', 'drawer',
467                     'event', 'font(-panel)?', 'formatter',
468                     'image( (cell|view))?', 'matrix', 'menu( item)?', 'item',
469                     'movie( view)?', 'open-panel', 'outline view', 'panel',
470                     'pasteboard', 'plugin', 'popup button',
471                     'progress indicator', 'responder', 'save-panel',
472                     'scroll view', 'secure text field( cell)?', 'slider',
473                     'sound', 'split view', 'stepper', 'tab view( item)?',
474                     'table( (column|header cell|header view|view))',
475                     'text( (field( cell)?|view))?', 'toolbar( item)?',
476                     'user-defaults', 'view', 'window')
477    StudioEvents = ('accept outline drop', 'accept table drop', 'action',
478                    'activated', 'alert ended', 'awake from nib', 'became key',
479                    'became main', 'begin editing', 'bounds changed',
480                    'cell value', 'cell value changed', 'change cell value',
481                    'change item value', 'changed', 'child of item',
482                    'choose menu item', 'clicked', 'clicked toolbar item',
483                    'closed', 'column clicked', 'column moved',
484                    'column resized', 'conclude drop', 'data representation',
485                    'deminiaturized', 'dialog ended', 'document nib name',
486                    'double clicked', 'drag( (entered|exited|updated))?',
487                    'drop', 'end editing', 'exposed', 'idle', 'item expandable',
488                    'item value', 'item value changed', 'items changed',
489                    'keyboard down', 'keyboard up', 'launched',
490                    'load data representation', 'miniaturized', 'mouse down',
491                    'mouse dragged', 'mouse entered', 'mouse exited',
492                    'mouse moved', 'mouse up', 'moved',
493                    'number of browser rows', 'number of items',
494                    'number of rows', 'open untitled', 'opened', 'panel ended',
495                    'parameters updated', 'plugin loaded', 'prepare drop',
496                    'prepare outline drag', 'prepare outline drop',
497                    'prepare table drag', 'prepare table drop',
498                    'read from file', 'resigned active', 'resigned key',
499                    'resigned main', 'resized( sub views)?',
500                    'right mouse down', 'right mouse dragged',
501                    'right mouse up', 'rows changed', 'scroll wheel',
502                    'selected tab view item', 'selection changed',
503                    'selection changing', 'should begin editing',
504                    'should close', 'should collapse item',
505                    'should end editing', 'should expand item',
506                    'should open( untitled)?',
507                    'should quit( after last window closed)?',
508                    'should select column', 'should select item',
509                    'should select row', 'should select tab view item',
510                    'should selection change', 'should zoom', 'shown',
511                    'update menu item', 'update parameters',
512                    'update toolbar item', 'was hidden', 'was miniaturized',
513                    'will become active', 'will close', 'will dismiss',
514                    'will display browser cell', 'will display cell',
515                    'will display item cell', 'will display outline cell',
516                    'will finish launching', 'will hide', 'will miniaturize',
517                    'will move', 'will open', 'will pop up', 'will quit',
518                    'will resign active', 'will resize( sub views)?',
519                    'will select tab view item', 'will show', 'will zoom',
520                    'write to file', 'zoomed')
521    StudioCommands = ('animate', 'append', 'call method', 'center',
522                      'close drawer', 'close panel', 'display',
523                      'display alert', 'display dialog', 'display panel', 'go',
524                      'hide', 'highlight', 'increment', 'item for',
525                      'load image', 'load movie', 'load nib', 'load panel',
526                      'load sound', 'localized string', 'lock focus', 'log',
527                      'open drawer', 'path for', 'pause', 'perform action',
528                      'play', 'register', 'resume', 'scroll', 'select( all)?',
529                      'show', 'size to fit', 'start', 'step back',
530                      'step forward', 'stop', 'synchronize', 'unlock focus',
531                      'update')
532    StudioProperties = ('accepts arrow key', 'action method', 'active',
533                        'alignment', 'allowed identifiers',
534                        'allows branch selection', 'allows column reordering',
535                        'allows column resizing', 'allows column selection',
536                        'allows customization',
537                        'allows editing text attributes',
538                        'allows empty selection', 'allows mixed state',
539                        'allows multiple selection', 'allows reordering',
540                        'allows undo', 'alpha( value)?', 'alternate image',
541                        'alternate increment value', 'alternate title',
542                        'animation delay', 'associated file name',
543                        'associated object', 'auto completes', 'auto display',
544                        'auto enables items', 'auto repeat',
545                        'auto resizes( outline column)?',
546                        'auto save expanded items', 'auto save name',
547                        'auto save table columns', 'auto saves configuration',
548                        'auto scroll', 'auto sizes all columns to fit',
549                        'auto sizes cells', 'background color', 'bezel state',
550                        'bezel style', 'bezeled', 'border rect', 'border type',
551                        'bordered', 'bounds( rotation)?', 'box type',
552                        'button returned', 'button type',
553                        'can choose directories', 'can choose files',
554                        'can draw', 'can hide',
555                        'cell( (background color|size|type))?', 'characters',
556                        'class', 'click count', 'clicked( data)? column',
557                        'clicked data item', 'clicked( data)? row',
558                        'closeable', 'collating', 'color( (mode|panel))',
559                        'command key down', 'configuration',
560                        'content(s| (size|view( margins)?))?', 'context',
561                        'continuous', 'control key down', 'control size',
562                        'control tint', 'control view',
563                        'controller visible', 'coordinate system',
564                        'copies( on scroll)?', 'corner view', 'current cell',
565                        'current column', 'current( field)?  editor',
566                        'current( menu)? item', 'current row',
567                        'current tab view item', 'data source',
568                        'default identifiers', 'delta (x|y|z)',
569                        'destination window', 'directory', 'display mode',
570                        'displayed cell', 'document( (edited|rect|view))?',
571                        'double value', 'dragged column', 'dragged distance',
572                        'dragged items', 'draws( cell)? background',
573                        'draws grid', 'dynamically scrolls', 'echos bullets',
574                        'edge', 'editable', 'edited( data)? column',
575                        'edited data item', 'edited( data)? row', 'enabled',
576                        'enclosing scroll view', 'ending page',
577                        'error handling', 'event number', 'event type',
578                        'excluded from windows menu', 'executable path',
579                        'expanded', 'fax number', 'field editor', 'file kind',
580                        'file name', 'file type', 'first responder',
581                        'first visible column', 'flipped', 'floating',
582                        'font( panel)?', 'formatter', 'frameworks path',
583                        'frontmost', 'gave up', 'grid color', 'has data items',
584                        'has horizontal ruler', 'has horizontal scroller',
585                        'has parent data item', 'has resize indicator',
586                        'has shadow', 'has sub menu', 'has vertical ruler',
587                        'has vertical scroller', 'header cell', 'header view',
588                        'hidden', 'hides when deactivated', 'highlights by',
589                        'horizontal line scroll', 'horizontal page scroll',
590                        'horizontal ruler view', 'horizontally resizable',
591                        'icon image', 'id', 'identifier',
592                        'ignores multiple clicks',
593                        'image( (alignment|dims when disabled|frame style|scaling))?',
594                        'imports graphics', 'increment value',
595                        'indentation per level', 'indeterminate', 'index',
596                        'integer value', 'intercell spacing', 'item height',
597                        'key( (code|equivalent( modifier)?|window))?',
598                        'knob thickness', 'label', 'last( visible)? column',
599                        'leading offset', 'leaf', 'level', 'line scroll',
600                        'loaded', 'localized sort', 'location', 'loop mode',
601                        'main( (bunde|menu|window))?', 'marker follows cell',
602                        'matrix mode', 'maximum( content)? size',
603                        'maximum visible columns',
604                        'menu( form representation)?', 'miniaturizable',
605                        'miniaturized', 'minimized image', 'minimized title',
606                        'minimum column width', 'minimum( content)? size',
607                        'modal', 'modified', 'mouse down state',
608                        'movie( (controller|file|rect))?', 'muted', 'name',
609                        'needs display', 'next state', 'next text',
610                        'number of tick marks', 'only tick mark values',
611                        'opaque', 'open panel', 'option key down',
612                        'outline table column', 'page scroll', 'pages across',
613                        'pages down', 'palette label', 'pane splitter',
614                        'parent data item', 'parent window', 'pasteboard',
615                        'path( (names|separator))?', 'playing',
616                        'plays every frame', 'plays selection only', 'position',
617                        'preferred edge', 'preferred type', 'pressure',
618                        'previous text', 'prompt', 'properties',
619                        'prototype cell', 'pulls down', 'rate',
620                        'released when closed', 'repeated',
621                        'requested print time', 'required file type',
622                        'resizable', 'resized column', 'resource path',
623                        'returns records', 'reuses columns', 'rich text',
624                        'roll over', 'row height', 'rulers visible',
625                        'save panel', 'scripts path', 'scrollable',
626                        'selectable( identifiers)?', 'selected cell',
627                        'selected( data)? columns?', 'selected data items?',
628                        'selected( data)? rows?', 'selected item identifier',
629                        'selection by rect', 'send action on arrow key',
630                        'sends action when done editing', 'separates columns',
631                        'separator item', 'sequence number', 'services menu',
632                        'shared frameworks path', 'shared support path',
633                        'sheet', 'shift key down', 'shows alpha',
634                        'shows state by', 'size( mode)?',
635                        'smart insert delete enabled', 'sort case sensitivity',
636                        'sort column', 'sort order', 'sort type',
637                        'sorted( data rows)?', 'sound', 'source( mask)?',
638                        'spell checking enabled', 'starting page', 'state',
639                        'string value', 'sub menu', 'super menu', 'super view',
640                        'tab key traverses cells', 'tab state', 'tab type',
641                        'tab view', 'table view', 'tag', 'target( printer)?',
642                        'text color', 'text container insert',
643                        'text container origin', 'text returned',
644                        'tick mark position', 'time stamp',
645                        'title(d| (cell|font|height|position|rect))?',
646                        'tool tip', 'toolbar', 'trailing offset', 'transparent',
647                        'treat packages as directories', 'truncated labels',
648                        'types', 'unmodified characters', 'update views',
649                        'use sort indicator', 'user defaults',
650                        'uses data source', 'uses ruler',
651                        'uses threaded animation',
652                        'uses title from previous column', 'value wraps',
653                        'version',
654                        'vertical( (line scroll|page scroll|ruler view))?',
655                        'vertically resizable', 'view',
656                        'visible( document rect)?', 'volume', 'width', 'window',
657                        'windows menu', 'wraps', 'zoomable', 'zoomed')
658
659    tokens = {
660        'root': [
661            (r'\s+', Text),
662            (r'¬\n', String.Escape),
663            (r"'s\s+", Text),  # This is a possessive, consider moving
664            (r'(--|#).*?$', Comment),
665            (r'\(\*', Comment.Multiline, 'comment'),
666            (r'[(){}!,.:]', Punctuation),
667            (r'(«)([^»]+)(»)',
668             bygroups(Text, Name.Builtin, Text)),
669            (r'\b((?:considering|ignoring)\s*)'
670             r'(application responses|case|diacriticals|hyphens|'
671             r'numeric strings|punctuation|white space)',
672             bygroups(Keyword, Name.Builtin)),
673            (r'(-|\*|\+|&|≠|>=?|<=?|=|≥|≤|/|÷|\^)', Operator),
674            (r"\b(%s)\b" % '|'.join(Operators), Operator.Word),
675            (r'^(\s*(?:on|end)\s+)'
676             r'(%s)' % '|'.join(StudioEvents[::-1]),
677             bygroups(Keyword, Name.Function)),
678            (r'^(\s*)(in|on|script|to)(\s+)', bygroups(Text, Keyword, Text)),
679            (r'\b(as )(%s)\b' % '|'.join(Classes),
680             bygroups(Keyword, Name.Class)),
681            (r'\b(%s)\b' % '|'.join(Literals), Name.Constant),
682            (r'\b(%s)\b' % '|'.join(Commands), Name.Builtin),
683            (r'\b(%s)\b' % '|'.join(Control), Keyword),
684            (r'\b(%s)\b' % '|'.join(Declarations), Keyword),
685            (r'\b(%s)\b' % '|'.join(Reserved), Name.Builtin),
686            (r'\b(%s)s?\b' % '|'.join(BuiltIn), Name.Builtin),
687            (r'\b(%s)\b' % '|'.join(HandlerParams), Name.Builtin),
688            (r'\b(%s)\b' % '|'.join(StudioProperties), Name.Attribute),
689            (r'\b(%s)s?\b' % '|'.join(StudioClasses), Name.Builtin),
690            (r'\b(%s)\b' % '|'.join(StudioCommands), Name.Builtin),
691            (r'\b(%s)\b' % '|'.join(References), Name.Builtin),
692            (r'"(\\\\|\\"|[^"])*"', String.Double),
693            (r'\b(%s)\b' % Identifiers, Name.Variable),
694            (r'[-+]?(\d+\.\d*|\d*\.\d+)(E[-+][0-9]+)?', Number.Float),
695            (r'[-+]?\d+', Number.Integer),
696        ],
697        'comment': [
698            (r'\(\*', Comment.Multiline, '#push'),
699            (r'\*\)', Comment.Multiline, '#pop'),
700            ('[^*(]+', Comment.Multiline),
701            ('[*(]', Comment.Multiline),
702        ],
703    }
704
705
706class RexxLexer(RegexLexer):
707    """
708    `Rexx <http://www.rexxinfo.org/>`_ is a scripting language available for
709    a wide range of different platforms with its roots found on mainframe
710    systems. It is popular for I/O- and data based tasks and can act as glue
711    language to bind different applications together.
712
713    .. versionadded:: 2.0
714    """
715    name = 'Rexx'
716    aliases = ['rexx', 'arexx']
717    filenames = ['*.rexx', '*.rex', '*.rx', '*.arexx']
718    mimetypes = ['text/x-rexx']
719    flags = re.IGNORECASE
720
721    tokens = {
722        'root': [
723            (r'\s', Whitespace),
724            (r'/\*', Comment.Multiline, 'comment'),
725            (r'"', String, 'string_double'),
726            (r"'", String, 'string_single'),
727            (r'[0-9]+(\.[0-9]+)?(e[+-]?[0-9])?', Number),
728            (r'([a-z_]\w*)(\s*)(:)(\s*)(procedure)\b',
729             bygroups(Name.Function, Whitespace, Operator, Whitespace,
730                      Keyword.Declaration)),
731            (r'([a-z_]\w*)(\s*)(:)',
732             bygroups(Name.Label, Whitespace, Operator)),
733            include('function'),
734            include('keyword'),
735            include('operator'),
736            (r'[a-z_]\w*', Text),
737        ],
738        'function': [
739            (words((
740                'abbrev', 'abs', 'address', 'arg', 'b2x', 'bitand', 'bitor', 'bitxor',
741                'c2d', 'c2x', 'center', 'charin', 'charout', 'chars', 'compare',
742                'condition', 'copies', 'd2c', 'd2x', 'datatype', 'date', 'delstr',
743                'delword', 'digits', 'errortext', 'form', 'format', 'fuzz', 'insert',
744                'lastpos', 'left', 'length', 'linein', 'lineout', 'lines', 'max',
745                'min', 'overlay', 'pos', 'queued', 'random', 'reverse', 'right', 'sign',
746                'sourceline', 'space', 'stream', 'strip', 'substr', 'subword', 'symbol',
747                'time', 'trace', 'translate', 'trunc', 'value', 'verify', 'word',
748                'wordindex', 'wordlength', 'wordpos', 'words', 'x2b', 'x2c', 'x2d',
749                'xrange'), suffix=r'(\s*)(\()'),
750             bygroups(Name.Builtin, Whitespace, Operator)),
751        ],
752        'keyword': [
753            (r'(address|arg|by|call|do|drop|else|end|exit|for|forever|if|'
754             r'interpret|iterate|leave|nop|numeric|off|on|options|parse|'
755             r'pull|push|queue|return|say|select|signal|to|then|trace|until|'
756             r'while)\b', Keyword.Reserved),
757        ],
758        'operator': [
759            (r'(-|//|/|\(|\)|\*\*|\*|\\<<|\\<|\\==|\\=|\\>>|\\>|\\|\|\||\||'
760             r'&&|&|%|\+|<<=|<<|<=|<>|<|==|=|><|>=|>>=|>>|>|¬<<|¬<|¬==|¬=|'
761             r'¬>>|¬>|¬|\.|,)', Operator),
762        ],
763        'string_double': [
764            (r'[^"\n]+', String),
765            (r'""', String),
766            (r'"', String, '#pop'),
767            (r'\n', Text, '#pop'),  # Stray linefeed also terminates strings.
768        ],
769        'string_single': [
770            (r'[^\'\n]', String),
771            (r'\'\'', String),
772            (r'\'', String, '#pop'),
773            (r'\n', Text, '#pop'),  # Stray linefeed also terminates strings.
774        ],
775        'comment': [
776            (r'[^*]+', Comment.Multiline),
777            (r'\*/', Comment.Multiline, '#pop'),
778            (r'\*', Comment.Multiline),
779        ]
780    }
781
782    _c = lambda s: re.compile(s, re.MULTILINE)
783    _ADDRESS_COMMAND_PATTERN = _c(r'^\s*address\s+command\b')
784    _ADDRESS_PATTERN = _c(r'^\s*address\s+')
785    _DO_WHILE_PATTERN = _c(r'^\s*do\s+while\b')
786    _IF_THEN_DO_PATTERN = _c(r'^\s*if\b.+\bthen\s+do\s*$')
787    _PROCEDURE_PATTERN = _c(r'^\s*([a-z_]\w*)(\s*)(:)(\s*)(procedure)\b')
788    _ELSE_DO_PATTERN = _c(r'\belse\s+do\s*$')
789    _PARSE_ARG_PATTERN = _c(r'^\s*parse\s+(upper\s+)?(arg|value)\b')
790    PATTERNS_AND_WEIGHTS = (
791        (_ADDRESS_COMMAND_PATTERN, 0.2),
792        (_ADDRESS_PATTERN, 0.05),
793        (_DO_WHILE_PATTERN, 0.1),
794        (_ELSE_DO_PATTERN, 0.1),
795        (_IF_THEN_DO_PATTERN, 0.1),
796        (_PROCEDURE_PATTERN, 0.5),
797        (_PARSE_ARG_PATTERN, 0.2),
798    )
799
800    def analyse_text(text):
801        """
802        Check for inital comment and patterns that distinguish Rexx from other
803        C-like languages.
804        """
805        if re.search(r'/\*\**\s*rexx', text, re.IGNORECASE):
806            # Header matches MVS Rexx requirements, this is certainly a Rexx
807            # script.
808            return 1.0
809        elif text.startswith('/*'):
810            # Header matches general Rexx requirements; the source code might
811            # still be any language using C comments such as C++, C# or Java.
812            lowerText = text.lower()
813            result = sum(weight
814                         for (pattern, weight) in RexxLexer.PATTERNS_AND_WEIGHTS
815                         if pattern.search(lowerText)) + 0.01
816            return min(result, 1.0)
817
818
819class MOOCodeLexer(RegexLexer):
820    """
821    For `MOOCode <http://www.moo.mud.org/>`_ (the MOO scripting
822    language).
823
824    .. versionadded:: 0.9
825    """
826    name = 'MOOCode'
827    filenames = ['*.moo']
828    aliases = ['moocode', 'moo']
829    mimetypes = ['text/x-moocode']
830
831    tokens = {
832        'root': [
833            # Numbers
834            (r'(0|[1-9][0-9_]*)', Number.Integer),
835            # Strings
836            (r'"(\\\\|\\"|[^"])*"', String),
837            # exceptions
838            (r'(E_PERM|E_DIV)', Name.Exception),
839            # db-refs
840            (r'((#[-0-9]+)|(\$\w+))', Name.Entity),
841            # Keywords
842            (r'\b(if|else|elseif|endif|for|endfor|fork|endfork|while'
843             r'|endwhile|break|continue|return|try'
844             r'|except|endtry|finally|in)\b', Keyword),
845            # builtins
846            (r'(random|length)', Name.Builtin),
847            # special variables
848            (r'(player|caller|this|args)', Name.Variable.Instance),
849            # skip whitespace
850            (r'\s+', Text),
851            (r'\n', Text),
852            # other operators
853            (r'([!;=,{}&|:.\[\]@()<>?]+)', Operator),
854            # function call
855            (r'(\w+)(\()', bygroups(Name.Function, Operator)),
856            # variables
857            (r'(\w+)', Text),
858        ]
859    }
860
861
862class HybrisLexer(RegexLexer):
863    """
864    For `Hybris <http://www.hybris-lang.org>`_ source code.
865
866    .. versionadded:: 1.4
867    """
868
869    name = 'Hybris'
870    aliases = ['hybris', 'hy']
871    filenames = ['*.hy', '*.hyb']
872    mimetypes = ['text/x-hybris', 'application/x-hybris']
873
874    flags = re.MULTILINE | re.DOTALL
875
876    tokens = {
877        'root': [
878            # method names
879            (r'^(\s*(?:function|method|operator\s+)+?)'
880             r'([a-zA-Z_]\w*)'
881             r'(\s*)(\()', bygroups(Keyword, Name.Function, Text, Operator)),
882            (r'[^\S\n]+', Text),
883            (r'//.*?\n', Comment.Single),
884            (r'/\*.*?\*/', Comment.Multiline),
885            (r'@[a-zA-Z_][\w.]*', Name.Decorator),
886            (r'(break|case|catch|next|default|do|else|finally|for|foreach|of|'
887             r'unless|if|new|return|switch|me|throw|try|while)\b', Keyword),
888            (r'(extends|private|protected|public|static|throws|function|method|'
889             r'operator)\b', Keyword.Declaration),
890            (r'(true|false|null|__FILE__|__LINE__|__VERSION__|__LIB_PATH__|'
891             r'__INC_PATH__)\b', Keyword.Constant),
892            (r'(class|struct)(\s+)',
893             bygroups(Keyword.Declaration, Text), 'class'),
894            (r'(import|include)(\s+)',
895             bygroups(Keyword.Namespace, Text), 'import'),
896            (words((
897                'gc_collect', 'gc_mm_items', 'gc_mm_usage', 'gc_collect_threshold',
898                'urlencode', 'urldecode', 'base64encode', 'base64decode', 'sha1', 'crc32',
899                'sha2', 'md5', 'md5_file', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos',
900                'cosh', 'exp', 'fabs', 'floor', 'fmod', 'log', 'log10', 'pow', 'sin',
901                'sinh', 'sqrt', 'tan', 'tanh', 'isint', 'isfloat', 'ischar', 'isstring',
902                'isarray', 'ismap', 'isalias', 'typeof', 'sizeof', 'toint', 'tostring',
903                'fromxml', 'toxml', 'binary', 'pack', 'load', 'eval', 'var_names',
904                'var_values', 'user_functions', 'dyn_functions', 'methods', 'call',
905                'call_method', 'mknod', 'mkfifo', 'mount', 'umount2', 'umount', 'ticks',
906                'usleep', 'sleep', 'time', 'strtime', 'strdate', 'dllopen', 'dlllink',
907                'dllcall', 'dllcall_argv', 'dllclose', 'env', 'exec', 'fork', 'getpid',
908                'wait', 'popen', 'pclose', 'exit', 'kill', 'pthread_create',
909                'pthread_create_argv', 'pthread_exit', 'pthread_join', 'pthread_kill',
910                'smtp_send', 'http_get', 'http_post', 'http_download', 'socket', 'bind',
911                'listen', 'accept', 'getsockname', 'getpeername', 'settimeout', 'connect',
912                'server', 'recv', 'send', 'close', 'print', 'println', 'printf', 'input',
913                'readline', 'serial_open', 'serial_fcntl', 'serial_get_attr',
914                'serial_get_ispeed', 'serial_get_ospeed', 'serial_set_attr',
915                'serial_set_ispeed', 'serial_set_ospeed', 'serial_write', 'serial_read',
916                'serial_close', 'xml_load', 'xml_parse', 'fopen', 'fseek', 'ftell',
917                'fsize', 'fread', 'fwrite', 'fgets', 'fclose', 'file', 'readdir',
918                'pcre_replace', 'size', 'pop', 'unmap', 'has', 'keys', 'values',
919                'length', 'find', 'substr', 'replace', 'split', 'trim', 'remove',
920                'contains', 'join'), suffix=r'\b'),
921             Name.Builtin),
922            (words((
923                'MethodReference', 'Runner', 'Dll', 'Thread', 'Pipe', 'Process',
924                'Runnable', 'CGI', 'ClientSocket', 'Socket', 'ServerSocket',
925                'File', 'Console', 'Directory', 'Exception'), suffix=r'\b'),
926             Keyword.Type),
927            (r'"(\\\\|\\"|[^"])*"', String),
928            (r"'\\.'|'[^\\]'|'\\u[0-9a-f]{4}'", String.Char),
929            (r'(\.)([a-zA-Z_]\w*)',
930             bygroups(Operator, Name.Attribute)),
931            (r'[a-zA-Z_]\w*:', Name.Label),
932            (r'[a-zA-Z_$]\w*', Name),
933            (r'[~^*!%&\[\](){}<>|+=:;,./?\-@]+', Operator),
934            (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
935            (r'0x[0-9a-f]+', Number.Hex),
936            (r'[0-9]+L?', Number.Integer),
937            (r'\n', Text),
938        ],
939        'class': [
940            (r'[a-zA-Z_]\w*', Name.Class, '#pop')
941        ],
942        'import': [
943            (r'[\w.]+\*?', Name.Namespace, '#pop')
944        ],
945    }
946
947    def analyse_text(text):
948        """public method and private method don't seem to be quite common
949        elsewhere."""
950        result = 0
951        if re.search(r'\b(?:public|private)\s+method\b', text):
952            result += 0.01
953        return result
954
955
956
957class EasytrieveLexer(RegexLexer):
958    """
959    Easytrieve Plus is a programming language for extracting, filtering and
960    converting sequential data. Furthermore it can layout data for reports.
961    It is mainly used on mainframe platforms and can access several of the
962    mainframe's native file formats. It is somewhat comparable to awk.
963
964    .. versionadded:: 2.1
965    """
966    name = 'Easytrieve'
967    aliases = ['easytrieve']
968    filenames = ['*.ezt', '*.mac']
969    mimetypes = ['text/x-easytrieve']
970    flags = 0
971
972    # Note: We cannot use r'\b' at the start and end of keywords because
973    # Easytrieve Plus delimiter characters are:
974    #
975    #   * space ( )
976    #   * apostrophe (')
977    #   * period (.)
978    #   * comma (,)
979    #   * paranthesis ( and )
980    #   * colon (:)
981    #
982    # Additionally words end once a '*' appears, indicatins a comment.
983    _DELIMITERS = r' \'.,():\n'
984    _DELIMITERS_OR_COMENT = _DELIMITERS + '*'
985    _DELIMITER_PATTERN = '[' + _DELIMITERS + ']'
986    _DELIMITER_PATTERN_CAPTURE = '(' + _DELIMITER_PATTERN + ')'
987    _NON_DELIMITER_OR_COMMENT_PATTERN = '[^' + _DELIMITERS_OR_COMENT + ']'
988    _OPERATORS_PATTERN = '[.+\\-/=\\[\\](){}<>;,&%¬]'
989    _KEYWORDS = [
990        'AFTER-BREAK', 'AFTER-LINE', 'AFTER-SCREEN', 'AIM', 'AND', 'ATTR',
991        'BEFORE', 'BEFORE-BREAK', 'BEFORE-LINE', 'BEFORE-SCREEN', 'BUSHU',
992        'BY', 'CALL', 'CASE', 'CHECKPOINT', 'CHKP', 'CHKP-STATUS', 'CLEAR',
993        'CLOSE', 'COL', 'COLOR', 'COMMIT', 'CONTROL', 'COPY', 'CURSOR', 'D',
994        'DECLARE', 'DEFAULT', 'DEFINE', 'DELETE', 'DENWA', 'DISPLAY', 'DLI',
995        'DO', 'DUPLICATE', 'E', 'ELSE', 'ELSE-IF', 'END', 'END-CASE',
996        'END-DO', 'END-IF', 'END-PROC', 'ENDPAGE', 'ENDTABLE', 'ENTER', 'EOF',
997        'EQ', 'ERROR', 'EXIT', 'EXTERNAL', 'EZLIB', 'F1', 'F10', 'F11', 'F12',
998        'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F2', 'F20', 'F21',
999        'F22', 'F23', 'F24', 'F25', 'F26', 'F27', 'F28', 'F29', 'F3', 'F30',
1000        'F31', 'F32', 'F33', 'F34', 'F35', 'F36', 'F4', 'F5', 'F6', 'F7',
1001        'F8', 'F9', 'FETCH', 'FILE-STATUS', 'FILL', 'FINAL', 'FIRST',
1002        'FIRST-DUP', 'FOR', 'GE', 'GET', 'GO', 'GOTO', 'GQ', 'GR', 'GT',
1003        'HEADING', 'HEX', 'HIGH-VALUES', 'IDD', 'IDMS', 'IF', 'IN', 'INSERT',
1004        'JUSTIFY', 'KANJI-DATE', 'KANJI-DATE-LONG', 'KANJI-TIME', 'KEY',
1005        'KEY-PRESSED', 'KOKUGO', 'KUN', 'LAST-DUP', 'LE', 'LEVEL', 'LIKE',
1006        'LINE', 'LINE-COUNT', 'LINE-NUMBER', 'LINK', 'LIST', 'LOW-VALUES',
1007        'LQ', 'LS', 'LT', 'MACRO', 'MASK', 'MATCHED', 'MEND', 'MESSAGE',
1008        'MOVE', 'MSTART', 'NE', 'NEWPAGE', 'NOMASK', 'NOPRINT', 'NOT',
1009        'NOTE', 'NOVERIFY', 'NQ', 'NULL', 'OF', 'OR', 'OTHERWISE', 'PA1',
1010        'PA2', 'PA3', 'PAGE-COUNT', 'PAGE-NUMBER', 'PARM-REGISTER',
1011        'PATH-ID', 'PATTERN', 'PERFORM', 'POINT', 'POS', 'PRIMARY', 'PRINT',
1012        'PROCEDURE', 'PROGRAM', 'PUT', 'READ', 'RECORD', 'RECORD-COUNT',
1013        'RECORD-LENGTH', 'REFRESH', 'RELEASE', 'RENUM', 'REPEAT', 'REPORT',
1014        'REPORT-INPUT', 'RESHOW', 'RESTART', 'RETRIEVE', 'RETURN-CODE',
1015        'ROLLBACK', 'ROW', 'S', 'SCREEN', 'SEARCH', 'SECONDARY', 'SELECT',
1016        'SEQUENCE', 'SIZE', 'SKIP', 'SOKAKU', 'SORT', 'SQL', 'STOP', 'SUM',
1017        'SYSDATE', 'SYSDATE-LONG', 'SYSIN', 'SYSIPT', 'SYSLST', 'SYSPRINT',
1018        'SYSSNAP', 'SYSTIME', 'TALLY', 'TERM-COLUMNS', 'TERM-NAME',
1019        'TERM-ROWS', 'TERMINATION', 'TITLE', 'TO', 'TRANSFER', 'TRC',
1020        'UNIQUE', 'UNTIL', 'UPDATE', 'UPPERCASE', 'USER', 'USERID', 'VALUE',
1021        'VERIFY', 'W', 'WHEN', 'WHILE', 'WORK', 'WRITE', 'X', 'XDM', 'XRST'
1022    ]
1023
1024    tokens = {
1025        'root': [
1026            (r'\*.*\n', Comment.Single),
1027            (r'\n+', Whitespace),
1028            # Macro argument
1029            (r'&' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+\.', Name.Variable,
1030             'after_macro_argument'),
1031            # Macro call
1032            (r'%' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name.Variable),
1033            (r'(FILE|MACRO|REPORT)(\s+)',
1034             bygroups(Keyword.Declaration, Whitespace), 'after_declaration'),
1035            (r'(JOB|PARM)' + r'(' + _DELIMITER_PATTERN + r')',
1036             bygroups(Keyword.Declaration, Operator)),
1037            (words(_KEYWORDS, suffix=_DELIMITER_PATTERN_CAPTURE),
1038             bygroups(Keyword.Reserved, Operator)),
1039            (_OPERATORS_PATTERN, Operator),
1040            # Procedure declaration
1041            (r'(' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+)(\s*)(\.?)(\s*)(PROC)(\s*\n)',
1042             bygroups(Name.Function, Whitespace, Operator, Whitespace,
1043                      Keyword.Declaration, Whitespace)),
1044            (r'[0-9]+\.[0-9]*', Number.Float),
1045            (r'[0-9]+', Number.Integer),
1046            (r"'(''|[^'])*'", String),
1047            (r'\s+', Whitespace),
1048            # Everything else just belongs to a name
1049            (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name),
1050         ],
1051        'after_declaration': [
1052            (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name.Function),
1053            default('#pop'),
1054        ],
1055        'after_macro_argument': [
1056            (r'\*.*\n', Comment.Single, '#pop'),
1057            (r'\s+', Whitespace, '#pop'),
1058            (_OPERATORS_PATTERN, Operator, '#pop'),
1059            (r"'(''|[^'])*'", String, '#pop'),
1060            # Everything else just belongs to a name
1061            (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name),
1062        ],
1063    }
1064    _COMMENT_LINE_REGEX = re.compile(r'^\s*\*')
1065    _MACRO_HEADER_REGEX = re.compile(r'^\s*MACRO')
1066
1067    def analyse_text(text):
1068        """
1069        Perform a structural analysis for basic Easytrieve constructs.
1070        """
1071        result = 0.0
1072        lines = text.split('\n')
1073        hasEndProc = False
1074        hasHeaderComment = False
1075        hasFile = False
1076        hasJob = False
1077        hasProc = False
1078        hasParm = False
1079        hasReport = False
1080
1081        def isCommentLine(line):
1082            return EasytrieveLexer._COMMENT_LINE_REGEX.match(lines[0]) is not None
1083
1084        def isEmptyLine(line):
1085            return not bool(line.strip())
1086
1087        # Remove possible empty lines and header comments.
1088        while lines and (isEmptyLine(lines[0]) or isCommentLine(lines[0])):
1089            if not isEmptyLine(lines[0]):
1090                hasHeaderComment = True
1091            del lines[0]
1092
1093        if EasytrieveLexer._MACRO_HEADER_REGEX.match(lines[0]):
1094            # Looks like an Easytrieve macro.
1095            result = 0.4
1096            if hasHeaderComment:
1097                result += 0.4
1098        else:
1099            # Scan the source for lines starting with indicators.
1100            for line in lines:
1101                words = line.split()
1102                if (len(words) >= 2):
1103                    firstWord = words[0]
1104                    if not hasReport:
1105                        if not hasJob:
1106                            if not hasFile:
1107                                if not hasParm:
1108                                    if firstWord == 'PARM':
1109                                        hasParm = True
1110                                if firstWord == 'FILE':
1111                                    hasFile = True
1112                            if firstWord == 'JOB':
1113                                hasJob = True
1114                        elif firstWord == 'PROC':
1115                            hasProc = True
1116                        elif firstWord == 'END-PROC':
1117                            hasEndProc = True
1118                        elif firstWord == 'REPORT':
1119                            hasReport = True
1120
1121            # Weight the findings.
1122            if hasJob and (hasProc == hasEndProc):
1123                if hasHeaderComment:
1124                    result += 0.1
1125                if hasParm:
1126                    if hasProc:
1127                        # Found PARM, JOB and PROC/END-PROC:
1128                        # pretty sure this is Easytrieve.
1129                        result += 0.8
1130                    else:
1131                        # Found PARAM and  JOB: probably this is Easytrieve
1132                        result += 0.5
1133                else:
1134                    # Found JOB and possibly other keywords: might be Easytrieve
1135                    result += 0.11
1136                    if hasParm:
1137                        # Note: PARAM is not a proper English word, so this is
1138                        # regarded a much better indicator for Easytrieve than
1139                        # the other words.
1140                        result += 0.2
1141                    if hasFile:
1142                        result += 0.01
1143                    if hasReport:
1144                        result += 0.01
1145        assert 0.0 <= result <= 1.0
1146        return result
1147
1148
1149class JclLexer(RegexLexer):
1150    """
1151    `Job Control Language (JCL)
1152    <http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IEA2B570/CCONTENTS>`_
1153    is a scripting language used on mainframe platforms to instruct the system
1154    on how to run a batch job or start a subsystem. It is somewhat
1155    comparable to MS DOS batch and Unix shell scripts.
1156
1157    .. versionadded:: 2.1
1158    """
1159    name = 'JCL'
1160    aliases = ['jcl']
1161    filenames = ['*.jcl']
1162    mimetypes = ['text/x-jcl']
1163    flags = re.IGNORECASE
1164
1165    tokens = {
1166        'root': [
1167            (r'//\*.*\n', Comment.Single),
1168            (r'//', Keyword.Pseudo, 'statement'),
1169            (r'/\*', Keyword.Pseudo, 'jes2_statement'),
1170            # TODO: JES3 statement
1171            (r'.*\n', Other)  # Input text or inline code in any language.
1172        ],
1173        'statement': [
1174            (r'\s*\n', Whitespace, '#pop'),
1175            (r'([a-z]\w*)(\s+)(exec|job)(\s*)',
1176             bygroups(Name.Label, Whitespace, Keyword.Reserved, Whitespace),
1177             'option'),
1178            (r'[a-z]\w*', Name.Variable, 'statement_command'),
1179            (r'\s+', Whitespace, 'statement_command'),
1180        ],
1181        'statement_command': [
1182            (r'\s+(command|cntl|dd|endctl|endif|else|include|jcllib|'
1183             r'output|pend|proc|set|then|xmit)\s+', Keyword.Reserved, 'option'),
1184            include('option')
1185        ],
1186        'jes2_statement': [
1187            (r'\s*\n', Whitespace, '#pop'),
1188            (r'\$', Keyword, 'option'),
1189            (r'\b(jobparam|message|netacct|notify|output|priority|route|'
1190             r'setup|signoff|xeq|xmit)\b', Keyword, 'option'),
1191        ],
1192        'option': [
1193            # (r'\n', Text, 'root'),
1194            (r'\*', Name.Builtin),
1195            (r'[\[\](){}<>;,]', Punctuation),
1196            (r'[-+*/=&%]', Operator),
1197            (r'[a-z_]\w*', Name),
1198            (r'\d+\.\d*', Number.Float),
1199            (r'\.\d+', Number.Float),
1200            (r'\d+', Number.Integer),
1201            (r"'", String, 'option_string'),
1202            (r'[ \t]+', Whitespace, 'option_comment'),
1203            (r'\.', Punctuation),
1204        ],
1205        'option_string': [
1206            (r"(\n)(//)", bygroups(Text, Keyword.Pseudo)),
1207            (r"''", String),
1208            (r"[^']", String),
1209            (r"'", String, '#pop'),
1210        ],
1211        'option_comment': [
1212            # (r'\n', Text, 'root'),
1213            (r'.+', Comment.Single),
1214        ]
1215    }
1216
1217    _JOB_HEADER_PATTERN = re.compile(r'^//[a-z#$@][a-z0-9#$@]{0,7}\s+job(\s+.*)?$',
1218                                     re.IGNORECASE)
1219
1220    def analyse_text(text):
1221        """
1222        Recognize JCL job by header.
1223        """
1224        result = 0.0
1225        lines = text.split('\n')
1226        if len(lines) > 0:
1227            if JclLexer._JOB_HEADER_PATTERN.match(lines[0]):
1228                result = 1.0
1229        assert 0.0 <= result <= 1.0
1230        return result
1231
1232
1233class MiniScriptLexer(RegexLexer):
1234    """
1235    For `MiniScript <https://miniscript.org>`_ source code.
1236
1237    .. versionadded:: 2.6
1238    """
1239
1240    name = "MiniScript"
1241    aliases = ["ms", "miniscript"]
1242    filenames = ["*.ms"]
1243    mimetypes = ['text/x-minicript', 'application/x-miniscript']
1244
1245    tokens = {
1246        'root': [
1247            (r'#!(.*?)$', Comment.Preproc),
1248            default('base'),
1249        ],
1250        'base': [
1251            ('//.*$', Comment.Single),
1252            (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number),
1253            (r'(?i)\d+e[+-]?\d+', Number),
1254            (r'\d+', Number),
1255            (r'\n', Text),
1256            (r'[^\S\n]+', Text),
1257            (r'"', String, 'string_double'),
1258            (r'(==|!=|<=|>=|[=+\-*/%^<>.:])', Operator),
1259            (r'[;,\[\]{}()]', Punctuation),
1260            (words((
1261                'break', 'continue', 'else', 'end', 'for', 'function', 'if',
1262                'in', 'isa', 'then', 'repeat', 'return', 'while'), suffix=r'\b'),
1263             Keyword),
1264            (words((
1265                'abs', 'acos', 'asin', 'atan', 'ceil', 'char', 'cos', 'floor',
1266                'log', 'round', 'rnd', 'pi', 'sign', 'sin', 'sqrt', 'str', 'tan',
1267                'hasIndex', 'indexOf', 'len', 'val', 'code', 'remove', 'lower',
1268                'upper', 'replace', 'split', 'indexes', 'values', 'join', 'sum',
1269                'sort', 'shuffle', 'push', 'pop', 'pull', 'range',
1270                'print', 'input', 'time', 'wait', 'locals', 'globals', 'outer',
1271                'yield'), suffix=r'\b'),
1272             Name.Builtin),
1273            (r'(true|false|null)\b', Keyword.Constant),
1274            (r'(and|or|not|new)\b', Operator.Word),
1275            (r'(self|super|__isa)\b', Name.Builtin.Pseudo),
1276            (r'[a-zA-Z_]\w*', Name.Variable)
1277        ],
1278        'string_double': [
1279            (r'[^"\n]+', String),
1280            (r'""', String),
1281            (r'"', String, '#pop'),
1282            (r'\n', Text, '#pop'),  # Stray linefeed also terminates strings.
1283        ]
1284    }
1285