Wordscript combines the best features from several languages, including Typescript, HTML, CSS, and Markdown.


The structure of Wordscript is simple: Just elements! Unlike other languages, text and attributes are elements too. You can easily append or nest multiple scripts because Wordscript uses fragments instead of a nested document. Furthermore, Wordscript provides incremental and dynamic "scopes" to reduce source code nesting and promote reusability.


Elements are defined using [[ and ]] bracket pairs; Elements have a tag and content inside them.

[[tag content]]

Special bracket characters can also be used.

〚tag content 〛

No space is allowed between the opening bracket and the tag.

[[tag]] // valid
[[ tag]] // valid but this will be parsed as a new "scope" containing a text element

All other whitespace between elements and around content is optional.


[[name     content      ]]



Brackets with no tagname indicate a nestable scope. The global scope contains all elements not declared inside brackets.

This is the global scope.

  This is a nested scope.
    This is a scope within another scope.


Text is defined using unreserved characters, or escaped reserved characters.


Wordscript uses \\[[ and \\]] for scopes and elements.

However, text can be scoped by putting it inside scope brackets.

[[ Hello ]]

Most of your text will be in the global scope, unless you need to put text inside elements that require scoped text as content, or if you want some scope to end.

  [[ scoped text inside someTag ]]

    scope text
    more scoped text that sparkles
text that does not sparkle


Attributes are also elements; Attributes use the @ tag.

This is [[@ color:red;]] red and [[@ color='blue']] blue

In Wordscript, text can contain attributes, attributes can contain text, text can contain text, and attributes can contain attributes!

This is [[@ color:red; [[ red ]] ]] and [[ [[@ color='blue']] blue ]]

