a/an before vowels

Hi all,

I can’t believe i’m having to ask this, but what’s the syntax for putting a or an in front of a consonant or vowel respectively?

i.e.
say “[an] [one of]cat[or]dog[or]aardvark[at random]”;

I honestly can’t find a mention of it on the docs

Thank you!

Ade

This does not exist for texts.

(For objects, you can say “[a obj]” and that will work.)

In that case, I’d suggest just including the article in the alternatives - “[one of]a cat[or]a dog[or]an aardvark[at random]”.

Ok…thanks z. That explains why I can’t find it.

Here’s a little function to insert the indefinite article b4 a text.

[code]Every turn:
choose a random row in the table of XAnimals;
say “[ind_art animal entry in title case] [animal entry].”;

To decide what text is the ind_art (TRA - a text):
Let J be “”;
Let I be character number 1 in TRA;
if I is “A” or I is “E” or I is “I” or I is “O” or I is “U” or I is “a” or I is “e” or I is “i” or I is “o” or I is “u”:
Let J be “an”;
otherwise:
Let J be “a”;
decide on J.

Table of XAnimals
animal
“cat”
“dog”
“aardvark”[/code]

It won’t work for [one of]…[at random] as the function isn’t resolved.

Ade.

Hi Cm - This was a much simplified example of a general indefinite article syntax for a text. I would do as you say usually.
Thank you!

Ade

Here’s a try that uses Text Capture to look ahead:

Include Text Capture by Eric Eve.

Lab is a room. 

Capturing text for article is initially false.

To say a-an of -- beginning a-an_of: 
	if text capturing is active: [if we're capturing text already, we can't start capturing it again for the article, so we punt--a better solution would be to buffer the old captured text to another variable]
		say "a ";
	otherwise:
		now capturing text for article is true;
		start capturing text.

