Get raw unprocessed text of passage in Sugarcube 2.37.3

Twine Version: 2.10.0
Sugarcube 2.37.3

How can I get the unprocessed text of a passage and store it in a variable?

Use-case: I have a function on my story’s JS setup object that returns an array of passage titles. I’d like to be able to select one of those array elements (a string holding a passage’s title) returned by the function and pass it into another JS function that would return the raw, unprocessed text of that passage.

Ultimately, I’d like to have a JS function that can be overloaded. The default would return the unprocessed text of the current story passage. But if passed a string, the function would – upon verifying that a passage exists matching that string title – return that passage’s raw text.

You want Story.get("PassageName").text.

Yes, and that works fine as long as I manually assign a string literal, but I can’t seem to get it working when I try passing Story.get() a variable holding the desired passage title.

Can you share the code you’re using? Because it should work fine when passed a variable containing the name of the passage. See this minimal example:

<<set setup.passagename = "Passage">>
<<print "<nowiki>"+Story.get(setup.passagename).text+"</nowiki>">>

Specifically, when you say you can’t get it to work, what exactly happens? Can you share the error you’re getting?

I can share when back at computer. I wasn’t using the no wiki tags, if that makes a difference. I bet it does.

The nowiki (Verbatim Text markup in the docs) is to stop it from processing the markup when you print it out.

So if you left out those, you should still get the text of the passage, but when you print it out it would be processed instead of raw.

Dunno if that matches what you’re seeing…

Instead of nowiki tags with <<print>> you could also console.log() the text for debugging purposes (it’d show up in the browser’s JavaScript console instead of on the page).

1 Like

Okay, so when I add the following two lines to a passage, it works as expected:

<<set _current to passage()>>
The current passage is <<= _current>>

However, when I then add the following line and try to run the story in app Twine, it just hangs:

<<print "<nowiki>" + Story.get(_current).text + "<nowiki>">>

Figured it out, I let the forward slash out of the closing </nowiki> tag.

Okay, here’s what I’m trying to do:

I’ve added a function to the javascript section of my story like this:

setup.getPassageText = function(passage){
  if(Story.has(passage)){
    return Story.get(passage).text;
  }else{
    return "";
  }
};

Then, in my passage, I have the following code:

<<set _current to passage()>>
The current passage is <<= _current>><br><br>
<<set _text to setup.getPassageText(_current)>>
<<print _text>>

This freezes the story when I try to run it in the browser. But if I remove the <<print _text>> line, it doesn’t lock up the browser when I run it.

If I replace the third line as shown below, the code runs fine and returns the text size in bytes as 3168, so I know that <<set _text to setup.getPassageText(_current)>> works.

The current passage is <<= _current>><br><br>
<<set _text to setup.getPassageText(_current)>>
The length of the returned text is <<= _text.length>>

I can’t figure out why <<print _text>> causes the browser to hang.

If I modify the line with the print macro to the following, it doesn’t hang and displays raw passage text as expected:

<<print "<nowiki>" + _text + "</nowiki>">>

Aha, so I moved the <nowiki> tags into the JS function on the setup object and now it works.

This function now works with the twinescript at the bottom of this post:

<<set _current to passage()>>
The current passage is <<= _current>><br><br>
<<set _text to setup.getPassageText(_current)>>
The length of the returned text is <<= _text.length>>
<<print _text>>
1 Like

Oh. Yeah, doing that on the current passage is an infinite loop if it’s wiki-processing the text: as part of displaying the passage, it will print the passage again, which (when wiki-processed) will print the passage again, which will print the passage again…

1 Like

How would I get a passage’s processed text (i.e., after twinescript has been evaluated)?

This suggests that getting the processed passage text isn’t possible.

I don’t know if there’s a better way, but you can technically do something extremely kludgy:

<span id="passagetext"><<print Story.get("passageName").text>></span>

<<done>>
    <<set _processedtext = $("#passagetext").text()>>
<</done>>

You could then hide the contents of the <span> with CSS.

This will run all the code in the passage, including all variable changes and anything else that might alter the game state, which you probably don’t want to happen. It will also cause the game to hang if you run it on the current passage for the same reasons Josh explained.

2 Likes

IIRC you can (in JS) output to whatever element, so you could possibly do something similar with an offscreen div or something? Maybe:

<< set _processedText = $('div').wikiPassage("passageName").text()>>

Oh, huh, or there’s <Passage>.processText(), so maybe:

<<set _text = Story.get("passage name").processText()>>

Although it’s not clear to me from the docs if that actually does what its name implies in this context…

1 Like

Hmm, that seems promising, but it seems to return the raw text and not the processed text for some reason?

Dang. I was wondering that from the doc text (“created from applying nobr tag and image passage processing to its raw text.”) but didn’t have time to test…

<Passage>.processText() only does the first step of the processing, it doesn’t also wikify, as you found out :smiley:

To reproduce normal passage rendering you either do a sequence of processText() and wiki() or wikiPassage() as @JoshGrams noted