[[@ color: red;
    [[@ font-size: 10px; ]]

[[ Hello
    [[ World ]]

Attribute Scope

Attributes are applied to either their surrounding scope, or their internal scope.

Internal Scope

Attributes with content create a new scope; The attributes are only applied to content within their scope.

I am black
[[@ color:red;  [[ I am red ]] ]]
I am black

Surrounding Scope

Attributes with only attribute blocks inside are applied to the scope the attribute element appears in; The attributes are effective starting from where they are declared.

I am black
[[@ color:red; ]]
I am red


A Wordscript consists of dialogue written in plain text. Dialogue is used to generate interactive media, such as podcasts, videos, web pages, and transcripts.

Single Newlines

Single newlines in dialogue function as a space. This avoids long lines and makes the script easier to read and write. Markdown, a popular language has a similiar behavior.

Mary had a
little lamb.

Her fleece was
as snow.

This will interpreted as:

Mary had a little lamb.

Her fleece was white as snow.

Multiple Newlines

Multiple newlines in dialogue function as a paragraph indicator. Multiple newlines are normalized into two newlines.

Paragraph 1

Paragraph 2

Paragraph 3

This will interpreted as:

Paragraph 1

Paragraph 2

Paragraph 3

Whitespace Control

If you do not want whitespace normalized, use a whitespace _ element.

Hello[[_\n\n\n  ]]World


Escaped Characters

All characters are allowed in dialogue except the sequences [[, ]], and \\. If you use these characters in your dialog, escape them with \\.

Wordscript uses \\[[ and \\]] to indicate elements, and uses the \\\\\\ characters to escape them.


Dialogue is marked up using elements. An element is defined using a tagname and and optional content; The tagname and content are placed between double braces [[ and ]].

[[tagname value]]

Unlike HTML and JSON, a Wordscript’s element attributes and child text are both expressed using elements.

For example, HTML syntax is:

<speak language="en">Hello</speak>

Wordscript syntax is:

[[@ language: en;]]

Element Tagname

An element tagname is specified using text immediately following the [[.

Element tags have some basic restrictions for the characters used for their names.

  • Names cannot contain the “ “` (backtick) character.
  • If the name contains a space, comma, [, ], or `\, the entire name must be enclosed in backticks`.

Tagnames are case insensitive. [[play]] and [[PLAY]] will both be interpreted as the same tag.

[[`my element`]]
[[`This silly tagname has "quotes", spaces, parenthesis and brackets ([])`]]

Closing Brackets

The closing tag does not need to include the tag name, although it can be added for clarity and script verification.

With a named closing bracket

[[# this is a comment

Without a named closing bracket

[[# this is a comment

If you need the tag name as content, and not a marker, include a space before the end bracket.

[[# this is a comment
# ]]

Element Value

Besides a tagname, elements also have a value. Values may be in any arbitrary format; It is up to the tag provider to mandate the syntax of the tag value.

[todo show examples]

Element Attributes

Elements do not not have attributes like other languages do. Instead, attributes a just elements added anywhere in the elements content.

Nested Elements

Elements can contain other elements, including attribute elements and unscoped text elements.

[[b [[i [[u I am bold, underlined, and italic.
]] ]] ]]

Comma Nesting

Nested elements can also use a comma nesting as a shorthand. This eliminates multiple opening and closing brackets. It can only be used if the outer elements only contain one element as content.

[[b,i,u I am bold, underline, and italic.]]

Mixed Content

Elements can also contain mixed content.

[[i Hello, [[b World ]]. ]]


Attributes are named values used by the Wordscript runtime, plugins, and scripts. Attributes can be set dynamically within a Wordscript.

For example, an attribute can indicate the voice used to speak the dialogue, the font used to print the dialogue, or the background image used in a video at a location.

An attribute can be set within any scope. A scope can be an element, section, location, or script.

Attribute Element

Attribute elements can set or modify attributes in any scope, using several language styles.

Using CSS style

[[play [[@ volume:60; ]] ]]

Using JSON style

[[play [[@ {"volume":60} ]] ]]

Using Javascript style

[[play [[@ {volume:60} ]] ]]

Using HTML style

[[play [[@ volume="60" ]] ]]

Using mixed types

    [[@ volume:60; ]]
    [[@ {repeat: true} ]]
    [[@ volume:60;  {repeat: true} ]]

Changing an attribute.


[[@ name:Woolly;]]
Hello [[$ name]]

[[@ name:Dolly;]]
Hello [[$ name]]

Attribute Blocks

Attributes can be set using a combination of CSS, JSON, Javascript, or HTML style notation. When using any non Javascript style, attribute values will always be of type string.

Using CSS style


Using JSON style


Using Javascript style


Using HTML style


Using mixed types

{repeat: true, maxRepeats: 10}
compress: true;

Attribute Namespace

A namespace can be specified before each attribute block.


A namespace will only set the items in the block that do not already have a namespace set.


The block above will become

{'css.color': 'red', 'css.font-size': '12px', 'script.title': 'Welcome' }


Dialogue can be grouped into sections.

Hello, World!

Welcome to Wordscript.

All dialogue that follows a section belongs to that section, until the next section or location change.

I am in the default first global section

I am in the second global section

[[! Scene 1 ]]
I am in the default first scene section

I am in the second scene section

Attribute shorthand

Only attributes are allowed inside section elements.

[[section [[@ color:red; ]] ]] // valid

[[section [[b bold text]] ]] // not valid

[[section [[section]] ]] // not valid

[[section [[@ color:red [[ bold text]]  ]] ]] // not valid

Attributes in sections can omit their braces.

[[section @ color:red; ]]

Named sections

Sections can be named.

[[section intro]]

Named sections have many uses in Wordscript. For example, sections can be the target of links, goto statements, inherited styles, and projected styles.


A location element, is used to further organize dialogue and sections.

A location consists of a series of areas (a name with an optional identifier), with each area separated by /.

Area names and identifiers are case insensitive. [[!paris]] and [[!PARIS]] are both interpreted as the same location.

All dialogue and sections following a location change belong to that location\’s scope. Locations do not need to enclose the dialogue they mark.

[[! act one]]
[[@ color:blue;]]

[[! act one / scene one ]]
[[@ color:green;]]

[[! slide 1 ]]
color is default here

[[! slide 2 ]]
color is default here

[[! act one / scene two ]]
color is blue from act one scope

Dialogue can return to previous locations.

[[! Paris ]]
I am in Paris.

[[! Chicago / "Willis Tower" / Floor 12 / Room 3]]
Now I am in Chicago.

[[! Paris ]]
Back to Paris!

Location And Section Scoped Attributes

A location or section id must be appended with a ; with the attribute block following.

[[section 1;
font-size: 2em;
color: green;

[[! paris;
background-image: eiffel_tower;

[[! chicago;
background-image: willis_tower;

When you set an attribute in a location scope, it will persist if you leave and then return.

[[! red-room;
background-color: red;

The background is red.

[[! other-room ]]

The background IS NOT red.

[[! red-room]]

The background IS red.


Locations and sections can inherit attributes from one or more other locations.

[[! scene 1;
color: red;

[[! scene 2;
background-color: grey;

[[! scene 3 << scene 1 & scene 2]]

Mutiple Files


Wordscript files can import other files by using the import keyword. A Wordscript module provides access to locations, scenes, and dialogue.

[[import p1 as './']]
[[import p2 as './']]

[[! home <<< p1.locations.act.1.scene.2]]


Wordscript files can include other files by using the import keyword. Including a file will essentially copy the contents verbatim.

[[include './' ]]
[[include './' ]]