Generalising rules for printing

This example from the Inform7 documentation lets you change how “Cleopatra’s nose” is printed, but is there any way to generalise it? Eg say there was a kind “bodypart” so I wanted a rule for printing the name of any bodypart no matter how many kinds of bodyparts are created.

Rule for printing the name of a nose (called target) while asking which do you mean : if everything matched is a nose: if the target is part of a person (called owner): if the owner is the player, say "your own"; otherwise say "[the owner][apostrophe]s"; otherwise: make no decision.

What I’m actually wanting is to create a rule such that any Y that is part of X is just printed as “Y” instead of “X’s Y” (so that I can make it say “Cleopatra’s nose” or “her nose” as context requires, because I want obsessive amounts of control over my diction). So I want something that amounts to “Rule for printing the name of something which is part of something else: say ‘[whatever the kind is]’.” but am getting the feeling my best bet is “Rule for printing the name of something (called it): if it is a nose, say “nose”; otherwise if it is a mouth, say “mouth”, etc etc”.

I don’t think you can get the effect of [whatever the kind is] at all, unfortunately – when I wanted something to test whether two things were of the same base kind, I hacked it using the “printed plural name” property, and no one said “Hey dummy! Use this instead.” Which I think means there isn’t anything obvious to use. And “printed plural name” won’t work for you, since you don’t want the plural. (And of course if anyone does use this hack, they need to make sure not to change anything’s printed plural name in a way that messes things up.)

What I would probably try is something like this:

[code]Definition: A thing is subordinate if it is part of a person.

A thing has some text called the sub-text. The sub-text of a thing is usually “”.
Definition: A thing is sub-textual if its subtext is not “”.

Rule for printing the name of a subordinate sub-textual thing (called target): say the sub-text of the target. [or whatever conditions you want.]

The sub-text of a nose is usually “nose”. [etc. for the different kinds of bodypart][/code]

I’m not entirely sure this compiles, though. And it makes you define sub-texts for everything you want to do this for, instead of doing it in one fell swoop; but it seems nicer to me than the big conditional.

Why not just use the printed name property?

A nose is part of every person. The printed name of a nose is usually "nose".
A mouth is part of every person. The printed name of a mouth is usually "mouth".
etc.

Um, yeah, that’s a good idea. I was thinking more of the OP’s original question about

but of course if she just wants to use this on noses, etc. which are always part of something else, then you can just set the printed name property and not bother with anything else.

My code might or might not still be useful in some circumstances, but it doesn’t seem to be necessary here.

You’re right, of course. Seems I understood the issue slightly differently from you.

Well, I think your understanding was the correct one.

I think in some older builds of Inform (around 5Z71), if you wrote “Every person incorporates a nose” rather than “A nose is part of every person” then the autogenerated noses would be named “nose” instead of “Cleopatra’s nose” or whatever. (This came up in my first RAIF post.) But that seems to have been changed in the latest builds, which is a good thing I think even if it makes things more difficult in this case.

Yeah, I can do:

Rule for printing the name of a nose: say "nose". Rule for printing the name of a mouth: say "mouth".

etc, it just means every time I add a new kind I’ve got to add a new rule; it’d be nice to have something that’d work for everything.

I had the brilliant idea in the shower today of using a “To say” thing with regular expressions to strip out the "X’s ", but then as soon as I sat down to code it I remembered you can’t use let phrases in a to say, so so much for that idea.

…On further reflection, I’ve come up with:

A thing has some indexed text called a printname. The printname of a thing is usually "". When play begins: repeat with it running through things: change the printname of it to "[it]"; if it is part of the player: replace the regular expression "your (.*)" in printname of it with "\1"; otherwise if it is part of something: replace the regular expression ".*<^a-zA-Z >s (.*)" in printname of it with "\1".

and then I can use printname instead of the ordinary printed name. Generally I don’t like creating new variables where an old one will do, but the printed name won’t work here and probably it’s best not to mess with it anyway. :slight_smile:

Thing that’s really useful that I forgot to mention: instead of “[apostrophe]” you can write “[’]”.

That looks like it works. (I thought it might fail on “John Brown’s nose” but it doesn’t.) As I understand it, indexed text can create a lot of overhead – someone better informed can tell you how much – but if that’s not a concern good for you, and maybe the indexed text allows you more control over your diction in the way you want.

(Strictly speaking you don’t need to write a rule for every new kind – Felix’s suggestion doesn’t involve new rules. But it’s just as much typing, I guess.)

John D. Clemens has this phrase on his webpage with Inform 7 tricks:

I couldn’t get it to compile though. (The compiler protested that there was no such constant as i7_kind.)

Undocumented I6 features are subject to change, obviously. It looks like the current equivalent is

To say kind name of (x - thing): (- print (I7_Kind_Name) KindHierarchy–>(({x}.KD_Count)*2); -).

But I haven’t tested that.