Instances of underscore+character being unwantingly interpreted as temp variables

Twine Version: 2.3.8
Story Format: Harlowe 3.1, Sugarcube 2.31

This is my first real stab at Twine with very little programming know-how. I’ve run into a problem using Harlowe where ANY instance of underscore followed by a character, even in what is meant to be a string, is output as an error because it’s treated as a temp variable in need of a value. For example, if I have set a variable to have a particular string (I have alternatively tried to set it to the string “_DG”, either way the same thing happens and is worsened because it immediately sees the _DG there as a temp variable):

(set: $def5 to “_”+“D”+“G”)

and then try to print it like so:

(print: $def5)

this is how it comes out:

twine_dg

I have also noticed a similar problem in Sugarcube 2.31.1, in which two underscores together will always underline whatever comes after it in the output (i.e. “underscore”+“underscore”+“O” is output as an underlined O). Is there a way to make it so that anything that resembles these macros will not actually be treated as that macro, so long as its contained within the quotation marks that denote a string? Or is this a Javascript/CSS thing I may have to apply? Apologies if this is something simple, but I have no clue how to work around this.

If you’re using SugarCube, then there are a couple of examples for how to do what you want in the “Naked Variable” section, right at the top of the SugarCube documentation. See the part that starts with, “Because variables within your passage text…”.

Also if you’re using SugarCube, if you haven’t defined a variable named _DG, then putting that in the passage will just show “_DG”.

Hope that helps! :smiley:

Maybe put backticks around the underscore (Harlowe’s verbatim markup)?

(set: $def5 to "`_`"+"D"+"G")
(print: $def5)
1 Like

Thank you Josh for your suggestion with Harlowe, because it seems to have worked there!

I’m still having trouble in Sugarcube however, and I’m curious as to how it could be fixed. I understand the naked variable is possible for output, but the verbatim markup only works if you want to output the variable name without interpolation, not what its set to. Unless I’m somehow wrong about how to place the no wiki markup; did it like “”"$def5""" wherever I wanted it output without interpolation…in this case its meant to output “UnderscoreUnderscoreO”. Trying to wrap the string I’m setting the variable to in that markup returns an error.

Ah, sorry, I misunderstood where the problem was.

This should work:

<<set $test = "__DG">>
<<= "<nowiki>" + $test + "</nowiki>">>

That will display __DG for you. (<<=>> is an alias for the <<print>> macro.)

1 Like

I have to admit, I’m curious what situation would require a word like _DG to be in your story text. It seems like leading with underscores would normally be a safe bet.

Although I did use $.var and _.var for my game engine just in case this came up, but I never thought it actually would.

That did it, thanks HiEv!!

I wanted to figure this out because I intend to use underscores and characters to symbolically represent seats on a bus! Underscore to indicate an empty seat, a letter to represent a character who’s in that seat. So _DG for example would mean the leftmost seat is empty, while Derek and Gina are sitting in the other 2 seats in that booth respectively.

1 Like

Aha. That makes a lot of sense. You could probably have just used spaces between the letters in that case, but I’m glad you got it work.

Thanks for sating my curiosity. Hehe. :smile:

1 Like

EDIT: This version turned out to be overly simplistic. See my next comment for a better version.


Ah, if that’s what you want, then you might want to put this in your Stylesheet section:

.seats {
	font-family: monospace;
	font-size: 16px;
	white-space: pre;
	letter-spacing: 4px;
	background-image: linear-gradient(to right, white 0%, white 25%, transparent 25%, transparent 50%, white 50%);
	background-size: 12.8px 1px;
	background-repeat: repeat-x;
	background-position: bottom;
}

And then you can just do this in your passages:

<<set $seats = "  DG">>
<span class="seats">$seats</span>

That should more clearly display what you’re trying to show, since each character is separately underlined.

Enjoy! :smiley:

1 Like

I’ll definitely toy around with this once I get the chance, because I have been wondering how to treat character interactions and all that. Thank you again for your help with this hahaha

I tried the class you posted but the underlining was not very exact for 3 individual letters, and is kinda inaccurate in general:

twine_dg2

So I tried messing with the background-image percentages and background-size properties and I found this worked well enough specifically for 3 letters:

.seats {
font-family: monospace;
font-size: 16px;
white-space: pre;
letter-spacing: 4px;
background-image: linear-gradient(to right, white 0%, white 75%, transparent 75%, transparent 100%, white 100%);
background-size: 14px 1px;
background-repeat: repeat-x;
background-position: bottom;
}

