Adding an article to string?

Is there some way to add an automatically chosen a/an article to a string, rather than an object? Specifically, a string attribute of an object. I dug through forum and documentation, but every instance of articles refers to pronoun instead, and prefixes, which is what articles seem to be called, are exclusive to objects.


Off the top of my head, you could make a function like this:

<function name="PrefixForString" parameters="word,prepend" type="string">
  output = ""
  if (IsDefined("prepend")) {
    if (prepend) {
      if (IsRegexMatch("^\\s", word)) {
        output = word
      }
      else {
        output = " " + word
      }
    }
  }
  if (IsRegexMatch ("^\\W*[aeiou]", word)) {
    return ("an" + output)
  }
  else {
    return ("a" + output)
  }
</function>

Then you could do stuff like:

  • PrefixForString ("banana") - returns a
  • PrefixForString ("overcoat") - returns an
  • PrefixForString ("tortoise", true) - returns a tortoise
  • PrefixForString ("aubergine", true) - returns an aubergine

(I wasn't sure if you would want the function to return just the prefix, or the prefix and the word; so I tried to make it do either)


Thank you, much appreciated! I am very much not good with regex, so that helps a bunch.


I used a regex rather than just checking the first character (like the English GetDefaultPrefix function does), because it's possible for an object name to start with an apostrophe or hyphen. Rare in English, but it happens, and I prefer my code to Just Work in as many situations as possible without the user needing to think about it. So I used the regex \\W* to make it ignore non-letter characters at the beginning.

But now I realised there's another rare case that I should deal with.

<function name="PrefixForString" parameters="word,prepend" type="string">
  output = ""
  if (IsDefined("prepend")) {
    if (prepend) {
      if (IsRegexMatch("^\\s", word)) {
        output = word
      }
      else {
        output = " " + word
      }
    }
  }
  if (IsRegexMatch ("^[^a-zA-Z]\\d", word)) {
    parts = Populate ("^\\D*(?<number>\\d{1,3})(,?\\d{3})*(?![,\\s]*\\d)", word)
    number = StringDictionaryItem (parts, "number")
    if (number = "1") {
      word = "first"
    }
    else {
      word = ToWords (ToInt (number))
    }
  }
  if (IsRegexMatch ("^\\W*[aeiou]", word)) {
    return ("an" + output)
  }
  else {
    return ("a" + output)
  }
</function>

That's a lot of work… and probably redundant for most people. But it should mean that the function will behave when you want to talk about a 1-cent coin, a 3rd place medal, an 8 dollar bill, or similar things.

(If the string contains a digit before the first letter, it uses a more complex regex to pull out the number and convert it to words before working out whether the string starts with a vowel. It makes a special case for "1", because it's one of very few English words that takes "a" while starting with a vowel. The function will still say "an one inch banana" if the number is written as words; which seems wrong but it would be a lot harder to find and account for all the exceptions. At least it gets it right with digits)

Note that this will only work if you have the game's language set to English, because the function ToWords is included in English.aslx. But I don't think anyone would be using this in a non-English game anyway. I also made the regex discard groups of 3 digits from the end of the number, because ToWords only works for numbers less than 2000. So a 64000-dollar question would pass "64" to ToWords, and get "sixty-four" back. Which is good enough in this case because it has the right first letter.


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums