ink icon indicating copy to clipboard operation
ink copied to clipboard

Impossible to prevent Ink from collapsing whitespace?

Open besttof opened this issue 4 years ago • 6 comments

Sorry for double posting this discussion #666 (heh, interesting), but the discussions don't seem to be very active.

I have a fictional terminal-like setup and I want to do ASCII drawings (and other fixed width formatted text) like these:

  ┌─────────────────┐
  │                 │
  │                 │
  ├──────────┐      │
  │          │      │
  │          │      │
  │          │      │
  └──────────┴──────┘

But when I get the text from the Ink api the whitespaces are collapsed and I get:

┌─────────────────┐
│ │
│ │
├──────────┐ │
│ │ │
│ │ │
│ │ │
└──────────┴──────┘

Using a special character to stand in for a space and replace that afterwards could work, but is quite cumbersome and error-prone. I can't do a custom tag or other bespoke postprocessing because, by the time I can process the string, the whitespaces are already collapsed.

I guess I'm looking an option or special syntax that would prevent Ink from collapsing whitespace. Does that exist?

besttof avatar Apr 23 '21 06:04 besttof

I think actually isn't ink; I think this is javascript. ink does preserve whitespace. JS tends to collapse it; but perhaps if you wrap everything as a monospaced font or something?

joningold avatar Apr 23 '21 20:04 joningold

Sorry, I should have mentioned I'm using the ink-unity-integration, and I'm positive it collapses all whitespaces and empty lines.

besttof avatar Apr 23 '21 21:04 besttof

I think actually isn't ink; I think this is javascript. ink does preserve whitespace. JS tends to collapse it; but perhaps if you wrap everything as a monospaced font or something?

Not to push back on that too hard, but are you sure? Having played around with it, calling currentText seems to trigger CleanOutputWhitespace, which strips out whitespace in a way that would explain this issue.

elliotherriman avatar May 10 '21 09:05 elliotherriman

I stand entirely corrected!

There's no in-engine way to stop that method from running, but you could hack it locally to skip the cleaning step if, say, a particular ink story bool was true.

joningold avatar May 10 '21 11:05 joningold

Yeah, you could add a global variable to a knot or stitch to indicate that ink should use your alternative line constructor, or maybe just add a tag to the switch statement that assigns a new value to paragraphText? Actually, yes, maybe that latter works better.

I've commented up the source code for how I approached this in Calico starting around here-- but that might be borderline incomprehensible to you, so I've simplified it down here. To use it, just place this inside the tag switch statement, right after the block for else if( tag == "CLEAR" || tag == "RESTART" ).

else if( splitTag && splitTag.property == "WHITESPACE" )
{
	// tags are applied before text is shown, but we already have our text at this point, so we have to reset it
	paragraphText = "";

	// loop through all the content,
	for (var i = 0; i < story.state.outputStream.length - 1; i++)
	{
		// and if it's text,
		if (story.state.outputStream[i].value)
		{
			// append it to our string
			paragraphText += story.state.outputStream[i].value;
		}
	}
}

Feel free to let me know if you can't get it working!

elliotherriman avatar May 10 '21 13:05 elliotherriman

Oh! Totally forgot-- you've gotta tweak the CSS, too. Since inkjs adds your lines to a <p> tag, by default, that will collapse whitespace. So along with the above, just include this in your CSS style, and it should fix things right up.

p
{
	white-space: pre-wrap;
}

elliotherriman avatar May 11 '21 02:05 elliotherriman