[i7] Abbreviated nouns with periods

There is a building in my WIP called ‘St. Christopher House’. That is its proper name, so matters of opinion as to whether it is desirable to expand ‘St.’ into ‘Saint’ are not really relevant: this is an attempt to depict the reality of a particular Toronto geography, so I need to spell it as it is written on the actual building. But Inform 7 won’t accept names with periods in them. I can give it the appearance of having the correct name with…

The printed name of Saint Christopher House is “St. Christopher House”.

…but the player can’t refer to it that way, and when I try a line like…

Understand “St. Christopher House” as Saint Christopher House.

…i7 rejects that too, saying punctuation isn’t allowed there. I also tried using a text substitution that references a period without any line break, like so…

Understand “St[dot] Christopher House” as Saint Christopher House.

…but i7 didn’t like that either, says it was unable to understand what I meant by the grammar token ‘dot’.

I am at a personal dead-end in getting this building to respond to the player as it should. Any ideas that do not involved renaming the building to my own or i7’s tastes, since that’s not really an option here?

Thanks for any light you could shed,

Paul.

P.S. This is also an issue that comes up when trying to refer to churches by their proper legal names.

As far as understanding the period properly goes, have you tried Emily Short’s Puncutation Removal extension? It seems as though the “Abbreviation” example is the sort of thing you need.

Thanks Matt, I haven’t tried it. I will check it out. Hate to add an extension just for this – hopefully I can just hack what I need out of it.

P.S. There were typos in my original examples above, now corrected.

If you don’t want to add the extension, I think you will at least need to duplicate the relevant parts of it. The I7 parser is somewhat hostile to punctuation currently.

I have high hopes that Ron Newcomb’s translation of the parser into I7 will lead to a new renaissance in this area, though.

I never want to add an extension, because they almost always solve more than I need solved. Particularly since there are many IF command conventions that I disagree with and prefer blocked; thus I don’t need any code that serves to keep those command options open.

So I will probably either do exactly as you suggest, or rejig the geography so that the protagonist doesn’t actually come anywhere near St. Christopher House. It’s not an important landmark to me; it just happens to sit prominently on a street corner I am using.

Paul.

Then you should definitely download the extension and figure out how it does what it does. :slight_smile:

Yep. I will try that first. 8)

If it’s only this one word, you could replace “st.” with “saint” (or “st”) before the game parses the command.

After reading a command: let T be indexed text; let T be the player's command; replace the text "st." in T with "saint"; change the text of the player's command to T.

Way exceeding my competence here, but my guess is that like you can get what you want from Punctuation Removal like this:

[spoiler][code]To resolve punctuated titles:
(- DeTitler(); players_command = 100 + WordCount(); -)

Include (-

[ Detitler i j buffer_length flag;

#ifdef TARGET_ZCODE;
buffer_length = buffer->1+(WORDSIZE-1);
#endif;
#ifdef TARGET_GLULX;
buffer_length = (buffer–>0)+(WORDSIZE-1);
#endif;
for (i = WORDSIZE : i <= buffer_length: i++)
{
if ((buffer->i) == ‘.’ && (i > WORDSIZE + 1))
{
! flag if the period follows Mr, Mrs, Dr, prof, rev, or st
!
! This is hackish, but our hearts are pure

		if ((buffer->(i-1)=='r') && (buffer->(i-2)=='m') && ((buffer->(i-3)==' ') || ((i-3) < WORDSIZE))) flag = 1;
		if ((buffer->(i-1)=='r') && (buffer->(i-2)=='d') && ((buffer->(i-3)==' ') || ((i-3) < WORDSIZE))) flag = 1;
		if ((buffer->(i-1)=='t') && (buffer->(i-2)=='s') && ((buffer->(i-3)==' ') || ((i-3) < WORDSIZE))) flag = 1;
		if ((buffer->(i-1)=='s') && (buffer->(i-2)=='r') && (buffer->(i-3)=='m') && ((buffer->(i-4)==' ') || ((i-4) < WORDSIZE))) flag = 1;
		if ((buffer->(i-1)=='v') && (buffer->(i-2)=='e') && (buffer->(i-3)=='r') && ((buffer->(i-4)==' ') || ((i-4) < WORDSIZE))) flag = 1;
		if ((buffer->(i-1)=='f') && (buffer->(i-2)=='o') && (buffer->(i-3)=='r') && (buffer->(i-4)=='p') && ((buffer->(i-5)==' ') || ((i-5) < WORDSIZE))) flag = 1;
		if (flag) buffer->i = ' ';   
	}
}
VM_Tokenise(buffer, parse);

];

-)

After reading a command:
resolve punctuated titles.[/code][/spoiler]

At an even wilder guess, if “st.” is the only title you need to resolve, you can probably do this:

[spoiler][code]To resolve punctuated titles:
(- DeTitler(); players_command = 100 + WordCount(); -)

Include (-

[ Detitler i j buffer_length flag;

#ifdef TARGET_ZCODE;
buffer_length = buffer->1+(WORDSIZE-1);
#endif;
#ifdef TARGET_GLULX;
buffer_length = (buffer–>0)+(WORDSIZE-1);
#endif;
for (i = WORDSIZE : i <= buffer_length: i++)
{
if ((buffer->i) == ‘.’ && (i > WORDSIZE + 1))
{
! flag if the period follows st
!
! This is hackish, but our hearts are pure

		if ((buffer->(i-1)=='t') && (buffer->(i-2)=='s') && ((buffer->(i-3)==' ') || ((i-3) < WORDSIZE))) flag = 1;
		if (flag) buffer->i = ' ';   
	}
}
VM_Tokenise(buffer, parse);

];

-)

After reading a command:
resolve punctuated titles.[/code][/spoiler]

Juhana’s solution is surely nicer, but this might work if you don’t want to use indexed text.

I do like being able to enter multiple commands on the same line, but it does not work well with titles. Perhaps this is another reflection of Inform’s British origins.

(BTW, you don’t have to download this extension; it’s built-in.)

Thanks again Matt, and also Juhana. These are some good tips. Juhana’s does certainly look more compact; I’m not sure what the consequences will be of converting the command to indexed text. In any case I will try both out and see how they shake out.

P.

The conversion from a snippet to indexed text is only so that you can compare and modify it. Note that the last line isn’t changing the player’s command, it’s changing the text of the player’s command.

Oh yes… I see your point and of course the indexed text type will not be carried from T into that text: just the data, right? So the text of the player’s command will remain non-indexed, I assume. Or, if not, it may not even matter, since as I say I don’t even know why indexed text would create a problem. Presumably it’s a data type that eats up more memory than an ordinary string variable, otherwise they’d all be indexed. I am not storing a lot of player commands (or texts of player commands) so it’s hard to see how it would have any bad consequences, anyway.

It looks like this is going to be the simplest way. I just haven’t tried any ways yet because this solution got postponed in favour of other improvements that are now holding my attention. Thanks again!

Paul.

If I’m not mistaken, indexed text is stored on the heap, so it can theoretically lead to runtime problems on the Z-machine. In practice, I don’t think that happens under normal usage. All “dynamic” data types (indexed text, stored actions, and lists) are stored the same way. The first time you use them, there’s a big jump in memory usage as the storage is allocated, but to use more doesn’t take up much additional space.

I think normal “text” is stored in compressed form, and only uncompressed when it is printed.

The text of the player’s command is an I6 character array, a data type not accessible in I7. See Ron Newcomb’s work on the parser for a (not practical for everyday use) way around this.