IWBTS Tab Language Manual
by Pythlow Stubson
Last update
Preamble
Take two, since I'm greatly overestimating.
Rationale
Language is designed to be easy to grasp but not restrictive if the need arises and above all else clearly constrainable so it's safe to execute.
Glossary
- Whitespace
- Whole list is defined by RegExp but the characters we can type with a
regular keyboard layout are
'SPACE' (U+0020)
,'CHARACTER TABULATION' (U+0009)
and line feed'LINE FEED (LF)' (U+000A)
- Empty element
- Element which by HTML specification cannot have any children. One of the
elements is
<img />
. There are others but they are not really important.
Description
Note: the "input" spacing to align things vertically/horizontally is just for presentation. You may use it, but it won't matter if you did.
Text
Since words would be ambiguous to the parser, they have to be quoted to be
turned into a text block. Both 'APOSTROPHE' (U+0027)
and
'QUOTATION MARK' (U+0022)
will start a text block which will
continue until a matching non-escaped quote is found. Escaping inside quoted
values follows
JSON
string rules. Text is not an element, so it can't have a class, id, or any
other attribute.
'Ayy & \'Lmao\''
#textAyy & 'Lmao'
Elements
To create an element specify its name.
span
<span>
Any whitespace terminates interaction with an element and next word will immediately start a new one.
span span
<span> <span>
Hierarchy, nesting
All non-empty elements are intended to have children in them. To nest
elements parentheses are used. All content inside
'LEFT PARENTHESIS' (U+0028)
and
'RIGHT PARENTHESIS' (U+0029)
will be attached as children to the
element immediately preceding the block. For example, text nested inside a
<span>
will allow us to assign
that span meaning through classes.
span('Pack my box with five dozen liquor jugs')
<span>#textPack my box with five dozen liquor jugs
Classes
Adding a class to an element is done by putting a
'FULL STOP' (U+002E)
after element's name and following it up with
a class name. Because classes can't contain spaces adding more than one is done
by repeating this pattern.
span.foo.bar.baz.etc
<span class='foo bar baz etc'>
Classes will allow elements be picked up by styling engine and scripts. Currently used classes are:
- op
- Person's, who's currently creating the stream, name. Purely cosmetic at the moment.
- bro
- Name of someone participating in the game along with the streamer. Cosmetic.
- off
- Free-form text describing the state of the channel while it's not in use. Cosmetic.
- game
- Text content that should be sent to Twitch as the game title. Applies only to main1.
Ids (skip this section)
Ids can be specified like in CSS too by appending
'NUMBER SIGN' (U+0023)
after element name and specifying the id
name.
span#test
<span id='test'>
While it's not an error to use the pattern more than once, the last occurrence will shadow all the previous ones.
Implicit element
One elment is used very frequently and that is the
<span>
. Because of that, when
setting a class or an id to apparently nothing, an element will be created
automatically. This means that writing .class
does exacly the same
as writing span.class
.
.class<span class='class'>
Attributes
The attribute block is opened with
'LEFT SQUARE BRACKET' (U+005B)
and closed with
'RIGHT SQUARE BRACKET' (U+005D)
. If you need an empty attribute
just specify its name and follow it up with a whitespace.
If an attribute value doesn't contain any whitespace, equal signs or closing
square brackets it will be sufficient to just separate its name from value with
an 'EQUALS SIGN' (U+003D)
, otherwise quoting as
text content is required.
Generally, the only attributes you'll need are:
- src
- URL of an
<img />
element. - alt
- Alternative text of an
<img />
element. Ideally, if image was replaced with this text and everything was read aloud, a blind person would get the same information as a person seeing everything. Logically, if the image is purely decorative, this attribute should be still defined, just empty.
span[foo=bar baz etc='Don\'t stop at a space']
<span foo='bar' baz='' etc='Don't stop at a space'>
img[src=/ti/streamer.png alt='Streamer\'s Name']
<img src='/ti/streamer.png' alt='Streamer's Name'>
Styles
Styles, instead of being specified in generic attribute block, have their own
block. It is opened with 'LEFT CURLY BRACKET' (U+007B)
and closed
with 'RIGHT CURLY BRACKET' (U+007D)
. Style properties are
separated with 'SEMICOLON' (U+003B)
and property name is separated
from value with 'COLON' (U+003A)
.
Some frequently used style property names have a shorthand. The shorthands are:
h
-height
m
-margin
mb
-margin-bottom
span{h:1em;mb:-.1em}
<span style='height: 1em; margin-bottom: -.1em'>
Helpers
Due to usefulness of a single space character text content and relatively
intense typing labour involved to produce it using quoted text, a shorthand is
offered. It can be invoked using an 'LOW LINE' (U+005F)
(it's literally the same as writing
' '
, though).
span _ span
<span> #text <span>
Complete examples
Plain text tab. Simple, but completely usable:
'Streamer') _ 'Movie Title 4'.op(
<span class='op'>#textStreamer #text #textMovie Title 4
A tab for Twitch with game title marked:
'Streamer') _ .game('Flavour of the Month').op(
<span class='op'>#textStreamer #text <span class='game'>#textFlavour of the Month
Content is fake but the form should cover most of tabbing needs:
img[src=/ti/streamer.png alt=Streamer]) _ img[src=/ti/FOTM.png alt='Movie title 4']{h:2em;mb:-.3em}.op(
<span class='op'><img src='/ti/streamer.png' alt='Streamer'> #text <img src='/ti/FOTM.png' style='height:2em;margin-bottom:-.3em' alt='Movie title 5'>
And another example, because we can't extrapolate:
img[src=/ti/streamer.png alt=Streamer]) _ .game(img[src=/ti/FOTM.png alt='Flavour of the Month']{h:2em;mb:-.3em}).op(
<span class='op'><img src='/ti/streamer.png' alt='Streamer'> #text <span class='game'><img src='/ti/FOTM.png' style='height:2em;margin-bottom:-.3em' alt='Flavor of the Month'>