Mainly got this through trial and error but I understand the gist of how you work with it now. This may not work as well when dealing with more than 3 characters, I don’t know if there’s a way to get a 100% accurate character-to-underline match, but for the sake of what I’m doing at the moment this will be fine for now.

Hmmm… Yeah, it appears to be browser dependent. (I knew I should have checked that!)

Worse, it also appears to be dependent on whether there are an even or odd number of characters.

OK, here’s a fix which should work on all of the most common browsers (tested in Chrome, Firefox, Opera (old and new), Internet Explorer 11, Edge, PaleMoon, Vivaldi, Brave, CCleaner, and Tor). First, put this in your Stylesheet section:

.seats {
	font-family: monospace;
	font-size: 16px;
	white-space: pre;
	letter-spacing: 4px;
	background-image: linear-gradient(to right, white 0%, white 25%, transparent 25%, transparent 50%, white 50%);
	background-size: 12.8px 1px;
	background-repeat: repeat-x;
	background-position: bottom;
}
.seatsFirefox {
	background-size: 13.6px 1px;
}
.seatsIE {
	background-size: 13.63px 1px;
}
.seatsPaleMoon {
	background-size: 13px 1px;
}
.seatsOdd {
	background-image: linear-gradient(to right, white 0%, white 75%, transparent 75%);
}

Then, put this in your JavaScript section:

var isChrome = !!window.chrome;
var isFirefox = (typeof InstallTrigger !== "undefined");
var isIE = /*@cc_on!@*/false || !!document.documentMode;
var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.includes(" OPR/");
var isPaleMoon = isFirefox && navigator.userAgent.includes(' PaleMoon/');

if ((isPaleMoon || isOpera) && (!isChrome)) {
	setup.seatstyle = "seats seatsPaleMoon";
} else if (isFirefox) {
	setup.seatstyle = "seats seatsFirefox";
} else if (isIE) {
	setup.seatstyle = "seats seatsIE";
} else {
	setup.seatstyle = "seats";
}
setup.seatstyleOdd = setup.seatstyle + " seatsOdd";

And then in your passages you’d do this:

<<set $seats = "Et harum quidem rerum facilis est et expedita distinctio">>
<span @class="setup.seatstyle">$seats</span> /* Even # of characters */
<<set $seats = "Et harum quidem rerum facilis est et expedita distinctio.">>
<span @class="setup.seatstyleOdd">$seats</span> /* Odd # of characters */

To make that a bit easier, create a widget passage with “widget” and “nobr” tags, and put this in it:

<<widget "underline">>
	<<set _tempStr = $args[0].toString()>>
	<<if _tempStr.length % 2>>
		<span @class="setup.seatstyleOdd">_tempStr</span>
	<<else>>
		<span @class="setup.seatstyle">_tempStr</span>
	<</if>>
<</widget>>

Now your passage code would just be this:

<<set $seats = "Et harum quidem rerum facilis est et expedita distinctio">>
<<underline $seats>>
<<set $seats = "Et harum quidem rerum facilis est et expedita distinctio.">>
<<underline $seats>>

That should make it automatically use the correct styling, based on number of characters and which browser is being used, with the Chrome styling being the default.

Enjoy! :smiley:

1 Like

I’m curious why something as simple as using a HTML Entity Code to replace the underscore wasn’t considered?
see: Character Entity Reference Chart
eg.

Low Bar: <<set $def5 to "&#95;" + "D" + "G">><<print $def5>>
Under Bracket: <<set $def5 to "&#9141;" + "D" + "G">><<print $def5>>

Originally because another solution which dealt with all kinds of markup was already presented, and since then because we’re now working on a way to put separated underlines under each character.

Sorry was busy the last few days. HiEv’s fix for the browser/odd or even problem seems to work!! I completely forgot about using the HTML code for underscore but I’m kinda glad I did, as HiEv’s suggestion for underlining text looks way nicer for the story. I’m very thankful they went so far for what could’ve been an easy fix for a worse direction to take it.

I don’t want to rely too much on using Javascript for the story if it can be helped, but I think I might officially go with Sugarcube to keep the effect. I was writing the story in both Sugarcube and Harlowe to figure out which I’d rather work with, but I know the latter is not the best for editing Javascript (it seems that way to me at least, and it does not like HiEv’s solution) so the former is looking more and more like the best option.