Making the first character lower case

Howdy, all. My first post.

I was inspired by my friend Aaron Reed’s lovely book about Inform 7 to write a modest IF game. Now I’m having trouble that I’ve been unable to solve alone.

I am trying to append “And” to an arbitrary sentence, changing the first letter of the string to lower case before I do.

I tried this, which didn’t work:

let new text be the description of this event; replace character number 1 in new text with character number 1 in new text in lower case; say "And [description of this event] [run paragraph on]";

It didn’t error, it just didn’t have any effect. Result:

The first word is still in its original sentence case.
So then I tried this more complex version:

let new text be the description of this event; let firstword be word number 1 in new text in lower case; replace word number 1 in new text with ""; say "And [firstword][new text] [run paragraph on]";

But this one revealed something funny. Each time I did something with “new text,” it ran all the text substitutions in the original “description of this event” some of which created random variations. The result was:

Which suffers from two problems: It changed the text since the first word was extracted and the replacement didn’t work at all.

So I’m back to the drawing board.

Any suggestions for how to lower case the first word of text?

Wes

Two things.

First, you’ll want the line let new text be indexed text; before assigning to new text. Ordinary text cannot be modified, and it leaves substitutions unevaluated, whereas indexed text is mutable, and, because it can store only characters, evaluates substitutions when assigned to from ordinary text.

Second, modifications to new text won’t be reflected in the description of the event; they are separate copies. So the say line should read say "And [new text] [run paragraph on]";
The compiler should have complained on the line replace character number 1 in new text with character number 1 in new text in lower case; because the story can’t actually change new text. But instead, it implicitly converted new text from ordinary to indexed text, made the substitution, and then had the resulting value thrown away. That’s a bug, and not one we have in the database, so if you could report it at http://inform7.com/mantis/, it would be much appreciated.

Why don’t you just use something like this? You can use similar concepts for upper case, title case and sentence case, like so.

[code]“Test”

To say stuff:
say “My name is Guybrush Threepwood! Prepare to die![line break]” in title case;
say “My name is Guybrush Threepwood! Prepare to die![line break]” in lower case;
say “My name is Guybrush Threepwood! Prepare to die![line break]” in upper case;
say “My name is Guybrush Threepwood! Prepare to die![line break]” in sentence case.

The Testing Room is A Room. The description of the testing room is “[stuff]”.[/code]

Hope this helps.

I understood from the documentation that when you asked inform to do replacements or extract a word or a character that it casts the text variable as indexed text. But I didn’t know about the uncomfortable side effects. And though I read about starting its life as indexed text I had not tried it yet.

let new text be indexed text; let new text be the description of this event; replace character number 1 in new text with character number 1 in new text in lower case; say "And [new text] [run paragraph on]";

Here’s the result:

Perfect. Thanks.

In these two examples:

say "My name is Guybrush Threepwood! Prepare to die![line break]" in lower case; say "My name is Guybrush Threepwood! Prepare to die![line break]" in sentence case.

The results are unsatisfactory:

It was precisely that, the capitalization of proper nouns, why I didn’t cast the whole sentence in lowercase and add a conjunction.

In that case, you want something like this.

[code]“Test”

To say stuff:
say "My name is " in title case;
say “Guybrush Threepwood”;
say “! Prepare to die![line break]” in title case;
say "My name is " in lower case;
say “Guybrush Threepwood”;
say “! Prepare to die![line break]” in lower case;
say "My name is " in upper case;
say “Guybrush Threepwood”;
say “! Prepare to die![line break]” in upper case;
say "My name is " in sentence case;
say “Guybrush Threepwood”;
say “! Prepare to die![line break]” in sentence case.

The Testing Room is A Room. The description of the testing room is “[stuff]”.[/code]

Hope this helps.

From my very first post! Now this no longer works:

"Let's hustle" Lee crosses the tracks and heads to the grassy field. And tou hear the train whistle, loud and close, as it hits the crossing.

It replaced the capital Y with a lowercase t.

Any ideas why this no longer works?

2 Likes

try let new text be the substituted form of description of this_event

I would hazard the reason it doesn’t work as expected is the oft-noted point that a text with substitutions can really be regarded not as a string but as a routine to produce a text. Referencing a ‘text with substitutions’ in code as a text can cause the routine to run and a text to be produced each time- and potentially a different text each time if the substitutions include random elements.

So your code says (in pseudocode):

let new text be a reference to the text-producing routine 'description of this_event';
retrieve the first character of the next text produced by that routine, make it lower case, store it temporarily;
retrieve the next text produced by that routine, store it as a true string assigning 'new text' to that string, and replace the first character with that just retrieved & stored previously;
say "And [the stored modified string new text] [run paragraph on]";

As you’ll see, this means that the text-producing routine ends up being run twice, with the (lower-case) 1st character of the text produced the 1st time substituting for the first character of the text produced 2nd time.

Doing as Zed suggests will mean the text-producing routine is run and the result stored only once, at the point of the first assignation to new text, with all further manipulations being performed on that stored result, because from the start new text is now a true string, not a pointer to a routine.

I assume it used to work this way automatically because in previous versions of Inform assigning to an indexed text would have achieved the same effect as assigning the substituted form of i.e. causing the text-producing routine to be run with immediate effect with the assignment being to the resulting string, rather than being initially assigned as a pointer to a routine, as now happens by default (under the hood, Inform still has true strings (indexed text) and text-producing-routines, but in source they are all simply referred to as text with conversion from one to the other happening automatically as required. The term indexed text still compiles, but is treated equivalently to text- although as you demonstrate here, the actual effect may end up being different to what it was).

2 Likes