To say end a-an -- ending a-an_of:
	if capturing text for article is true: [if we wound up not capturing text for the article, we don't want to do this]
		stop capturing text;
		if character number 1 in "[captured text]" is a vowel:
			say "an [captured text]";
		otherwise:
			say "a [captured text]";
	now capturing text for article is false.
	
To decide whether (letter - a text) is a vowel:
	if letter exactly matches the regular expression "a|e|i|o|u|A|E|I|O|U", yes;
	no.
	
Every turn: say "You see [a-an of][one of]red[or]orange[or]yellow[or]green[or]blue[or]indigo[or]violet[cycling][end a-an] light."

Of course, if you’re already using Text Capture it gets awkward. Also it won’t capture exceptions like “uniform” or “honest” or “ytterbium,” which I guess you’d have to special-case in the part that currently tests whether it begins with a vowel. Also when I tried to get A-An to work with uppercase articles, I got errors–presumably I could solve that by making the substitution [capital A-An], though it seems inelegant. (Or I might have just messed up.)

Unfortunately, both your phrases for deciding which indefinite article to use are easily thwarted - for example (at least in my dialect), we say “a unicorn” but “an hour”. Neither would be correctly guessed by your code, and the only way to make it work would be dictionary lookup.

With objects it works because each object stores its own indefinite article as part of its definition.

This is actually quite interesting. I’ve been doing a lot of procedural text generation, and the indefinite article rule is, as you point out, not an absolute at all. An uninterrupted power supply. An uncle. A unicorn. A uniform. A euphonium. An before a vowel except when it isn’t. The glide [j] of the initial y sound is the exception. Or an unsounded ‘H’. An honorable. An honest. I’m not ready to introduce phonetic pronunciation tags into my code as yet, so I’m avoiding instances of exception in my text.

Although, I’m now thinking about having:

IAExceptions is a list of text that varies. IAExceptions is {“honorable”,“uniform”,“unicorn”…}.

Then it’s easy enough to have an extra condition:

If X is listed in IAExceptions…

hmmm…

To say a-an of – beginning a-an_of:

BTW - I was completely unaware that syntax existed. It is well buried in the documentation! It’s pretty cool. thanks matt.

Ade

I think this is poorly extensible, though. Using a table might be better. Or an activity:

Printing an indefinite article is an activity on text.

To say end a-an -- ending a-an_of:
	if capturing text for article is true: [if we wound up not capturing text for the article, we don't want to do this]
		stop capturing text;
		begin the printing an indefinite article activity for the captured text;
		if handling the printing an indefinite article activity for the captured text:
			if character number 1 in "[captured text]" is a vowel:
				say "an ";
			otherwise:
				say "a ";
		end the printing an indefinite article activity for the captured text;
		say captured text;
	now capturing text for article is false.

Rule for printing the indefinite article of "honour":
	say "an ".

Rule for printing the indefinite article of "uniform":
	say "a ".

Mind you, I’m not entirely happy with the one rule per exception word that that approach results in, but it does mean anyone can add additional words. A table would also allow this, via table continuations, while being quite a bit simpler.

Admittedly, with a list it could still be amended at runtime, but I prefer to be able to set up all the initial state at compile time. (It would be nice if the command prompt and status line texts also allowed this. Oh well.) I guess you could have two lists - IAExceptions, which you define, and IAExceptionsExtra, which is just defined as “a list that varies” without giving a value, but that still means you need to join them at runtime (or check in both).

…of course, I’m speaking as if this is being done for an extension. If it’s just for yourself, none of that matters!

Probably because the use of this syntax normally involves I6 inclusions. I’m actually kind of surprised that it has been used here without them.

Nope. You can define an indefinite article property for any object, but normally the library guesses based on initial letter.

Yeah, I had sort of been under the impression that you had to at least define an I6 constant to get a segmented substitution working, but you don’t. (Or maybe I’m thinking of use options.) Anyway, this is from §27.28, which is the antepenultimate section of Writing with Inform. It does get translated directly into I6–well, everything does, but a-an_of gets turned directly into an I6 identifier, which is why I think I can’t define A-An_of separately, because I6 identifiers aren’t case-sensitive, I expect. Though if that were the problem it seems as though it should work to define [A-An of] and [end A-An of] and leave the I6 thingy as uppercase_A-an_of. Maybe the problem is that Inform doesn’t distinguish [end a-an of] and [end A-An of], because the difference in capitalization doesn’t come at the beginning.

Anyway, here’s something with a proviso for doing it in uppercase–oh, the blather in the last paragraph was all about why the straightforward way of doing that with “[A-An of]” doesn’t work. And a change in the routine so you can have a table of exception words. I made it a table rather than a list because I think tables are quicker to check, but who knows. If you have lots of hyphenations you might want to change things up a little, using punctuated words instead of words (if I’ve got that right).

Include Text Capture by Eric Eve.

Lab is a room. 

Capturing text for article is initially false.

To say a-an of -- beginning a-an_of: 
	if text capturing is active: [if we're capturing text already, we can't start capturing it again for the article, so we punt--a better solution would be to buffer the old captured text to another variable]
		say "a ";
	otherwise:
		now capturing text for article is true;
		start capturing text.

To say end a-an -- ending a-an_of:
	if capturing text for article is true: [if we wound up not capturing text for the article, we don't want to do this]
		stop capturing text;
		if "[captured text]" starts with a vowel sound:
			say "an [captured text]";
		otherwise:
			say "a [captured text]";
	now capturing text for article is false.
	
To say uppercase A-An of -- beginning uppercase_A-An_of: 
	if text capturing is active: [if we're capturing text already, we can't start capturing it again for the article, so we punt--a better solution would be to buffer the old captured text to another variable]
		say "A ";
	otherwise:
		now capturing text for article is true;
		start capturing text.

To say end uppercase A-An -- ending uppercase_A-An_of:
	if capturing text for article is true: [if we wound up not capturing text for the article, we don't want to do this]
		stop capturing text;
		if "[captured text]" starts with a vowel sound:
			say "An [captured text]";
		otherwise:
			say "A [captured text]";
	now capturing text for article is false.

To decide whether (string - a text) starts with a vowel sound:
	let the first word be word number 1 in string;
	if the first word is a word listed in the Table of Words That Start With Vowel Sounds, yes;
	if the first word is a word listed in the Table of Words That Don't Start With Vowel Sounds, no;
	if character number 1 in the first word is a vowel, yes;
	no.
	
To decide whether (letter - a text) is a vowel:
	if letter exactly matches the regular expression "a|e|i|o|u|A|E|I|O|U", yes;
	no.
	
Table of Words That Start With Vowel Sounds
word
"hour"
"hourglass"
"honest"
"yttrium"

Table of Words That Don't Start With Vowel Sounds
word
"uniform"
"unicorn"
"united"
"United"
	
Every turn: say "You see [a-an of][one of]red[or]orange[or]yellow[or]green[or]blue[or]indigo[or]violet[cycling][end a-an] light and [a-an of][one of]honest broker[or]hourglass[or]United States flag[or]umber hulk[or]unicorn[or]elf[or]battery[or]honest broker[at random][end a-an]. [Uppercase A-An of][one of]green[or]blue[or]violet[or]red[or]orange[or]what is the opposite of indigo really, that is such a bogus color[or]yellow[cycling][end uppercase A-An] afterimage is visible after it fades."

Note that the exception list is case-sensitive–you’d get “an Uniform Code of Criminal Justice.” It wouldn’t be that hard to fix that, probably by forcing the first word into upper case and then putting on caps lock while you type the tables of exceptions. Though if your game includes a US flag and an Us Weekly, you’ll want the case-sensitivity.

Oh… you’re right. I thought it guessed based on the article you used when defining it, but I guess I was wrong.

Still, they do store an indefinite article as part of their definition, which will be used in place of the guess if it’s provided.

(It does notice if you used “some” rather than “a/an”, but I think it really should also notice when you use “a/an”, though I guess people often define with “the” instead and then it would have no way of knowing. And using “some” sets the plural-named property rather than the indefinite article property.)

Necro’ing, but I realized that you can use this trick in front of any sayable value.

To decide what text is a-an (T - sayable value): let string be the substituted form of "[T]"; if string starts with a vowel sound: decide on "an [string]"; otherwise: decide on "a [string]".

(Given the code I had elsewhere about “starts with a vowel sound.”)

This won’t capture the original use case, with a [one of]…, though in that case you might be able to put the articles inside the [one of] (as the first reply pointed out). In some other cases you might have to wrap something in a “to decide what text” phrase. But this seems more flexible and more palatable than the Text Capture solution.

Here’s a code example, with an additional “uppercase” operator because you can’t write a different phrase for A-An (that works for text substitutions but not for phrases):

[code]Lab is a room.

To decide what text is a-an (T - sayable value):
let string be the substituted form of “[T]”;
if string starts with a vowel sound:
decide on “an [string]”;
otherwise:
decide on “a [string]”.

To decide what text is uppercase (T - sayable value):
let string be the substituted form of “[T]”;
replace character number 1 in string with character number 1 in string in upper case;
decide on string.

To decide what text is upper case (T - sayable value):
decide on uppercase T.

To decide whether (string - a text) starts with a vowel sound:
let the first word be word number 1 in string;
if the first word is a word listed in the Table of Words That Start With Vowel Sounds, yes;
if the first word is a word listed in the Table of Words That Don’t Start With Vowel Sounds, no;
if character number 1 in the first word is a vowel, yes;
no.

To decide whether (letter - a text) is a vowel:
if letter exactly matches the regular expression “a|e|i|o|u|A|E|I|O|U”, yes;
no.

Table of Words That Start With Vowel Sounds
word
“hour”
“hourglass”
“honest”
“yttrium”

Table of Words That Don’t Start With Vowel Sounds
word
“uniform”
“unicorn”
“united”
“United”
“one”

Color is a kind of value. The colors are red, orange, yellow, green, blue, indigo, and violet.

When play begins:
repeat with hue running through colors:
say “You see [a-an hue] stripe.”;
repeat with index running from 1 to 20:
say “You see [a-an color description] block.”;
repeat with hue running through colors:
say “[Uppercase a-an hue] orb is here.”

To decide what text is color description:
decide on “[random color][if a random chance of 1 in 2 succeeds] and [a-an random color]”.
[/code]

You should be able to set this per object also if that matters, but it looks like you were setting up a text phrase.

[code]Test Room is a room.

the unicorn is here.
some socks are here.

the indefinite article of the unicorn is “a”.
the indefinite article of socks is “a pair of”.

Every turn:
say “This room contains [a list of touchable objects]!”
[/code]

Yeah, the idea is that you want to be able to look ahead at the next letter in case you have an adjective that starts with a vowel. Like this (appended to the previous code):

[code]A block is a kind of thing. A block has a color. A block is usually proper-named. Understand the color property as describing a block.
Rule for printing the name of a block: say “[a-an color of the item described] block”.

One red block and one orange block are in Lab.
[/code]

This works nicely in limited applications but probably isn’t too flexible. A better thing would be to feed this into the indefinite article somehow but messing with indirect articles seems really fragile–there’s that business about how checking the indirect article runs the rules for printing the name of a thing, or however it works. In fact, my attempt keeps producing run-time errors even though it’s also working–I have no idea what’s going on, and the errors are happening outside of any rule that shows up with a rules trace, and the runtime error says it’s “paragraph 1 of the source text” which is not useful. Any suggestions? Here’s the complete code:

[code]Lab is a room.

To decide what text is a-an (T - sayable value):
let string be the substituted form of “[T]”;
if string starts with a vowel sound:
decide on “an [string]”;
otherwise:
decide on “a [string]”.

To decide what text is uppercase (T - sayable value):
let string be the substituted form of “[T]”;
replace character number 1 in string with character number 1 in string in upper case;
decide on string.

To decide what text is upper case (T - sayable value):
decide on uppercase T.

To decide whether (string - a text) starts with a vowel sound:
let the first word be word number 1 in string;
if the first word is a word listed in the Table of Words That Start With Vowel Sounds, yes;
if the first word is a word listed in the Table of Words That Don’t Start With Vowel Sounds, no;
if character number 1 in the first word is a vowel, yes;
no.

To decide whether (letter - a text) is a vowel:
if letter exactly matches the regular expression “a|e|i|o|u|A|E|I|O|U”, yes;
no.

Table of Words That Start With Vowel Sounds
word
“hour”
“hourglass”
“honest”
“yttrium”

Table of Words That Don’t Start With Vowel Sounds
word
“uniform”
“unicorn”
“united”
“United”
“one”

Color is a kind of value. The colors are red, orange, yellow, green, blue, indigo, and violet.

A block is a kind of thing. A block has a color. A block can be definitely described or indefinitely described. The indefinite article of a block is usually “[indefinite with color for the item described]”. Understand the color property as describing a block.

Before printing the name of a block (called cube) when the cube is definitely described: say "[color of the cube] ".

To say indefinite with color for (cube - a block):
now the cube is indefinitely described;
say "[a-an color of the cube] ".

After printing the name of a block (called cube):
now the cube is definitely described.

One red block and one orange block are in Lab.[/code]

Output:

The explanation of the error:

I don’t see why this produces an error, and I definitely don’t see why it works perfectly well when printing the text and then produces an error at the end of the turn.

OK, some clueless thrashing about reveals that the problem is that at the end of the turn this code is trying to silently run “indefinite with color” on the Lab. So a workaround is to replace the definition of “indefinite with color” with this:

To say indefinite with color for (cube - an object): if cube is a block: now the cube is indefinitely described; say "[a-an color of the cube]".

Now if I knew why this was running “indefinite with color” on the Lab, I would be happier. It might help explain why the next thing I’m trying isn’t working.

OK, here’s a further kick. I decided to try to make a more general routine, because the one I had was pretty ugly–it depends on the fact that the first thing after the article for a block will always be the color, and requires some nitpicky workarounds there. That wouldn’t do if, for instance, we wanted to be able to describe containers as “an empty bottle” or “an open chest,” when we wouldn’t necessarily be sure which adjective would come first.

So I thought I’d try to write something generic that runs the routine for printing the name of the item, grabs its text, and runs the a-an routine on that. Here’s what I came up with–the first half is just the a-an business from a few posts ago, which is still working as expected; the good stuff starts at “An object is already printed with the article.”

[spoiler][code]Use the serial comma.

Lab is a room.

To decide what text is a-an (T - sayable value):
let string be the substituted form of “[T]”;
if string starts with a vowel sound:
decide on “an [string]”;
otherwise:
decide on “a [string]”.

To decide what text is uppercase (T - sayable value):
let string be the substituted form of “[T]”;
replace character number 1 in string with character number 1 in string in upper case;
decide on string.

To decide what text is upper case (T - sayable value):
decide on uppercase T.

To decide whether (string - a text) starts with a vowel sound:
let the first word be word number 1 in string;
if the first word is a word listed in the Table of Words That Start With Vowel Sounds, yes;
if the first word is a word listed in the Table of Words That Don’t Start With Vowel Sounds, no;
if character number 1 in the first word is a vowel, yes;
no.

To decide whether (letter - a text) is a vowel:
if letter exactly matches the regular expression “a|e|i|o|u|A|E|I|O|U”, yes;
no.

Table of Words That Start With Vowel Sounds
word
“hour”
“hourglass”
“honest”
“yttrium”

Table of Words That Don’t Start With Vowel Sounds
word
“uniform”
“unicorn”
“united”
“United”
“one”

Color is a kind of value. The colors are red, orange, yellow, green, blue, indigo, and violet.

A block is a kind of thing. A block has a color. Understand the color property as describing a block.

Before printing the name of a block (called cube):
say "[color of the cube] ".

An object can be already printed with the article. The indefinite article of a block is usually “[adaptive article of the item described]”.

To say adaptive article of (item - an object):
if item is not already printed with the article:
let T be the substituted form of “[item]”;
now the item is already printed with the article; [if the previous two lines are switched, this doesn’t work at all]
say “[a-an T]”.

First before printing the name of an object (called item) that is already printed with the article:
do nothing instead.

First for printing the name of an object that is already printed with the article:
do nothing.

First after printing the name of an object (called item) that is already printed with the article:
now the item is not already printed with the article instead.

One red block and one orange block are in Lab.

A fancier is a person in the lab. The indefinite article of the fancier is “[adaptive article of the item described]”. [if we write "[adaptive article of the fancier] " instead, the name prints blank!]
Before printing the name of the fancier:
say "[one of]cat[or]dog[or]aardvark[cycling] ".[/code][/spoiler]

Output:

Note that there’s an extra space after “a red block” but not after “an orange block.” Some experiment with debugging text confirms that this is where the rules before/for/after printing the name of an object that is already printed with the article are running. Not sure why they don’t run for the orange block.

If I switch the two lines that I mention in the “To say adaptive article of” phrase, then we get “a red block, a orange block”–with an extra space going before “red” and “orange,” and the test for whether the word starts with a vowel failing for “orange.” The debugging text confirms that the extra space is where the rules before/for/after printing the name of an object that is already printed with the article are running.

Also, for the cat/dog/aardvark fancier, note that the indefinite article you get depends on whether the next thing it’s planning to print starts with a vowel, not whether the one it’s about to print does. I think this may be an inescapable side-effect of the way Inform now preloads its text substitutions, which is too bad, because it makes this approach pretty useless.

Also! If I change the indefinite article of the fancier from “[adaptive article of the item described]” to “[adaptive article of the fancier]”, then the fancier’s name goes completely blank, thus:

Why is that happening? They’re two calls to the same object.

There is something strange going on here, some of it partly in my code, but I also think that the adaptation of indefinite articles is wobbly and tends to fall over when pushed. Which is too bad, because I’d really like to be able to do this smoothly without special-casing it every time I add a new way to vary my text.

Continuing to talk to myself, I whittled down the first problem I was having to a minimal case and reported it; the problem seems to be specifically with an indefinite article calling a say phrase with “item described” as an argument. Hopefully this will produce a bit of clarity.