Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

How to change the text of the current passage? (Sugarcane)

Maybe my previous question was formulated not clearly, so I'm re-formulating it.
I need to change the text of a passage, depending on a condition (in my case, if not $forward, all "left" must be replaced to "right" and vice versa). Please explain me how to do it.
So far, I found out that state.history[0].passage.text=newtext doesn't work, and there is no innerHTML property of state.history[0].passage.

Comments

  • Why not simply use the <<if>> macro and/or $variables? That's the reason they exist—to allow you to have logic within your passages.
  • Why not simply answer my question? I'm sure you know how to do it. And I know what I do need and what I don't.
    I don't want to sound rude, but if someone asks your "why using cycle instead of typing the same block 1000 times", what will be your reaction?
  • edited March 2016
    @yun
    Did you stop and think that the reason that TheMadExile may of been asking you why you are not using a simple built-in feature to achieve your desired result was so that they could determine if it is necessary for them to spend the time and effort needed to first implement, then test and finally describe a more complex solution to your request. (assuming that such a solution is possible)

    Please remember that community members are not obligated to expend the time and effort it takes to answer other peoples questions.
  • Yun: based on your previous question, it does seem like your inverted direction problem could be solved with variables (from what I understand). I posted my thoughts there.
  • yunyun
    edited March 2016
    I can accept the answer "this is way too complex to do", while this surprises me very much - I was sure that was an easy task for everyone who knows how exactly the passages are coded and processed, and that it was solved already long ago. But I hate to get answers which are not to my question, like "Where can I find toilet paper? - Why not using sandpaper instead?"
    Definitely I know what variables are and can type manually <<$left>> instead of "лев" (that's the root of the word "left" in my language) in every place of every passage and same for "right" (and forward and backward), luckily Sugarcane even accepts it in links (not all story formats do), but this is inconvenient, and one-time adding of several lines to prerender or postrender function is much better.
    I found that if I scan the children of document.getElementById("storeArea"), I will get nameless(!) divs with passage codes, which can be recognized by the attribute "tiddler" which has the passage name, so to get the current passage innerHTML, I can every time(!) scan the whole "storeArea" checking this attribute. And I am still not sure that FoundPassage.innerHTML=MyReplaceFunction(FoundPassage.innerHTML) will work (will it?) Anyway, this looks awkward. I was sure there was a simpler way to access and change the current passage code. Am I wrong?
  • edited March 2016
    You can also access loaded Passage objects via the tale.get() function, entering the following in the Console of your web-browser's Development Tools will output the Start passage object data:
    tale.get('Start');
    
    ... which can be used to access/modify the content of a Passage object (before it is rendered/displayed) but that is when the actual fun starts!

    The real issue is writing the string replacement code in a generic way (which a third person would have to do because they don't know your story like you do) that does not cause unwanted side-effects like:

    a. changing the letter case of the replaced words.
    eg. Right becomes left.

    b. changing part of a word.
    eg. Copyright becomes Copyleft.

    c. changing a link's target passage name.
    eg. Boss left the room becomes Boss right the room

    d. changing embed CSS
    eg. style="left: 3em;" becomes style="right: 3em;"

    e. anything else I did not think of in the time it took me to write this reply...

    Using $variables is a lot simpler, but if you feel up to the challenge then I wish you all the best.
  • Great! And really simple, as I thought ;)
    So, this code works:
    prerender['runBeforeTheNextPassage'] = function () {
     function turnback(str) {str=str.replace(/лев/g,"ПРАВ");str=str.replace(/прав/g,"лев");return str.replace(/ПРАВ/g,"прав");}
     if (state.history[0].passage.title.indexOf("maze")==0 && !state.history[0].variables["forward"])
     { tale.get(state.history[0].passage.title).text=turnback(tale.get(state.history[0].passage.title).text);
    }
    };
    

    As for "side effects", I considered them of course. Most of them are not relevant to me just because my language is not English and my alphabet is not Latin.
  • yun wrote: »
    Great! And really simple, as I thought ;)
    It may of been simple for you as all you had to do was read the answer. *smile*

    But I had to go to the Sugarcane repository, find the code related to displaying a passage, determine how it accessed the relevant Passage object, check if the conversion of that object's passage text into DOM elements happens before or after the prerender, write a test harness to check that modifying the object's passage text in a prerender actually works and then write up the answer I gave.
  • greyelf wrote: »
    been simple for you as all you had to do was read the answer. *smile*

    But I had to go to the Sugarcane repository, find the code related to displaying a passage, determine how it accessed the relevant Passage object, check if the conversion of that object's passage text into DOM elements happens before or after the prerender, write a test harness to check that modifying the object's passage text in a prerender actually works and then write up the answer I gave.

    Thanks for your efforts!
    Again, I thought someone knew the answer already when I asked my question. Anyway, now we know ;)
  • Some more points for those who want to use this trick. If used in prerender/postrender function, this.text can be used instead of tale.get(state.history[0].passage.title).text (yes, really THAT simple). And, more important, all these variants change the passage text permanently, so if you need to alter it only temporary, save it to a global variable in prerender and restore in postrender. Like this:
    var tmp;
    
    prerender['runBeforeTheNextPassage'] = function () {
    if (this.title.indexOf("maze")==0)
    {tmp=this.text;
     if (!state.history[0].variables["forward"]) this.text=turnback(this.text);
     }
    };
    
    postrender['runBeforeTheNextPassage'] = function () {
    if (this.title.indexOf("maze")==0)
     this.text=tmp;
    }
    
Sign In or Register to comment.