From 218853c6e2055966b892ca2401799854b16ca5d0 Mon Sep 17 00:00:00 2001 From: Kuba Sunderland-Ober Date: Mon, 25 May 2026 20:39:56 +0200 Subject: [PATCH 1/5] Fix the twinBASIC Rouge highlighter's line continuation handling. --- docs/_plugins/twinbasic.rb | 45 ++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/docs/_plugins/twinbasic.rb b/docs/_plugins/twinbasic.rb index e0e7d07..de3afa2 100644 --- a/docs/_plugins/twinbasic.rb +++ b/docs/_plugins/twinbasic.rb @@ -80,7 +80,14 @@ def self.builtins id = /[a-z_]\w*/i state :whitespace do - rule %r/_[ \t]*\n/, Punctuation::LineContinuation + # Line continuation absorbs the next line's leading whitespace + # into the same LineContinuation token -- semantically the `_` + # plus trailing space, newline, and the continuing line's + # indent are one continuation unit, and folding them all into + # a single span keeps rendering consistent with the other + # states (`:attrargs`, `:dotted`, etc.) that already used the + # `_[ \t]*\n[ \t]*` form. + rule %r/_[ \t]*\n[ \t]*/, Punctuation::LineContinuation rule %r/\n/, Text, :bol rule %r/[^\S\n]+/, Text rule %r/rem\b.*?$/i, Comment::Single @@ -228,20 +235,41 @@ def self.builtins rule(//) { pop! } end + # The :dim / :funcname / :typename / :typename_ext / :namespace / + # :end states each consume one or more identifiers that follow a + # specific opener keyword (Dim, Function, Class, Module, End, ...) + # and then pop back to :root. The original mixin :whitespace rule + # pushed :bol on `\n`, leaving the state on the stack so the next + # line's first identifier was mis-classified -- e.g. + # + # Module MyModule + # Option Private Module + # End Module + # + # tokenised the second `Module` as Keyword + push :namespace, then + # `\n` pushed :bol, popping back to :namespace for the next line. + # The next line's `End` then matched the :namespace identifier rule + # and rendered as Name::Namespace (`nn`) instead of Keyword (`k`). + # The fix: drop mixin :whitespace, add non-newline whitespace plus + # the `_[ \t]*\n` line continuation, and let `\n` fall through to + # the empty-match `(//) { pop! }` so each state pops at end-of-line. state :dim do - mixin :whitespace + rule %r/_[ \t]*\n[ \t]*/, Punctuation::LineContinuation + rule %r/[^\S\n]+/, Text rule %r/#{id}[%&@!#$]?/, Name::Variable, :pop! rule(//) { pop! } end state :funcname do - mixin :whitespace + rule %r/_[ \t]*\n[ \t]*/, Punctuation::LineContinuation + rule %r/[^\S\n]+/, Text rule %r/#{id}[%&@!#$]?/, Name::Function, :pop! rule(//) { pop! } end state :typename do - mixin :whitespace + rule %r/_[ \t]*\n[ \t]*/, Punctuation::LineContinuation + rule %r/[^\S\n]+/, Text rule id do |m| token Name::Class goto :typename_ext @@ -250,7 +278,8 @@ def self.builtins end state :typename_ext do - mixin :whitespace + rule %r/_[ \t]*\n[ \t]*/, Punctuation::LineContinuation + rule %r/[^\S\n]+/, Text rule %r/(Extends|As)\b/i do |m| token Keyword goto :typename @@ -259,13 +288,15 @@ def self.builtins end state :namespace do - mixin :whitespace + rule %r/_[ \t]*\n[ \t]*/, Punctuation::LineContinuation + rule %r/[^\S\n]+/, Text rule %r/#{id}([.]#{id})*/, Name::Namespace, :pop! rule(//) { pop! } end state :end do - mixin :whitespace + rule %r/_[ \t]*\n[ \t]*/, Punctuation::LineContinuation + rule %r/[^\S\n]+/, Text rule %r/(Function|Sub|Property|Class|CoClass|Structure|Enum|Module|Namespace|Type|Interface|Select|If|With)\b/i, Keyword, :pop! rule(//) { pop! } From bf4825479a0f2de07db6b1cef1237cc69ba95440 Mon Sep 17 00:00:00 2001 From: Kuba Sunderland-Ober Date: Mon, 25 May 2026 20:46:04 +0200 Subject: [PATCH 2/5] Remove HTML comments as their processing differs between markdown-it and kramdown. --- docs/IDE/Project Explorer.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/IDE/Project Explorer.md b/docs/IDE/Project Explorer.md index 6b51ddc..a697c48 100644 --- a/docs/IDE/Project Explorer.md +++ b/docs/IDE/Project Explorer.md @@ -13,11 +13,6 @@ permalink: /tB/IDE/Project/Explorer ![Folder](Images/Folder.png "Folder") ImportedTypeLibraries ![Folder](Images/Folder.png "Folder") Miscellaneous ![Folder](Images/Folder.png "Folder") Packages - - - - - ![Folder](Images/Folder.png "Folder") References ![Folder](Images/Folder.png "Folder") Resources ![Folder](Images/Folder.png "Folder") Sources From 5f3667136c6350e47671d368b00ad39fd2548986 Mon Sep 17 00:00:00 2001 From: Kuba Sunderland-Ober Date: Mon, 25 May 2026 20:47:46 +0200 Subject: [PATCH 3/5] Simplify whitespace in markdown. --- .../Importing a package from a TWINPACK file.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/docs/Features/Packages/Importing a package from a TWINPACK file.md b/docs/Features/Packages/Importing a package from a TWINPACK file.md index 76a0a36..46df932 100644 --- a/docs/Features/Packages/Importing a package from a TWINPACK file.md +++ b/docs/Features/Packages/Importing a package from a TWINPACK file.md @@ -17,21 +17,13 @@ To import a package directly from a TWINPACK file (instead of using TWINSERV), f - navigate to the References section - select the 'Available Packages' button ![image](Images/d9f1e4d9-1805-47e5-93aa-251151b4e914.png) - - press the 'Import from file...' button: - ![image](Images/e35d5955-9e70-4d6e-abd7-748558da75ba.png) - - - - choose the TWINPACK file you want to import, and then it should appear in the references list (ticked): - ![image](Images/4e4b8e4d-2a1c-42e5-8f4b-5a9b3f523ee8.png) +- Save the `Settings` and if needed restart the compiler
-
- -- Save the `Settings` and if needed restart the compiler Now you're ready to use the package! In the example shown above I added a reference to the CSharpishStringFormater package, and I can now confirm that I can access components from the package in my code: From 3c82562790cf7627cd24797146f21a0e377e235a Mon Sep 17 00:00:00 2001 From: Kuba Sunderland-Ober Date: Mon, 25 May 2026 20:54:50 +0200 Subject: [PATCH 4/5] Add missing escapes in markdown. --- docs/Reference/VBA/Information/VarPtr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Reference/VBA/Information/VarPtr.md b/docs/Reference/VBA/Information/VarPtr.md index 71cfada..700690e 100644 --- a/docs/Reference/VBA/Information/VarPtr.md +++ b/docs/Reference/VBA/Information/VarPtr.md @@ -17,7 +17,7 @@ Syntax: **VarPtr(** *Var* **)** The returned address is the storage location of *Var* itself --- the same place the runtime would write to for an assignment. For a numeric or fixed-length type the value of the variable lives at that address; for a **String** or **Variant** the value at the address is the variable's BSTR pointer or **VARIANT** descriptor. -Pass the result to an API function that needs a raw address, or pass it to one of the [**GetMem*** / **PutMem***](../HiddenModule/) helpers to read or write the underlying bytes. The pointer is valid only for as long as *Var* is alive in its scope; locals, arguments, and elements of expanded arrays can move when their owning frame or array is reallocated. +Pass the result to an API function that needs a raw address, or pass it to one of the [**GetMem**\* / **PutMem**\*](../HiddenModule/) helpers to read or write the underlying bytes. The pointer is valid only for as long as *Var* is alive in its scope; locals, arguments, and elements of expanded arrays can move when their owning frame or array is reallocated. ### Example From 7e0a536f22a02a276b952e740313507c864f5aab Mon Sep 17 00:00:00 2001 From: Kuba Sunderland-Ober Date: Mon, 25 May 2026 21:00:26 +0200 Subject: [PATCH 5/5] Code-quote string literals. --- docs/Reference/WinServicesLib/ServiceManager.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Reference/WinServicesLib/ServiceManager.md b/docs/Reference/WinServicesLib/ServiceManager.md index f9f1600..57f0185 100644 --- a/docs/Reference/WinServicesLib/ServiceManager.md +++ b/docs/Reference/WinServicesLib/ServiceManager.md @@ -161,7 +161,7 @@ Opens the SCM with `SC_MANAGER_CONNECT Or SC_MANAGER_CREATE_SERVICE`, calls `Cre > [!IMPORTANT] > [**Install**](#install) writes to the SCM database, which requires administrator rights. The usual pattern is to call it once from an elevated installer, not from the application's normal startup path. Running from within the twinBASIC IDE typically fails --- the IDE is rarely elevated. -Raises run-time error 5 with a descriptive message on permission failure (*"Unable to open the Service manager..."*) or unrecoverable create failure (*"CreateServiceW() failed with error code "*). +Raises run-time error 5 with a descriptive message on permission failure (`"Unable to open the Service manager..."`) or unrecoverable create failure (`"CreateServiceW() failed with error code "`). ### ReportStatus {: .no_toc }