diff --git a/docs/source/conf.py b/docs/source/conf.py index de8d5282..316c92b9 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -21,6 +21,7 @@ "sphinx_design", "sphinxcontrib.youtube", "sphinx_copybutton", + "sphinx_rsquirrel", ] intersphinx_mapping = { @@ -58,3 +59,5 @@ # -- Options for EPUB output epub_show_urls = "footnote" + +highlight_language = "squirrel" diff --git a/docs/source/guides/gettingstarted.rst b/docs/source/guides/gettingstarted.rst index eae1db37..8f6ae98b 100644 --- a/docs/source/guides/gettingstarted.rst +++ b/docs/source/guides/gettingstarted.rst @@ -199,7 +199,7 @@ configuration file. When starting a match, ``Northstar.CustomServers`` mod will retrieve the configuration variable value, or its default value if it hasn't been specified in configuration file: -.. code-block:: javascript +.. code-block:: // start countdown SetUIVar( level, "gameStartTime", Time() + GetConVarFloat( "ns_private_match_countdown_length" ) ) diff --git a/docs/source/guides/keyvalue/localisation.rst b/docs/source/guides/keyvalue/localisation.rst index 8f1da083..5bc02a93 100644 --- a/docs/source/guides/keyvalue/localisation.rst +++ b/docs/source/guides/keyvalue/localisation.rst @@ -82,19 +82,19 @@ translation keys, preceded by a ``#``. For example, to translate the "Launch Northstar" button on main menu, instead of calling: -.. code-block:: javascript +.. code-block:: AddComboButton( comboStruct, headerIndex, buttonIndex++, "Launch Northstar" ) We'll use: -.. code-block:: javascript +.. code-block:: AddComboButton( comboStruct, headerIndex, buttonIndex++, "#MENU_LAUNCH_NORTHSTAR" ) You can also use the ``Localize`` method client-side: -.. code-block:: javascript +.. code-block:: Localize( "#MENU_LAUNCH_NORTHSTAR" ) diff --git a/docs/source/guides/scripting/gamemodemods.rst b/docs/source/guides/scripting/gamemodemods.rst index 77ea9ff3..1d052e3b 100644 --- a/docs/source/guides/scripting/gamemodemods.rst +++ b/docs/source/guides/scripting/gamemodemods.rst @@ -124,7 +124,7 @@ Shared functions ---------------- Let's begin the process by first creating the file ``sh_gamemode_simplerandomiser.nut`` and making the core components of the gamemode, which is to define the gamemode properties. -.. code-block:: javascript +.. code-block:: global function simplerandomiser_init // initializing functions global const string GAMEMODE_SIMPLERANDOMISER = "rand" @@ -194,7 +194,7 @@ Server-side function -------------------- Now that we're down with defining the gamemode, its time to focus on the component on what makes the gamemode function in-game. For this, it will be mostly handled by the server scripts, so head into ``_gamemode_simplerandomiser.nut`` to begin writing the randomizing script. -.. code-block:: javascript +.. code-block:: global function GamemodeRand_Init @@ -214,7 +214,7 @@ Now that our initial function is created, we now have the game triggering `GiveR Firstly, we need to know what weapons we can equip. For this we define an array: -.. code-block:: javascript +.. code-block:: array pilotWeapons = ["mp_weapon_alternator_smg", "mp_weapon_autopistol", @@ -228,7 +228,7 @@ Randomise function As we already know its going to call the function ``GiveRandomGun`` when a player respawns, let's define that now. First we strip any existing weapons: -.. code-block:: javascript +.. code-block:: void function GiveRandomGun(entity player) { @@ -239,14 +239,14 @@ This iterates through each weapon (that being the primary, secondary and anti-ti Then lets give them a new, random weapon by selecting a random item from our previous array: -.. code-block:: javascript +.. code-block:: player.GiveWeapon( pilotWeapons[ RandomInt( pilotWeapons.len() ) ] ) Now, remember the server callback that we defined earlier in ``sh_gamemode_simplerandomiser.nut``? Let's put that to use. We are going to make it so the player receives an announcement whenever they have their weapons randomized. -.. code-block:: javascript +.. code-block:: // checks if the toggle option is set to enabled if ( GetCurrentPlaylistVarInt( "rand_enableannouncements", 1 ) == 1 ) @@ -254,7 +254,7 @@ We are going to make it so the player receives an announcement whenever they hav Overall, the server script should look like this. -.. code-block:: javascript +.. code-block:: global function GamemodeRand_Init @@ -291,7 +291,7 @@ Client-side functions ------------------ Lastly, for your ``cl_gamemode_simplerandomiser.nut``, we are going to utilize the callback functions from earlier, as well as add some music to play during the gamemode. -.. code-block:: javascript +.. code-block:: global function ClGamemodeRand_Init global function ServerCallback_Randomiser @@ -370,7 +370,7 @@ Yes, you will need to create a folder called ``keyvalues`` which is separate fro Next, inside this ``playlist_v2.txt``, we will need to allow/disallow what maps can the gamemode be played on. -.. code-block:: +.. code-block:: text playlists { diff --git a/docs/source/guides/tools/VTFModding.rst b/docs/source/guides/tools/VTFModding.rst index 34621de5..9a83d1cc 100644 --- a/docs/source/guides/tools/VTFModding.rst +++ b/docs/source/guides/tools/VTFModding.rst @@ -75,14 +75,14 @@ Creating VMT In the same folder you extracted your mdl's. Make a ``materials`` folder next to the ``models`` folder. Example: -:: +.. code-block:: text models materials Recreate the path you changed in the ``materials`` folder, such that the last section is a .vmt file: -:: +.. code-block:: text materials └─ models @@ -91,7 +91,7 @@ Recreate the path you changed in the ``materials`` folder, such that the last se └─ car_ctm.vmt Inside your .vmt paste: -:: +.. code-block:: text "UnlitTwoTexture" { @@ -141,7 +141,7 @@ Final VPK folder Your root folder should look somewhat like this -:: +.. code-block:: text root ├─ materials @@ -172,7 +172,8 @@ To add animation functionality, all we need to do is add a Proxie; which is just You need to create a .vtf texture with multiple frames imported to a single .vtf texture, that's your animated texture. You can do this with `VTFEdit`_. Then assign the texture in ``$basetexture``. At the bottom of your vmt but before the ``}``, add this: -:: +.. code-block:: text + "Proxies" { AnimatedTexture @@ -183,4 +184,5 @@ At the bottom of your vmt but before the ``}``, add this: } } + To change the fps of the texture, change the value after ``animatedTextureFrameRate``, and you'll be done making your texture animated! \ No newline at end of file diff --git a/docs/source/guides/tools/rpakmodding.rst b/docs/source/guides/tools/rpakmodding.rst index 46881e84..cc114fab 100644 --- a/docs/source/guides/tools/rpakmodding.rst +++ b/docs/source/guides/tools/rpakmodding.rst @@ -33,7 +33,7 @@ Once it has been downloaded, it is recommended to set up your file structure as Depending on the version of RePak, some of these folders and files might be already there for you -.. code-block:: +.. code-block:: text RePak ├── RePak.exe @@ -241,7 +241,7 @@ The file structure of your ``paks`` folder should be similar to this: |PaksStructure| -.. code-block:: +.. code-block:: text paks ├── example.rpak diff --git a/docs/source/guides/tools/soundmodding.rst b/docs/source/guides/tools/soundmodding.rst index 1a2ebab7..7a8a2561 100644 --- a/docs/source/guides/tools/soundmodding.rst +++ b/docs/source/guides/tools/soundmodding.rst @@ -53,7 +53,7 @@ When you successfully identified your event and have the audio file/s ready it's time to set up the folder structure. Assuming the event name is ``pilot_grapple_fire``, the folder structure of your mod should look like this: -.. code-block:: +.. code-block:: text author.mod/ ├── audio/ diff --git a/docs/source/reference/northstar/chathooks.rst b/docs/source/reference/northstar/chathooks.rst index b556cc24..0dd5cd6f 100644 --- a/docs/source/reference/northstar/chathooks.rst +++ b/docs/source/reference/northstar/chathooks.rst @@ -55,7 +55,7 @@ The client chat callbacks allow you to intercept chat messages and modify or blo **Example:** - .. code-block:: javascript + .. code-block:: ClClient_MessageStruct function MyChatFilter(ClClient_MessageStruct message) { @@ -87,7 +87,7 @@ players, they only display them locally. **Example:** - .. code-block:: javascript + .. code-block:: void function OnGameStarted() { @@ -101,7 +101,7 @@ players, they only display them locally. **Example:** - .. code-block:: javascript + .. code-block:: void function InitialiseHEVSuit() { @@ -122,7 +122,7 @@ players, they only display them locally. **Example:** - .. code-block:: javascript + .. code-block:: void function MyModInit() { @@ -136,7 +136,7 @@ players, they only display them locally. **Example:** - .. code-block:: javascript + .. code-block:: void function OnButtonPressed() { @@ -193,7 +193,7 @@ The server chat callbacks allow you to intercept incoming chat messages and modi **Example:** - .. code-block:: javascript + .. code-block:: ClServer_MessageStruct function MyChatFilter(ClServer_MessageStruct message) { @@ -230,7 +230,7 @@ With custom messages you can send chat messages at any time, to all players or t **Example:** - .. code-block:: javascript + .. code-block:: void function OnSayRedCommand(entity player, string text) { @@ -252,7 +252,7 @@ With custom messages you can send chat messages at any time, to all players or t **Example:** - .. code-block:: javascript + .. code-block:: void function OnSendToFriendsCommand(entity fromPlayer, string text) { @@ -275,7 +275,7 @@ With custom messages you can send chat messages at any time, to all players or t **Example:** - .. code-block:: javascript + .. code-block:: void function RestartServerThread() { @@ -308,7 +308,7 @@ With custom messages you can send chat messages at any time, to all players or t **Example:** - .. code-block:: javascript + .. code-block:: void function OnBanCommand(entity player, array args) { @@ -330,7 +330,7 @@ ANSI Escape Codes All messages support ANSI escape codes for customising text color. These are commands in strings that have special meaning. For example, the string: -.. code-block:: +.. code-block:: text Hello world, \x1b[31mthis text is red\x1b[0m. And \x1b[34mthis text is blue\x1b[0m. diff --git a/docs/source/reference/northstar/dependencyconstants.rst b/docs/source/reference/northstar/dependencyconstants.rst index b3de2f1b..aa5bcc0a 100644 --- a/docs/source/reference/northstar/dependencyconstants.rst +++ b/docs/source/reference/northstar/dependencyconstants.rst @@ -18,13 +18,13 @@ Contditons you can check for are These conditions can also be combined with the regular squirrel boolean expressions -.. code-block:: javascript +.. code-block:: #if SERVER Chat_ServerBroadcast("Message from the server VM") #endif -.. code-block:: javascript +.. code-block:: #if (CLIENT && MP) || DEV ... @@ -40,7 +40,7 @@ loaded, these use the Compiler directives syntax. Inside your ``mod.json`` define a constant as: -.. code-block:: javascript +.. code-block:: { // mod.json stuff @@ -52,14 +52,14 @@ Inside your ``mod.json`` define a constant as: For Example: -.. code-block:: javascript +.. code-block:: "PLAYER_HAS_ROGUELIKE_MOD": "TF|Roguelike" Will define a constant ``PLAYER_HAS_ROGUELIKE_MOD`` that is set to ``0`` or ``1`` depending if the mod is enabled. It then can be used as a constant/compiler flag. -.. code-block:: csharp +.. code-block:: #if PLAYER_HAS_ROGUELIKE_MOD print("player has roguelike mod") diff --git a/docs/source/reference/northstar/httprequests.rst b/docs/source/reference/northstar/httprequests.rst index 8e7659a8..11fe3f29 100644 --- a/docs/source/reference/northstar/httprequests.rst +++ b/docs/source/reference/northstar/httprequests.rst @@ -195,7 +195,7 @@ Functions Lambdas are particularly useful as they let you capture local variables of the functions to re-use later such as ``callback`` in this example. - .. code-block:: javascript + .. code-block:: HttpRequest request request.method = HttpRequestMethod.GET @@ -239,7 +239,7 @@ Functions This is the same example as NSHttpRequest()'s example. However, it uses this function instead. - .. code-block:: javascript + .. code-block:: table > params params[ "id" ] <- [ id.tostring() ] @@ -302,7 +302,7 @@ Functions In this example, we'll convert a table to JSON, and send it over to a web API. - .. code-block:: javascript + .. code-block:: table myData = {} myData[ "uid" ] <- player.GetUID() diff --git a/docs/source/reference/northstar/serversiderui.rst b/docs/source/reference/northstar/serversiderui.rst index 38da6622..da9d9b90 100644 --- a/docs/source/reference/northstar/serversiderui.rst +++ b/docs/source/reference/northstar/serversiderui.rst @@ -22,7 +22,7 @@ Creates a poll on ``player``. **Example:** -.. code-block:: javascript +.. code-block:: void function CreateDummyPoll() { @@ -42,7 +42,7 @@ Returns the index of the item from ``options`` the player voted for. If the play **Example:** -.. code-block:: javascript +.. code-block:: void function CheckResponseToDummyPoll(entity player) { @@ -67,7 +67,7 @@ Sends a large message to ``player`` which will appear in the top right corner. **Example:** -.. code-block:: javascript +.. code-block:: void function SendDummyLargeMessage(entity player) { @@ -91,7 +91,7 @@ Sends a smaller message to ``player`` which will appear from the center right. **Example:** -.. code-block:: javascript +.. code-block:: void function SendDummyInfoMessage(entity player) { @@ -115,7 +115,7 @@ Send a small popup to ``player`` which will appear in the lower half of their sc **Example:** -.. code-block:: javascript +.. code-block:: void funcions SendDummyPopUp(entity player) { @@ -139,7 +139,7 @@ Sends a large announcement to ``player``. **Example:** -.. code-block:: javascript +.. code-block:: void function SendDummyAnnouncement(entity player) { @@ -175,7 +175,7 @@ Deletes the status message which was created with ``id`` **Examples:** -.. code-block:: javascript +.. code-block:: void function TestStatusMessage_Threaded(entity player) { diff --git a/docs/source/reference/northstar/usefulfuncs.rst b/docs/source/reference/northstar/usefulfuncs.rst index d8ac4513..7a9b4d6c 100644 --- a/docs/source/reference/northstar/usefulfuncs.rst +++ b/docs/source/reference/northstar/usefulfuncs.rst @@ -378,7 +378,7 @@ String replaces text that should be localzied on the client - .. code-block:: javascript + .. code-block:: string localized = Localize( token ) @@ -390,7 +390,7 @@ String You can eliminate the possibility of the returned index being null by casting like this: - .. code-block:: javascript + .. code-block:: int ornull index = GetMapName().find( "mp" ) diff --git a/docs/source/reference/respawn/clientcommands.rst b/docs/source/reference/respawn/clientcommands.rst index 2ed03c13..ec9ab725 100644 --- a/docs/source/reference/respawn/clientcommands.rst +++ b/docs/source/reference/respawn/clientcommands.rst @@ -7,7 +7,7 @@ Client commands are how the clients communicate with the server. Mods can define Registers a function as a callback for a client command. This can only be done once per client command string. - .. code-block:: javascript + .. code-block:: AddClientCommandCallback("commandname", commandcallback) diff --git a/docs/source/reference/respawn/hud_element_notation.rst b/docs/source/reference/respawn/hud_element_notation.rst index 773322d4..3fe71341 100644 --- a/docs/source/reference/respawn/hud_element_notation.rst +++ b/docs/source/reference/respawn/hud_element_notation.rst @@ -445,7 +445,7 @@ Usable conditions are: the game's language. - .. code-block:: + .. code-block:: text // use allcaps only in russian allCaps 0 [!$RUSSIAN] @@ -458,7 +458,7 @@ On top of that, logical operators like ``!``, ``&&`` and ``||`` are available as Example: ^^^^ -.. code-block:: +.. code-block:: text // This element only shows on pc IngameTextChat [$WINDOWS] diff --git a/docs/source/reference/respawn/hud_menus.rst b/docs/source/reference/respawn/hud_menus.rst index 4287def7..8af1699f 100644 --- a/docs/source/reference/respawn/hud_menus.rst +++ b/docs/source/reference/respawn/hud_menus.rst @@ -20,7 +20,7 @@ In your ``mod.json``, add a ``Before`` UI callback like this: In the script you referenced, create a global in which you register your menu with the ``AddMenu`` like this: -.. code-block:: javascript +.. code-block:: global InitProfilesMenu @@ -35,7 +35,7 @@ The returns ``void`` and takes no parameters. It gets called once the menu is in It's recommended to create a file struct in which you store menu states: -.. code-block:: javascript +.. code-block:: struct { var menu diff --git a/docs/source/reference/respawn/movers.rst b/docs/source/reference/respawn/movers.rst index 49420830..ee38bb7f 100644 --- a/docs/source/reference/respawn/movers.rst +++ b/docs/source/reference/respawn/movers.rst @@ -65,7 +65,7 @@ Behaviour Examples -------- -.. code-block:: javascript +.. code-block:: entity mover = CreateScriptMover( <0,0,0> ) @@ -82,7 +82,7 @@ Examples wait 0.5 mover.NonPhysicsStop() -.. code-block:: javascript +.. code-block:: // creating a elevator // using a mover with a model @@ -100,7 +100,7 @@ Examples } -.. code-block:: javascript +.. code-block:: // Phase shifting the player to a destination // setting a position diff --git a/docs/source/reference/respawn/rui.rst b/docs/source/reference/respawn/rui.rst index 04736ca4..3325967f 100644 --- a/docs/source/reference/respawn/rui.rst +++ b/docs/source/reference/respawn/rui.rst @@ -3,7 +3,7 @@ Rui Functions for creating a rui, and methods of the rui object -.. code-block:: javascript +.. code-block:: // To create one, do: rui = RuiCreate( $"ui/assetname.rpak", topology, drawGroup, sortKey ) // sortkey = int to prevent z-fighting. higher -> in front @@ -23,7 +23,7 @@ Functions for creating a rui, and methods of the rui object Drawgroups -.. code-block:: javascript +.. code-block:: RUI_DRAW_WORLD RUI_DRAW_HUD @@ -32,7 +32,7 @@ Drawgroups Trackers -.. code-block:: javascript +.. code-block:: // VECTOR TYPES RUI_TRACK_ABSORIGIN_FOLLOW // Create at absorigin, and update to follow the entity @@ -92,7 +92,7 @@ Trackers .. cpp:function:: void RuiSetResolution(rui, screenSizeX, screenSizey) - .. code-block:: javascript + .. code-block:: screenSizeX = GetScreenSize()[0] screenSizeY = GetScreenSize()[1] diff --git a/docs/source/reference/respawn/titan.rst b/docs/source/reference/respawn/titan.rst index bde3c08d..667899ce 100644 --- a/docs/source/reference/respawn/titan.rst +++ b/docs/source/reference/respawn/titan.rst @@ -3,7 +3,7 @@ Titan Functions for getting titan, and methods of the titan object -.. code-block:: javascript +.. code-block:: entity soul = player.IsTitan() ? player.GetTitanSoul() : player.GetPetTitan().GetTitanSoul() // getting the titan depends on wether the player is in the titan or not diff --git a/docs/source/reference/respawn/topology.rst b/docs/source/reference/respawn/topology.rst index d810b315..9cea3f0a 100644 --- a/docs/source/reference/respawn/topology.rst +++ b/docs/source/reference/respawn/topology.rst @@ -7,7 +7,7 @@ The position of topologies are relative to the position of their parent. Since the number of topologies that can be created is very limited and Vanilla uses most of the slots already, try to minimize your topology uses. Instead of creating new ones, check if you can use one that already exists: -.. code-block:: javascript +.. code-block:: clGlobal.topoFullScreen clGlobal.topoCockpitHudPermanent @@ -61,7 +61,7 @@ Drawcalls determine how and where RUIs on a topology are being rendered. HUD Topology example ^^^^^^ -.. code-block:: javascript +.. code-block:: // Cover the top left quadrant of the screen with a basic image float[2] s = GetScreenSize() @@ -71,7 +71,7 @@ HUD Topology example Worldspace Topology example ^^^^^^ -.. code-block:: javascript +.. code-block:: // REMEMBER TO DESTROY ALL TOPOS, RUIS AND PROPS YOU CREATE WHEN YOU NO LONGER NEED THEM // ripped from respawn diff --git a/docs/source/repak/map.rst b/docs/source/repak/map.rst index 1eafd279..5b3c9cbf 100644 --- a/docs/source/repak/map.rst +++ b/docs/source/repak/map.rst @@ -15,7 +15,7 @@ Examples: "version": 7 } -.. code-block:: +.. code-block:: text root ├── RePak.exe @@ -53,7 +53,7 @@ Examples: ] } -.. code-block:: +.. code-block:: text root ├── RePak.exe @@ -111,7 +111,7 @@ Examples: ] } -.. code-block:: +.. code-block:: text root ├── RePak.exe diff --git a/docs/source/squirrel/async.rst b/docs/source/squirrel/async.rst index 4952b359..d685071c 100644 --- a/docs/source/squirrel/async.rst +++ b/docs/source/squirrel/async.rst @@ -19,14 +19,14 @@ Spinning off a thread To create a new coroutine, call a function with the ``thread`` keyword before. -.. code-block:: javascript +.. code-block:: thread void function(){}() thread MyFunction() To get a thread object, use the ``newthread`` function. -.. code-block:: javascript +.. code-block:: void function CoroutineExample() { @@ -43,7 +43,7 @@ wait The ``wait`` statement halts threads for a set amount of time specified after the ``wait`` keyword. Integers and floats are accepted as times in seconds. -.. code-block:: javascript +.. code-block:: void function WaitExample( float n ) { @@ -59,7 +59,7 @@ When using infinite loops it's important to work with ``wait`` statements to avo If you want to wait until a thread is finished, you can spin off the thread that you wait for with the ``waitthread`` keyword. -.. code-block:: javascript +.. code-block:: void function ParentThread() { @@ -77,7 +77,7 @@ OnThreadEnd Use the ``OnThreadEnd`` function to execute a callback after a thread has ended. This is useful for cleanup functions that remove entities after they're used or similar. -.. code-block:: javascript +.. code-block:: void function PlayIncomingFX( vector origin, int teamNum ) { @@ -107,7 +107,7 @@ Use the ``OnThreadEnd`` function to execute a callback after a thread has ended. Example Script ^^^^^^^^^^^^^^ -.. code-block:: javascript +.. code-block:: void function SetPositionDelayed( entity ent, vector pos, float delay ) { @@ -177,7 +177,7 @@ It's also possible to trigger and catch signals with methods that aren't propert Wait for any of the passed signals to be triggered. - .. code-block:: javascript + .. code-block:: // Wait for the NPC to die, delete, or get leeched, then remove the npc from the array WaitSignal( ent, "OnDeath", "OnDestroy", "OnLeeched" ) @@ -191,7 +191,7 @@ Example For example, if we want to tell a player not to give up after being killed several times, we can write it this way: -.. code-block:: javascript +.. code-block:: // First, we register signal we want to use RegisterSignal("OnMultipleDeaths") @@ -313,7 +313,7 @@ Flags Example ~~~~~~~ -.. code-block:: javascript +.. code-block:: void function FlagExample() { diff --git a/docs/source/squirrel/class.rst b/docs/source/squirrel/class.rst index 43022524..1166c517 100644 --- a/docs/source/squirrel/class.rst +++ b/docs/source/squirrel/class.rst @@ -14,7 +14,7 @@ Declaring Classes To declare a class, first add the ``untyped`` keyword and the class as a variable at file level. -.. code-block:: javascript +.. code-block:: untyped var ExampleClass @@ -35,7 +35,7 @@ class inside of a function. Most classes use a constructor. A constructor is a function of the instance that gets executed on object creation. -.. code-block:: javascript +.. code-block:: void function initClient() { class ExampleClass { @@ -50,7 +50,7 @@ Function parameters are passed as type ``var``, but the type keyword is not requ ``constructor( parameter ){}; func( parameter ){};`` and ``constructor( var parameter ){}; func( var parameter ){};`` are both correct. -.. code-block:: javascript +.. code-block:: class ExampleClass { propertyString = null // Actual type is var @@ -73,7 +73,7 @@ required to set a default value of a property. This may be ``null``. Every object has a reference to itself called ``this``. You can change parameters of an object by reference. -.. code-block:: javascript +.. code-block:: void function initClient() { class ExampleClass { @@ -93,7 +93,7 @@ Declaring Functions of Classes Functions of a class have to return a value of type ``var``. This may be ``null``. Define functions like this: -.. code-block:: javascript +.. code-block:: global var ExampleClass; void function initClassF(){ @@ -122,7 +122,7 @@ Inserting Properties Into Classes It's possible to insert more properties into a class at runtime. To achieve this, use the ``<-`` operator. -.. code-block:: javascript +.. code-block:: // Using ``ExampleClass`` and ``exampleObject`` from example above ExampleClass.newProperty <- "New property in class" @@ -134,7 +134,7 @@ the ``<-`` operator. It is not possible to insert new fields into an instance or a class *after instantiation* - .. code-block:: javascript + .. code-block:: var ExampleErrorClass; @@ -147,7 +147,7 @@ the ``<-`` operator. Inserting functions is also possible using the ``::`` operator -.. code-block:: javascript +.. code-block:: function ExampleClass::AddOne( var param /* parameters have to be var */ ){ return expect int( param ) + 1 } var e = ExampleClass() @@ -158,7 +158,7 @@ mods that have already been loaded. For example, extending functionality of the CPlayer class might look like this: -.. code-block:: javascript +.. code-block:: global function InitCPlayerInsert @@ -193,7 +193,7 @@ Instantiating Objects To create an instance, do: -.. code-block:: javascript +.. code-block:: class ExampleClass { property = null @@ -209,7 +209,7 @@ To create an instance, do: It's also possible to create an instance without calling the constructor. -.. code-block:: javascript +.. code-block:: // Using 'ExampleClass' from previous examples var e = ExampleClass.instance() @@ -222,7 +222,7 @@ Methods from a class can be accessed without an instance. Note that the class it doesn't have a reference to itself, meaning that the ``this`` keyword refers to the root table. -.. code-block:: javascript +.. code-block:: var class = ExampleClass var instance = class.constructor() @@ -234,7 +234,7 @@ Unlike other types, passing an object does not pass a copy of the object, but a reference to itself. This means that any modifications inside of a function are applied to the original object. -.. code-block:: javascript +.. code-block:: void function initClass(){ class Container { @@ -255,7 +255,7 @@ to the original object. You can avoid this by using cloned objects. Use the ``clone`` keyword to create a copy of an object. -.. code-block:: javascript +.. code-block:: // Assumes the 'Container' class from the previous example has already been declared void function initClass(){ @@ -278,7 +278,7 @@ Instead of declaring classes as a global var, you can use other types such as ta hold multiple class objects that emulate the behaviour of namespaces to a certain extend. -.. code-block:: javascript +.. code-block:: global table fakeNamespace = { class1 = null, @@ -289,7 +289,7 @@ This allows you to group classes together in a single global variable. You can use the classes inside of the table like this: -.. code-block:: javascript +.. code-block:: // Create a class object in field class fakeNamespace.class1 { constructor(){ print("constructing instance of class1") } } @@ -304,7 +304,7 @@ You can use the classes inside of the table like this: You can also declare classes in an array: -.. code-block:: javascript +.. code-block:: array classes // This has to be at file level @@ -314,7 +314,7 @@ You can also declare classes in an array: And in a similar fashion in structs: -.. code-block:: javascript +.. code-block:: struct { var class1 = null @@ -332,7 +332,7 @@ And in a similar fashion in structs: Respawn's fork doesn't appear to support inheritance. Using the ``extend`` keyword won't compile. - .. code-block:: javascript + .. code-block:: class Child extends Parent{} diff --git a/docs/source/squirrel/complex_types.rst b/docs/source/squirrel/complex_types.rst index 47eece65..cd31d72b 100644 --- a/docs/source/squirrel/complex_types.rst +++ b/docs/source/squirrel/complex_types.rst @@ -8,14 +8,15 @@ Strings Strings in squirrel represent an array of chars, however chars are not their own type in squirrel, as they are represent by integers. To initialize a string, use the ``string`` keyword: -.. code-block:: javascript +.. code-block:: string Hello = "World" You can get the integer value of any char with the ``[index]`` like in arrays, however this only returns the ASCII value of that character. To get the string of the char, you need to: -.. code-block:: javascript +.. code-block:: + :force: int charInt = Hello[0] string charString = charInt.tochar() @@ -29,13 +30,13 @@ Assets are strings that describe a path to a resource like models or RUI assets. You can declare asset literals with a $ symbol -.. code-block:: javascript +.. code-block:: asset m = $"path/to/my/model.mdl" You can convert strings to assets with the ``StringToAsset`` method added by Northstar. -.. code-block:: javascript +.. code-block:: string s = format( "path/to/my/%s", "model.mdl" ) asset m = StringToAsset( s ) @@ -45,7 +46,7 @@ Arrays Arrays can store large sets of data and are indexed using numbers, starting from 0, and are declared using ``array arrayname`` the identifier can be ignored but will result in the array being of the type ``var``. -.. code-block:: javascript +.. code-block:: array numbers = [1,2,3,4,5,6,7,8,9,10] @@ -57,7 +58,7 @@ adding and removing values from arrays can be done using ``.append(value)`` and additionally the index of values can be found using the ``.find()`` function and the length by using the ``.len()`` function: -.. code-block:: javascript +.. code-block:: array numbers = [1,2,3,4,5,6,7,8,9,10] @@ -80,7 +81,7 @@ If you know the exact length of the array ahead of time, you can use static arra The syntax for static arrays is ``type[size]``. -.. code-block:: javascript +.. code-block:: int[3] stArr printt( stArr[2] ) // note that this index isn't explicitly initialized @@ -96,7 +97,7 @@ Creation of a table is done in a similar way to arrays, however may have 2 types There are multiple ways to define a table with the ``[]`` when declaring a key you type a literal -.. code-block:: javascript +.. code-block:: table numberofletters = { ["hello"] = 5, @@ -110,7 +111,7 @@ There are multiple ways to define a table with the ``[]`` when declaring a key y unlike arrays however adding values to tables cannot be done using ``.append`` or similar means, as the index must also be declared, adding to tables is done using the ``<-`` operator like so. -.. code-block:: javascript +.. code-block:: table playerkills = {} foreach(entity player in GetPlayerArray()) @@ -118,13 +119,13 @@ unlike arrays however adding values to tables cannot be done using ``.append`` o To read a value from a table you use the array syntax but instead of an index you write your key: -.. code-block:: javascript +.. code-block:: printt(playerKills[player]) // 5 To check if the table has a certain key, you can use the "in" keyword: -.. code-block:: javascript +.. code-block:: table playerNames = {} if( "key" in playerNames ) @@ -143,13 +144,13 @@ Structs -------- Structs are a way of storing multiple variables in one object. To create a struct type you just write: -.. code-block:: javascript +.. code-block:: struct ExampleStruct {} Inside the brackets you can declare all the variables your struct should contain, you can also directly assign a standard value to a variable, if you dont override this value it will automatically be assigned. -.. code-block:: javascript +.. code-block:: struct ExampleStruct { int VariableInt @@ -163,7 +164,7 @@ Inside the brackets you can declare all the variables your struct should contain You then need to create instances of your struct to use it, like this: -.. code-block:: javascript +.. code-block:: //functions we need to assign, they are placeholders void function VoidFuntion(){ @@ -196,7 +197,7 @@ You then need to create instances of your struct to use it, like this: For values that we do not declare like ``Optional`` in the case of ``structOne`` we just add a ``...`` as an argument. Now that we have two instances we can get the values out of it like this: -.. code-block:: javascript +.. code-block:: printt(structOne.VariableInt) // 1 printt(structOne.VariableString) // "Hello World" @@ -214,7 +215,7 @@ In struct one we have defined that ``ExampleStringFunction`` is assigned to ``St We can do the same thing for ``structTwo``: -.. code-block:: javascript +.. code-block:: printt(structTwo.VariableInt) >> 2 @@ -234,7 +235,7 @@ We can do the same thing for ``structTwo``: Now that we have a struct we can also pass it as an argument in functions or return the struct from a function: -.. code-block:: javascript +.. code-block:: ExampleStruct function ChangeTheStruct(ExampleStruct struct){ if(struct.VariableInt == 1) @@ -248,7 +249,7 @@ Now that we have a struct we can also pass it as an argument in functions or ret You can also nest structs like this: -.. code-block:: javascript +.. code-block:: struct NewStruct{ Examplestruct CoolStruct @@ -267,7 +268,7 @@ You can also nest structs like this: In the same way you can also use it as a type for arrays or tables: -.. code-block:: javascript +.. code-block:: array StructArray = [] StructArray.append( structOne ) @@ -282,7 +283,7 @@ Alternatively you can define a struct and directly have it as an instance, the d This might be particularly useful when you want to share multiple variables at once between multiple files. You create one just like a regular struct, but the name is behind the closing bracket, like this: -.. code-block:: javascript +.. code-block:: struct { int CoolInt @@ -291,7 +292,7 @@ You create one just like a regular struct, but the name is behind the closing br Now you do not need to create an instance to give the struct a value: -.. code-block:: javascript +.. code-block:: file.CoolInt = 5 printt(file.CoolInt) @@ -309,14 +310,14 @@ Vectors Vectors are a type that store three floats in one object. They are declared using the ``< >`` operators. The values are seperated with a ``,``. Here the first number represents the X, the 2nd the Y, and the 3rd the Z coordinate. -.. code-block:: javascript +.. code-block:: vector myFirstVector = <0, 120, 40> We can then get the coordinates out of the vector with: -.. code-block:: javascript +.. code-block:: float x = myFirstVector.x float y = myFirstVector.y @@ -334,7 +335,7 @@ Most in game entities inherit from the ``CBaseEntity`` or ``C_BaseEntity`` class A fast way to create an entity is to use: -.. code-block:: javascript +.. code-block:: entity myFisrtNPC = CreateNPC( NpcName, team, origin, angles ) @@ -351,14 +352,14 @@ You declare a functionref with the return type, the ``functionref`` key word, th That variable will be of type ``functionref`` -.. code-block:: javascript +.. code-block:: void functionref(string) MyReference = void function(string str){ /* your code could be here */} You can then just call the fucntion by its functionref name. -.. code-block:: javascript +.. code-block:: void CallFunction(void functionref(string) func ){ func("hello") @@ -369,7 +370,7 @@ ornull To declare a type to contain a value or ``null``, declare the variable like this: ``type ornull identifier``. -.. code-block:: javascript +.. code-block:: int ornull number = CoinFlip() ? null : 0 if( number == null ) @@ -381,7 +382,7 @@ typedef To alias a type, use ``typedef``. Typedefs can optionally be global as well -.. code-block:: javascript +.. code-block:: global typedef DontDoThis var typedef crazyArray array[2] ornull diff --git a/docs/source/squirrel/functions.rst b/docs/source/squirrel/functions.rst index a1a71d3a..45a784b0 100644 --- a/docs/source/squirrel/functions.rst +++ b/docs/source/squirrel/functions.rst @@ -8,7 +8,7 @@ Declaring Functions Functions in squirrel are first defined by stating the **return type** (output) followed by the keyword **function**. For example, if you wanted to define a function that returns TRUE or FALSE you would type: -.. code-block:: javascript +.. code-block:: bool function ReturnTrueOrFalse() { @@ -21,7 +21,7 @@ If you don't want to return anything, use ``void`` as the return type. This indi If a function is lacking a ``return`` statement or a return value, it will return ``null``. For example: -.. code-block:: javascript +.. code-block:: void function ThisDoesStuff() { @@ -45,7 +45,7 @@ Optional parameters aren't required to call the function and will be assigned a To make a parameter optional, add a default after the parameter -.. code-block:: javascript +.. code-block:: void function OptionalExample( string msg = "default parameter", optional2 = 1 ) { @@ -62,7 +62,7 @@ Passing Functions as parameters If you want to pass a function as a parameter to another function, for example as a callback set their type as ``functionref( [parameters] )``. -.. code-block:: javascript +.. code-block:: void function FnLiteral( int req, int opt = 2 ) { @@ -83,7 +83,7 @@ You can call functions with opening and closing brackets containing all paramete You can also call functions with an array of parameters -.. code-block:: javascript +.. code-block:: void function FnLiteral( int opt = 2, int opt2 = 2 ) { @@ -102,7 +102,7 @@ Implicit parameters If you don't know how many parameters you get at compile time, you can use implicit parameters. -.. code-block:: javascript +.. code-block:: void function XParameters( string required, string optional = "", ... ) { @@ -121,7 +121,7 @@ Implicit Capture It's not possible to use locals from a parent function, but it is possible to capture them in an anonymous functions. -.. code-block:: javascript +.. code-block:: void function ParentFunc() { diff --git a/docs/source/squirrel/intro.rst b/docs/source/squirrel/intro.rst index 9aaaf2ae..bd69287b 100644 --- a/docs/source/squirrel/intro.rst +++ b/docs/source/squirrel/intro.rst @@ -9,19 +9,19 @@ Integer The type for an interger (whole number) in squirrel is ``int``. It represents a 32-bit whole number. It is declared like this: -.. code-block:: javascript +.. code-block:: int number = 5 They can be assigned expressions -.. code-block:: javascript +.. code-block:: number = 5 + 10 - 5 Alternatively you can also write the number in HEX code or as a single ASCII character with ``''`` -.. code-block:: javascript +.. code-block:: number = 'c' // IS VALID number = "c" // NOT VALID @@ -42,13 +42,13 @@ Float Floating-point numbers are numbers with decimal places, they are declared with the ``float`` keyword. -.. code-block:: javascript +.. code-block:: float number = 5.69420 You can also assign fractions but you need to use decimal points: -.. code-block:: javascript +.. code-block:: float number = 5.0/2.0 // has the value 2.5 float number = 5/2 // Will compile BUT with value 2 @@ -66,13 +66,13 @@ Boolean Booleans are a value that either represent ``true`` or ``false`` and are declared with the keyword ``bool`` -.. code-block:: javascript +.. code-block:: bool TrueOrFalse = true They can also accept comnparison expressions, which return a boolean -.. code-block:: javascript +.. code-block:: bool TrueOrFalse = 1 == 2 @@ -97,7 +97,7 @@ Variables that can represent any type (complex or primitive) can be initialized There are no build-in function to cast to var. -.. code-block:: javascript +.. code-block:: var anyValue = "String" var two = 2 @@ -110,13 +110,13 @@ Easy casting For all previous types you can also cast them by using the ``type( variable )`` notation: -.. code-block:: javascript +.. code-block:: int number = int ( "5" ) To convert a ``var`` to other types you need use the ``expect`` keyword: -.. code-block:: javascript +.. code-block:: var numberVar = 2 int numberInt = expect int(numberVar) @@ -128,7 +128,7 @@ Global variables and functions When creating a mod, you might want to allow other files or mods to access a ``variable`` or a ``function``, this can be achieved by declaring them using the ``global`` keyword. They act like any other variable or function, but can be accessed from any other file or mod. They should be declared at the top of your file, and have a unique name which doesn't appear as a global in any other file, mod, or built-in squirrel code. -.. code-block:: javascript +.. code-block:: global int GlobalInt global array GlobalArray diff --git a/docs/source/squirrel/networking.rst b/docs/source/squirrel/networking.rst index aa7b7f45..5be07e27 100644 --- a/docs/source/squirrel/networking.rst +++ b/docs/source/squirrel/networking.rst @@ -36,7 +36,7 @@ Example mod.json extract: -.. code-block:: javascript +.. code-block:: json "Scripts": [ { @@ -56,7 +56,7 @@ sh_spaceships.nut: The networked ``CLIENT`` function has to be global -.. code-block:: javascript +.. code-block:: #if CLIENT global function Server_GetNetworkedVariable // make the networked function only global on CLIENT @@ -84,7 +84,7 @@ The networked ``CLIENT`` function has to be global Calling the ``CLIENT`` function ``Server_GetNetworkedVariable`` on ``SERVER`` vm: -.. code-block:: javascript +.. code-block:: // player: CPlayer entity that should execute the function // func: function identifier string @@ -123,7 +123,7 @@ and execute with the function serverside: Example: ^^^^^^^^ -.. code-block:: javascript +.. code-block:: void function MessageUtils_ClientInit() { @@ -163,7 +163,7 @@ Since version 1.5 mods can receive notifications when a client command has been Example usage with the :doc:`PrivateMatchLaunch` clientcommand - .. code-block:: javascript + .. code-block:: void function init(){ AddClientCommandNotifyCallback("PrivateMatchLaunch", started) @@ -188,7 +188,7 @@ You can also pass parameters to the function. ``identifier`` is the name of the Example: ^^^^^^^^ -.. code-block:: javascript +.. code-block:: #if UI global function CallMe @@ -214,7 +214,7 @@ You can also pass parameters to the function. ``identifier`` is the name of the Example: ^^^^^^^^ -.. code-block:: javascript +.. code-block:: #if CLIENT global function CallMe diff --git a/docs/source/squirrel/statements.rst b/docs/source/squirrel/statements.rst index f8e6749d..5d39226b 100644 --- a/docs/source/squirrel/statements.rst +++ b/docs/source/squirrel/statements.rst @@ -6,13 +6,13 @@ If statements If statements use a similar style to most programming languages and will execute their asigned code if the test placed inside returns the boolean value true. If I wanted to have something occur if, and only if, our previous ``ReturnTrueOrFalse`` function returned true, then you can use: -.. code-block:: javascript +.. code-block:: if( ReturnTrueOrFalse() ) Conditional operators can also be used to make comparisons, such as ``==`` (equals), ``<`` (less than), ``<=`` (less than or equal), ``!=`` (not equal), etc., returning true if their condition is satisfied. For example, to execute code if a dice roll landed on 5: -.. code-block:: javascript +.. code-block:: if( RandomInt( 6 ) + 1 == 5 ) @@ -21,7 +21,7 @@ Like other languages, if statements can be connected to ``else if`` and ``else`` Squirrel supports ternary operations like most languages. The value of the expression depends if a condition is truthy or not. However, if not used carefully this can worsen readability. The Syntax is ``condition ? if_condition_true : if_condition_false``. This is especially useful when declaring variables or passing parameters. -.. code-block:: javascript +.. code-block:: // shortenedUsername is "longus..."" if username is "longusername" or "short" if username is "short" string shortenedUsername = username.len() > 9 ? username.slice(0,6) + "..." : username; @@ -36,7 +36,7 @@ While Loops A while loop runs as long as the condition evaluates to a truthy value. -.. code-block:: javascript +.. code-block:: while( true ) { @@ -53,7 +53,7 @@ Do While Loop A do while loop is the same as a while loop but the condition is checked **after** the body is executed. -.. code-block:: javascript +.. code-block:: do { @@ -67,7 +67,7 @@ A for loop also runs until a condition is met however it provides you with a cou The Syntax is as follows: ``for( int counter; condition; behaviour_after_body_execution )`` -.. code-block:: javascript +.. code-block:: // prints 0, 1, 2, 3, 4 for( int i; i < 5; i++ ) @@ -81,13 +81,13 @@ The Syntax is as follows: ``for( int counter; condition; behaviour_after_body_ex { print( arr[i] ) } - + Foreach Loop ~~~~~~~~~~~~ A foreach loop iterates over a ``table`` or an ``array`` and executes for each entry. The loop provides you with an optional counter for arrays or key for tables. -.. code-block:: javascript +.. code-block:: array arr = [ 1, 2, 3, 4 ] table map = { @@ -111,11 +111,11 @@ Implicit conditional behavior ----------------------------- Conditional statements, such as while loops and if statements, also implictly cast non-boolean inputs to booleans. For numbers, this means 0 is considered false and anything else is considered true. For instance variables like arrays and entities, ``null`` is considered false and anything else is considered true. For example, these inputs are considered true by the if statements: -.. code-block:: javascript +.. code-block:: if(2) -.. code-block:: javascript +.. code-block:: array somelist = [0, 1] if(somelist) @@ -128,7 +128,7 @@ So great, we can loop and check things, but what can we do with this information For example, lets make our ``ReturnTrueOrFalse`` function, that randomly picks either true or false, first: -.. code-block:: javascript +.. code-block:: bool function ReturnTrueOrFalse() { return RandomInt(2) == 1 @@ -137,14 +137,14 @@ For example, lets make our ``ReturnTrueOrFalse`` function, that randomly picks e Note that while functions always need ``{}``, single-line ``if``/``else`` statements and loops do not: -.. code-block:: javascript +.. code-block:: if(ReturnTrueOrFalse()) printt("Only called if true") Now let's make a more complicated function that will use the previous script to determine true or false, printing a list each time it returns true: -.. code-block:: javascript +.. code-block:: array someinformation = [1,2,3,4,5,6] void function ThisDoesStuff(){ diff --git a/poetry.lock b/poetry.lock index 3b28d92f..2e1bd19b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -708,4 +708,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "0b61b16490cffd1bce067bce3566dc9b50d26f13b87dcb1fd7664bcc4ede5be6" +content-hash = "b4215ce90d4b398697857bd059c2038f91ee98c490f08f0a4ce3290b2b090d76" diff --git a/pyproject.toml b/pyproject.toml index 3555b8e2..4b662c32 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,10 @@ version = "0.1.0" description = "This repo contains the technical documentation on all things related to making Northstar mods." authors = ["R2Northstar"] license = "MIT" -packages = [{ include = "docs/source/**/*.py" }] +packages = [ + { include = "docs/source/**/*.py" }, + { include = "sphinx_rsquirrel" }, +] [tool.poetry.dependencies] python = "^3.8" @@ -14,9 +17,12 @@ sphinx-autobuild = "^2021.3.14" sphinxcontrib-youtube = "^1.2.0" sphinx-copybutton = "^0.5.0" sphinx-design = "^0.3.0" +pygments = { extras = ["plugins"], version = "^2.14.0" } [tool.poetry.dev-dependencies] +[tool.poetry.plugins."pygments.lexers"] +"squirrel" = "squirrel_support:SquirrelLexer" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/sphinx_rsquirrel/__init__.py b/sphinx_rsquirrel/__init__.py new file mode 100644 index 00000000..f417c10d --- /dev/null +++ b/sphinx_rsquirrel/__init__.py @@ -0,0 +1,4 @@ +from .lexer import SquirrelLexer +from .sphinx_ext import setup + +__all__ = ["SquirrelLexer", "setup"] diff --git a/sphinx_rsquirrel/lexer.py b/sphinx_rsquirrel/lexer.py new file mode 100644 index 00000000..4eaf45ad --- /dev/null +++ b/sphinx_rsquirrel/lexer.py @@ -0,0 +1,302 @@ +from pygments.lexer import RegexLexer, bygroups, default, include, this, using, words +from pygments.token import ( + Comment, + Generic, + Keyword, + Name, + Number, + Operator, + Punctuation, + String, + Text, + Token, + Whitespace, +) + +# test: hwatch -t -N --no-help-banner -c py -m pygments -x -O"full,debug_token_types" -l .\sphinx_rsquirrel\lexer.py:SquirrelLexer test.gnut +# py -m pygments -v -f html -x -O"full,debug_token_types" -l .\sphinx_rsquirrel\lexer.py:SquirrelLexer test.gnut + + +class SquirrelLexer(RegexLexer): + name = "Squirrel" + aliases = ["squirrel"] + filenames = ["*.nut", "*.gnut"] + + _keyword_types = [ + "void", + "bool", + "int", + "float", + "entity", + "string", + "vector", + "asset", + "var", + ] + _builtin_names = [ + "TitanLoadoutDef", + "PilotLoadoutDef", + ] + _declarations = [ + "global", + "const", + "static", + "local", + "typedef", + ] + tokens = { + "values": [ + (r"[^\S\n]+", Whitespace), + (r"(\$?\"(\\.|.)*?[\"\n])", String), + (r"-?([0-9]+(([.]([0-9]+)?)(e[-]?[0-9]+)?))", Number.Float), + (r"(0x[0-9a-fA-F]+|0[0-7]+|-?[0-9]+|'[a-f]')", Number.Integer), + include("constants"), + ], + "value": [include("values"), default("#pop")], + "root": [ + (r"(\"(\\.|.)*?[\"\n])", String), + include("comments"), + include("keywords"), + include("operators"), + include("statement"), + # include("generic"), + ], + "statement": [ + (r"#.*", Comment.Preproc), + (r"(function)(\s+)", bygroups(Keyword, Whitespace), "funcname"), + ( + r"(class)(\s+)([a-zA-Z_]\w*)", + bygroups(Keyword, Whitespace, Name.Class), + ), + (r"(struct|enum)( ?)(\{)", bygroups(Name.Class, Whitespace, Punctuation)), + include("declarations"), + ( + r"(\.?)([a-zA-Z_]\w*)(\s*?)(\()", + bygroups(Punctuation, Name.Function, Whitespace, Punctuation), + "arguments", + ), + include("type"), + (r"(?<=\w)(\.)(\w+)", bygroups(Punctuation, Name.Attribute)), + ( + r"(?<=\w)(\.)(\w+)(=)", + bygroups(Punctuation, Name.Attribute, Punctuation), + ), + ( + r"([a-zA-Z_]\w*)(\s*)(=)", + bygroups(Name.Variable, Whitespace, Punctuation), + ), + include("values"), + include("tableaccess"), + (r"[a-zA-Z_.]\w*", Name.Variable), + (r"[\{\}\(\)\[\]]", Punctuation), + ], + "funcname": [ + (r"[a-zA-Z_]\w*", Name.Function), + (r"[(]", Punctuation, "sig"), + default("#pop"), + ], + "sig": [ + ( + r"([a-zA-Z_]\w*)(\s*?)(?=[,)])", + bygroups(Name.Variable, Whitespace), + ), + (r"[\[<]", Generic.Error, "array"), + (r",", Punctuation), + (r"=", Punctuation, "value"), + (r"\.\.\.", Keyword.Pseudo), + include("operators"), + (r"[)]", Punctuation, "#pop"), + include("typed_name"), + ], + "itype": [ + (r"[>]", Punctuation, "#pop"), + include("tableaccess"), + include("typed_name"), + ], + "typeb": [ + include("typed_name"), + default("#pop"), + ], + "typed_name": [ + include("type"), + (r"[a-zA-Z_]\w*", Name.Variable), + ], + "type": [ + ( + r"(array|table)(\s*?)(<)", + bygroups(Keyword.Type, Whitespace, Punctuation), + "itype", + ), + (words(_keyword_types, suffix=r"\b"), Keyword.Type), + (words(_builtin_names, suffix=r"\b"), Name.Builtin), + include("constants"), + (r"ornull", Keyword.Type), + ( + r"(\s*?)(functionref)(\()", + bygroups(Whitespace, Name.Builtin.Type, Punctuation), + "sig", + ), + (",", Punctuation), + include("whitespace"), + ], + "whitespace": [ + (r"\n", Whitespace), + (r"[^\S\n]+", Whitespace), + ], + "arguments": [ + (r"\)", Punctuation, "#pop"), # end of arguments + (r"(,)", Punctuation), # end of argument + include("tableaccess"), + (r"[\[<]", Punctuation, "array"), + (r"{", Punctuation, "structure"), + (r"[a-zA-Z_]\w*", Name.Variable), + include("funcname"), + include("operators"), + include("values"), + include("namedargs"), + ], + "namedargs": [(r"(\w+?)(=)", bygroups(Name.Variable, Punctuation))], + "structure": [ + (r"}", Punctuation, "#pop"), # end of structure + (r"(,)( )", bygroups(Punctuation, Whitespace)), # end of member + (r"[\[<]", Punctuation, "array"), + include("constants"), + include("namedargs"), + ], + "tableaccess": [ + (r"(\w+)(\[)", bygroups(Name.Variable, Punctuation), "tablekey"), + ], + "tablekey": [ + (r"\]", Punctuation, "#pop"), # end of structure + include("values"), + (r"[a-zA-Z_]\w*", Name.Variable), + ], + "array": [ + (r"[\]>]", Punctuation, "#pop"), + include("tableaccess"), + (r"(,)( ?)", bygroups(Punctuation, Whitespace)), # end of member + (r" ", Whitespace), # end of member + (r"/\*.+?\*/", Comment), + include("values"), + ], + "comments": [ + (r"(//.*?$)", Comment.Single), + (r"/\*", Comment.Multiline, "comment_multiline"), + ], + "comment_multiline": [ + (r"[^*/]", Comment.Multiline), + (r"/\*", Comment.Multiline), + (r"\*/", Comment.Multiline, "#pop"), + (r"[*/]", Comment.Multiline), + ], + "operators": [ + (words(("in", "and", "or", "not"), suffix=r"\b"), Operator.Word), + ( + words( + ( + "=", + ";", + ":", + "?", + "!", + "!=", + "||", + "==", + "&&", + "<=", + "=>", + ">", + "<", + "+", + "+=", + "-", + "-=", + "/", + "/=", + "*", + "*=", + "%", + "%=", + "++", + "--", + "<-", + "&", + "^", + "|", + "~", + ">>", + "<<", + ">>>", + "!", + ), + ), + Operator, + ), + ], + "declarations": [ + (words(_declarations, suffix=r"\b"), Keyword.Declaration), + ], + "constants": [ + ( + words( + ( + "true", + "false", + "null", + ), + suffix=r"\b", + ), + Keyword.Constant, + ), + ], + "keywords": [ + ( + words( + ( + "break", + "case", + "catch", + "clone", + "continue", + "default", + "delegate", + "delete", + "else", + "extends", + "for", + "foreach", + "if", + "local", + "resume", + "return", + "switch", + "this", + "throw", + "try", + "typeof", + "while", + "parent", + "yield", + "vargc", + "vargv", + "instanceof", + "static", + "untyped", + "globalize_all_functions", + "wait", + "thread", + "unreachable", + "expect", + "waitthread", + "waitthreadsolo", + "delaythread", + "typedef", + ), + suffix=r"\b", + ), + Keyword, + ), + include("declarations"), + include("constants"), + ], + } diff --git a/sphinx_rsquirrel/sphinx_ext.py b/sphinx_rsquirrel/sphinx_ext.py new file mode 100644 index 00000000..a91e8358 --- /dev/null +++ b/sphinx_rsquirrel/sphinx_ext.py @@ -0,0 +1,13 @@ +from sphinx.application import Sphinx + +from .lexer import SquirrelLexer + + +def setup(app: Sphinx): + app.add_lexer("squirrel", SquirrelLexer) + + return { + "version": "0.1", + "parallel_read_safe": True, + "parallel_write_safe": True, + }