[I6] Print rule to capitalise a word

I have a custom verb to say something. I want the response to appear in sentence case. For example:

>say hello
"Hello."
>SAY GOODBYE
"Goodbye."

In other words, the noun is converted to sentence case. The first letter is upper case and the remainder is lower case. Is there a print rule in the standard Inform 6 library that does this or do I have to write my own?

PrintCapitalised() should do the job.

That is not a print rule. It is not clear how to use it (as in which parameters are required and what they do). It also looks unsafe due to possible buffer overflow if someone enters a long phrase. Perhaps you could give an example of how to use it.

Look in parser.h for its definition and the definition of Cap() that calls it; it’s quite clear. Otherwise there are also UpperCase() and LowerCase().

Obviously, I looked at that and I didn’t think it was clear. That’s why I was asking for clarification. I thought Cap() looked the safer alternative, but I couldn’t get it to compile in the situation that I was using it.

Ah, I just realised that I was trying to capitalise something that was already subject to my own print rule. Maybe I can just change that.

I had done something like this for the needs of translation, I don’t know if it can help you or mislead you.

[ FirstCapital w;
   PrintToBuffer(StorageForShortName, 160, w);
   PrintFromBuffer(StorageForShortName, true, 1);
];

I’ m not familiar with GLULX.

PrintToBuffer() and PrintCapitalised() are meant to be used on strings or other printables. They write to a temporary buffer, which, as you say, has potential overflow issues.

You want to print out text which is in the input buffer. This is easier because it’s already a character array.

I don’t have code for you, I’m afraid. The plan would be to look at the consult_from and consult_words variables (see §31) to decide what words from the input buffer to print. Then look at the parse buffer to find the character start point and length of each of those words. Then go down the input array, printing character by character, while remembering to capitalize the first one.

1 Like

PrintFromBuffer has potential if I can just work out how to access the buffer. I’m already using consult_from and consult_words. This is what I have now, but without the capitalisation working:

[ firstConsultWord word i;
  for (i=0:i<WordLength(word):i++)
    if (i == 0)
      print (char)WordAddress(word)->i;
    else
      print (char)WordAddress(word)->i;
];

[ consultWord word i;
  for (i=0:i<WordLength(word):i++)
    print (char)WordAddress(word)->i;
];

Extend only 'say' first
  * topic -> Say;

[ SaySub i;
  if (consult_words == 0)
    "You have nothing to say.";
  print "~";
  i = consult_from;
  print (firstConsultWord)i++;
  while (i < consult_from + consult_words)
    print " ", (consultWord)i++;
  print ".~^^";
  if (AfterRoutines())
    return;
  "Nothing happens.";
];

That’s most of the way there. I haven’t tested this, but try:

[ consultWord word i;
  print (char) UpperCase(WordAddress(word)->0);
  for (i=1:i<WordLength(word):i++)
    print (char)WordAddress(word)->i;
];

EDIT: Oops, that’ll capitalize every word in the topic. But you can probably adjust it from there – have a separate CapConsultWord function.

EDIT AGAIN: Heh, I didn’t see that you already had a firstConsultWord() function in there! Silly scrolling panes.

2 Likes

Brilliant. Thanks, Zarf. Works a treat.

I had tried something like that before, but had the (char) after UpperCase and LowerCase rather than before. I thought I had to coerce the word to a character before passing that character to the UpperCase or LowerCase function. Live and learn. It’s one of those idiosynchracies of Inform, I guess.

1 Like

It’s not a type coercion.

WordAddress(word)->i is a character. UpperCase() is a function which takes a character and returns a character. print (char) x prints the character value x.

1 Like

Yes, you’re right. I guess what I was trying to say is that it’s sometimes difficult to work out whether something is returning a char or a word and, in the case of a word, how that is to be interpreted, as most of the weird and wonderful functions within the library are not documented, presumably because they are not meant for public consumption. It’s also hard to work out whether some functions are normal functions or print rules. As you rightly pointed out, (char) is a print rule.

It was all meant for public consumption.

I hate to say it, but in 1995, Graham just wasn’t very good at commenting his code.