Syntax highlighting for HTML and select storyformats (see Features) on top of Twee 3 code.
Made possible feedback from the folks over at the Twine Games Discord Server and through contributions from:
Made with contrib.rocks.
The extension relies on a workspace (or a folder) being open. If single files are to be edited, the storyformat must be configured manually.
Supported file extensions:
.tw
.twee
To set the correct storyformat for the files, a StoryData
passage with the storyformat (and version) (see example below) mentioned in it is preferred. If not, the extension provides the option to set the format explictly.)
:: StoryData
{
"ifid": "<ifid here>",
"format": "<story format here, i.e. 'SugarCube'>",
"format-version": "<story format version here, i.e. '2.35.0'>"
}
Syntax highlighting.
Snippet to generate the StoryData
special passage: start typing StoryData
in a Twee document and press Tab when prompted with the snippet. This populates the IFID field with a newly generated one.
Command palette tool to generate IFID: open the command palette (Ctrl/Cmd + Shift + P or F1 by default) and search for "IFID".
A list of passages for quick jumps (can be grouped by files, folders, or passage tags.) Open from the Twee 3 Language Tools tab on the activity bar (the forking paths logo.)
Workspace statistics Status bar item (WIP).
A story-map view that opens inside VSCode (and optionally, in the browser)! Still in early stages. Also accessible from the Twee 3 Language Tools tab on the activity bar.
Currently implemented features:
Usage:
(id: sugarcube-2
)
*.twee-config.yml
. See: Custom macro definitions for SC):
<<end...>>
closing macros:
twee3LanguageTools.sugarcube-2.undefinedMacroWarnings
setting:
t3lt.twee-config.yml
in the root of the first workspace folder.)(id: chapbook-2
)
(id: harlowe-3
)
The extension adds diagnostics for erroneous usage of macros in TwineScript for the sugarcube-2
storyformat. By default, only the definitions for the core SugarCube library are present, but custom definitions can be added. The process is as follows:
*.twee-config.yaml
(or .yml
) OR *.twee-config.json
(*
represents any valid file name) file to your project folder (or anywhere in the workspace.)Define custom macros as follows:
If using *.twee-config.yaml
(indentation is important for YAML files):
sugarcube-2:
macros:
customMacroName:
container: true
anotherOne: {}
*.twee-config.json
:
{
"sugarcube-2": {
"macros": {
"customMacroName": {
"container": true
},
"anotherOne": {}
}
}
}
The following properties are currently programmed, even though not all of them are used as of now:
(string)
optional: Name of the macro (currently unused in code; the name of the object suffices for now.)(string)
optional: Description of macro. Shown on hover. Supports markdown.(boolean)
optional: If the macro is a container (i.e. requires a closing tag) or not. false
by default.(boolean)
optional: If the macro is a self-closable. Requires macro to be a container first. false
by default.(string|child-definition array)
optional: If the macro has children, specify their names as an array (currently unused in code.) You still need to define the child macros as their own macro definitions.(string array)
optional: If the macro is a child macro, specify the names of its parents as an array (currently unused in code.)(boolean)
optional: If the macro is deprecated or not. false
by default.(string array)
optional: If the macro is deprecated, specify any alternatives to the macro as an array.(object)
optional: Allows for macro argument validation. Read here for more information.(object)
optional: Allows for declaring decorations to be displayed on that macro. Uses DecorationRenderOptions' fields. Requires definedMacroDecorations
setting to be enabled.The fields description
and parameters
allow substituting globally defined values in. Read here for more information.
NOTE: Multiple twee-config
files can be present in a workspace. They will stack and add to the macro definitions for the workspace. The recommended strategy is to make separate files for separate macro sets/libraries, e.g. (the following file can also be used as an example):
click-to-proceed.twee-config.yaml
(Link)Uses a simple packing algorithm to space out passages into clusters based on the file they originate from.
To use, search for Pack passages to clusters
from the command palette (Ctrl/Cmd + Shift + P or F1 by default).
Adds every unrecognized macro to the definition file, instead of doing it one by one.
To use, search for Unrecognized Macros
from the command palette (Ctrl/Cmd + Shift + P or F1 by default).
However, it is still recommended to add definitions one at a time.
NOTE: SugarCube 2 does NOT have a self-closing syntax for container macros, this feature is just to support custom passage processing functions.
Example of such a function which replaces self-closed instances with the actual closing macro tag (i.e. <<macro />>
with <<macro>><</macro>>
):
Config.passages.onProcess = function(p) {
const macroNamePattern = `[A-Za-z][\\w-]*|[=-]`;
const selfCloseMacroRegex = new RegExp(`<<(${macroNamePattern})((?:\\s*)(?:(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/)|(?://.*\\n)|(?:\`(?:\\\\.|[^\`\\\\])*\`)|(?:"(?:\\\\.|[^"\\\\])*")|(?:'(?:\\\\.|[^'\\\\])*')|(?:\\[(?:[<>]?[Ii][Mm][Gg])?\\[[^\\r\\n]*?\\]\\]+)|[^>]|(?:>(?!>)))*?)\\/>>`, 'gm');
return p.text.replace(selfCloseMacroRegex, "<<$1$2>><</$1>>");
};
The twee3LanguageTools.experimental.sugarcube-2.selfClosingMacros.enable
setting enables detection of self-closed macros.
Argument validation is still a work in progress. Passage name validation, especially. Shouldn't hinder workflow, however.
Changelog here.