HTML Interfaces + Ink: Part 2: Reacting to Tags

HTML Interfaces + Ink

Note: This series is a sequel to JavaScript + Ink series. It builds on the code and concepts found there.


Reacting to Tags

In the previous part, the text returned by calling Continue() was parsed and the speaker text was used to set a CSS class. And, while this is certainly a valid way to go about writing a story in Ink, there is an alternative approach for getting information about text blocks.

The Ink for Web functionality build into Inky has support for a number of tags that can be used in Ink that act as meta-information about the story itself. Using this same approach, tags can be used to react to text.

Using Tags

In Ink, tags are extra information not parsed by the default runtime. They exist for other code to read and understand in some way. They are written using a hash, #, and then some text.

Multiple tags can also be used on a single line through using an additional hash, #, between them.

When used in Inky, for example, tags appear after the text on which they are used as a separate line.

Getting tags using currentTags

For every call to Continue(), the property currentTags is filled with any tags found within that block of text. As an array, currentTags will contain any tags or be an empty array if no tags are found for that block of text.

I really don't know what I'm going to do with them, Susan. They are driving me crazy. #Dan
I hear you, but what, really, can you do? #Susan
I don't know. I just… I wish they would listen to me. #Dan
Dan. They are kittens. You are literally herding cats. They don't listen to anyone. #Susan
Okay. Sure. That's a valid point. But, I mean, just look! These kittens are crawling up everything in the room. #Dan

While not as readable, the speaker of any text could be added as a tag for that block of text.

// Use the storyContent to create an Ink story
var story = new inkjs.Story(storyContent);
// Save a reference to the storyContainer where text will be added
var storyContainer = document.getElementById("story");
function continueStory() {
// Check if there is more content in the story
if(story.canContinue) {
// Get ink to generate the next paragraph
var paragraphText = story.Continue();
var speaker = story.currentTags;
// Create paragraph element
var paragraphElement = document.createElement('p');
// Check if speaker is an empty array
if(speaker.length > 0) {
// Add a CSS class matching the speaker
paragraphElement.classList.add(speaker[0]);
}
// Add the text to the P-element
paragraphElement.innerHTML = paragraphText;
// Append the P-element to the storyContainer
storyContainer.appendChild(paragraphElement);
}
}
// Call continueStory() to start
continueStory();
// Listen for the "click" event and show text
window.addEventListener("click", continueStory);
view raw main.js hosted with ❤ by GitHub

Changing the code from the last part, the speaker could be read as the first entry in the currentTags array per call to continueStory().

Once more with feeling!

In addition to the speaker of different text blocks, the emotional overtone of a speaker could also be encoded through using a tag.

I really don't know what I'm going to do with them, Susan. They are driving me crazy. #Dan #Angry
I hear you, but what, really, can you do? #Susan #Understanding
I don't know. I just… I wish they would listen to me. #Dan #Frustration
Dan. They are kittens. You are literally herding cats. They don't listen to anyone. #Susan #Annoyance
Okay. Sure. That's a valid point. But, I mean, just look! These kittens are crawling up everything in the room. #Dan #Acceptance

Adapting the main.js code would only mean adding one additional line.

// Use the storyContent to create an Ink story
var story = new inkjs.Story(storyContent);
// Save a reference to the storyContainer where text will be added
var storyContainer = document.getElementById("story");
function continueStory() {
// Check if there is more content in the story
if(story.canContinue) {
// Get ink to generate the next paragraph
var paragraphText = story.Continue();
var speaker = story.currentTags;
// Create paragraph element
var paragraphElement = document.createElement('p');
// Check if speaker is an empty array
if(speaker.length > 0) {
// Add a CSS class matching the speaker
paragraphElement.classList.add(speaker[0]);
// Add a CSS class matching the emotion
paragraphElement.classList.add(speaker[1]);
}
// Add the text to the P-element
paragraphElement.innerHTML = paragraphText;
// Append the P-element to the storyContainer
storyContainer.appendChild(paragraphElement);
}
}
// Call continueStory() to start
continueStory();
// Listen for the "click" event and show text
window.addEventListener("click", continueStory);
view raw main.js hosted with ❤ by GitHub

However, as there is now a need for new CSS classes, they also have to be added.

.Dan {
color: green;
}
.Susan {
color: purple;
}
.Angry {
font-weight: 900;
}
.Annoyance {
font-style: italic;
}
view raw site.css hosted with ❤ by GitHub