This guide illustrates the process of developing plugins for vLabeler. Should you encounter any inadequacies in the
plugin specification for your needs, please do not hesitate to submit questions or feature requests.
vLabeler currently supports two types of plugins:
- Macro plugins: Execute during the project editing phase. They are typically used for batch editing of entries.
- Template plugins: Execute when initiating a new project. Their primary function is to generate a series of entries for further editing.
While both plugin types share the same structural design, their execution contexts differ, leading to variations in inputs and outputs.
This guide will cover:
A vLabeler plugin is a folder containing:
- A
plugin.jsonfile to specify the plugin's behavior. - At least one
*.jsscript file. - Additional files needed by your scripts.
The plugin.json file is structured as a JSON object, containing the following properties:
| Key | Type | Default value | Supported Plugin Type | Description |
|---|---|---|---|---|
| name | String | (Required) | All | This value should match the folder's name. |
| version | Integer | 1 | All | The version of the plugin. |
| type | String | (Required) | All | Specify as either template or macro. |
| displayedName | String (Localized) | name value |
All | The displayed name of the plugin. |
| author | String | (Required) | All | The author of the plugin. |
| String | "" | All | Contact email of the author. | |
| description | String (Localized) | "" | All | A brief description of the plugin. |
| website | String | "" | All | The website or source code repository of the plugin |
| supportedLabelFileExtension | String | (Required) | All | Supported extensions for your label file (e.g., ini for UTAU oto). Use "*" to accept all types; use "|" to separate multiple extensions. |
| outputRawEntry | Boolean | false | Template | If set to true, outputs the raw entry text rather than a parsed object. |
| scope | String | "Module" | All | Determines the plugin's access range: either Module or Project. |
| parameters | Parameters | null | null | All | For details, refer to the Defining Parameters section. |
| scriptFiles | String[] | (Required) | All | Names of all script files. These files execute in the order they are listed. |
| resourceFiles | String[] | [] | All | Files utilized as resources in your scripts. Their contents are fed into your scripts as string values in the order listed. |
| inputFinderScriptFile | String | null | null | Template | Name of the script file used to identify input files dynamically. |
Within the parameters object is an array named list:
{
// ...,
"parameters": {
"list": [
// ...
]
},
// ...
}Each object within list specifies a parameter that will appear in the plugin configuration dialog and will be passed
to your scripts.
For a comprehensive definition of a parameter, see Parameter.
Below are guidelines on scripting for plugins:
For detailed information on the scripting environment and available APIs, please refer to Scripting in vLabeler.
Plugins with template type operate on the New Project page, facilitating the creation of entry lists for subsequent
edits.
Before your scripts are executed, the following variables will be set in the JavaScript environment:
| Name | Type | Description |
|---|---|---|
| inputs | String[] | Texts sourced from input files, facilitated by the input finder script. |
| samples | String[] | List of sample file names. |
| params | Dictionary | A dictionary containing all parameters defined in plugin.json. You can get values using their name as the key. |
| resources | String[] | Texts from resource files, in the order they appear in plugin.json. |
| labeler | LabelerConf | JSON object mirroring LabelerConf. |
| labelerParams | Dictionary | A dictionary containing all parameters defined in the current labeler. You can get values using their name as the key. |
| debug | Boolean | Whether the execution is in debug mode (during the Gradle run task). |
| pluginDirectory | File | The plugin directory. |
For labelers that create projects with subprojects, you can dynamically find input files for every subproject. The
plugin's inputFinderScriptFile attribute in plugin.json should specify a script for this.
This JavaScript file:
- Receives
root(type:File), representing the project's root directory. - Receives
moduleName(type:String), the subproject name. - Accepts variables
debug,params,labeler,labelerParams, similar to those in the template generation scripts. - Outputs
inputFilePaths(type:String[]), containing desired input file paths. - Optionally, outputs
encoding(type:String) to specify input file encoding; otherwise, the chosen encoding during project creation is used.
Refer to the documentation for the File type's specifications and
the audacity2lab plugin as a sample implementation.
For input files unrelated to a subproject (like user customizable dictionaries), utilize a file or rawFile parameter
type.
See Defining a Parameter for specifics.
Return results to the app using a list named output. This can be presented in two methods:
Construct an output array containing parsed Entry objects. For example:
let output = [];
for (const line of lines) {
// parse line to get `name`, `sample`, `start`, `end`, etc.
const entry = new Entry(sample, name, start, end, points, extras);
output.push(entry);
}If outputRawEntry is set to true, populate output with raw entry strings in the label file's format. The labeler's
parser will process these later.
- When
labeler.allowSameNameEntryisfalse, only the first entry with a duplicate name is retained. Address this in your script if preserving all is necessary. - If no entries are created, an error will be raised. As a remedy, include a fallback entry.
- Projects initiated by a labeler's parser with a raw label file will encompass all sample files, even those absent in the raw label. Default entries are generated for these. However, for projects initiated by a plugin, unreferenced sample files in the output are ignored. Ensure all desired sample files have corresponding entries.
Explore these integrated template plugins for insight:
- ust2lab-ja-kana: Converts an input UST file to Sinsy lab entries.
- cv-oto-gen: Produces CV oto entries from parameters.
- regex-raw-gen: Uses regex to craft raw entry lines, supporting all labeler types.
- audacity2lab: Creates lab entries from an Audacity label file.
Also compatible with
NNSVS singer labeler, which constructs projects with subprojects.
In the context of vLabeler, batch edit scripts (type: macro) are designed to operate over projects, either over the
entire project or a particular subproject/module. The scope of the plugin determines the domain of operation,
with Module scope operating on the current module, and Project scope covering the entire project.
Before your scripts are executed, the following variables will be set in the JavaScript environment:
| Parameter Name | Type | Scope | Description |
|---|---|---|---|
| entries | Entry[] | Module | A list of the current Entry objects in the active module. |
| currentEntryIndex | Entry[] | Module | The index of the currently displayed entry. |
| module | Module | Module | The current Module object. |
| modules | Module[] | Project | All Module objects in the project. |
| currentModuleIndex | Integer | Project | The index of the currently displayed module. |
| params | Dictionary | All | A dictionary containing all parameters defined in plugin.json. You can get values using their name as the key. |
| resources | String[] | All | Texts from resource files, in the order they appear in plugin.json. |
| labeler | LabelerConf | All | JSON object mirroring LabelerConf. |
| labelerParams | Dictionary | All | A dictionary containing all parameters defined in the current labeler. You can get values using their name as the key. |
| debug | Boolean | All | Whether the execution is in debug mode (during the Gradle run task). |
| pluginDirectory | File | All | The plugin directory. |
| projectRootDirectory | File | Project | The project's root directory. |
This type of parameter lets the user specify a subset of entries for operation and is accessible under Module scope.
Here's a code snippet for its utilization:
let selectedIndexes = params["selector"] // `selector` is the name of the entry selector parameter
for (let index of selectedIndexes) {
let entry = entries[index]
// do something with the entry
}To bring about changes in the project, directly modify the entries or modules list. Note that for Module scope,
while you can access the module, changes to it won't be saved. Here's an example to add suffixes to each entry name in
the current module:
let suffix = params["suffix"]
for (let entry of entries) {
entry.name += suffix
}After execution, you can display reports. Refer to the section in Scripting in vLabeler for more details.
After execution, you can request an audio playback. Refer to the section in Scripting in vLabeler for more details.
Explore these integrated macro plugins for insight:
- batch-edit-entry-name: Modify names of selected entries across all labelers. It demonstrates the use of the entry selector.
- batch-edit-oto-parameter: Edit parameters of chosen UTAU
oto entries. It demonstrates the use of the
labelervariable. - compare-oto-entries: Compares an input oto with the ongoing
project. The function
report()is used here. - execute-scripts: Run input scripts to edit the project. It can be used as a debugging tool during plugin development.
- resampler-test: Examine the resampler synthesis of the active
entry. Demonstrates the use of
requestAudioFilePlayback(), along withEnv,File, andCommandLineAPIs.
Check Localized strings in vLabeler about the String (Localized) type mentioned above.
For in-depth understanding and strategies to handle errors, refer to the section in Scripting in vLabeler.
You can use logs to help debug your scripts.
The standard output (e.g. console.log()) is written to .logs/info.log and the error output is written to
.logs/error.log.
If your plugin doesn't appear in the list, it might have faced issues during loading,
such as problems parsing plugin.json. Check the error log for more information.