@@ -73,6 +73,15 @@ interface WordOptions {
count: boolean;
}
const emptyConfig: WordOptions = {
capital: false,
count: false,
kind: NounKind.Specific,
plural: false,
proper: false,
vowel: VowelSound.Default
}
export type TextLike = { toString: () => string }
// updates as needed
@@ -96,61 +105,98 @@ export class DynText {
return (this.parts.map(part => part.toString())).join('')
}
}
export class Noun implements Pluralizable {
constructor (private singularNoun: string, private pluralNoun: string|null = null, private options: WordOptions = { plural: false, capital: false, proper: false, kind: NounKind.Specific, vowel: VowelSound.Default, count: true }) {
export abstract class Word {
constructor (public opt: WordOptions = emptyConfig) {
}
get capital (): Noun {
const opts: WordOptions = Object.assign({}, this.options)
abstract configure (opts: WordOptions): Word;
abstract toString (): string;
// These functions are pure; they don't mutate the original object.
// This is necessary to avoid causing chaos.
get capital (): Word {
const opts: WordOptions = Object.assign({}, this.opt)
opts.capital = true
return new Noun(this.singularNoun, this.pluralNoun, opts)
return this.configure( opts)
}
get plural (): Noun {
const opts: WordOptions = Object.assign({}, this.options)
get plural (): Word {
const opts: WordOptions = Object.assign({}, this.opt)
opts.plural = true
return new Noun(this.singularNoun, this.pluralNoun, opts)
return this.configure( opts)
}
get proper (): Noun {
const opts: WordOptions = Object.assign({}, this.options )
get proper (): Word {
const opts: WordOptions = Object.assign({}, this.opt)
opts.proper = true
return new Noun(this.singularNoun, this.pluralNoun, opts)
return this.configure( opts)
}
get improper (): Noun {
const opts: WordOptions = Object.assign({}, this.options )
get improper (): Word {
const opts: WordOptions = Object.assign({}, this.opt)
opts.proper = false
return new Noun(this.singularNoun, this.pluralNoun, opts)
return this.configure( opts)
}
get specific (): Noun {
const opts: WordOptions = Object.assign({}, this.options )
get specific (): Word {
const opts: WordOptions = Object.assign({}, this.opt)
opts.kind = NounKind.Specific
return new Noun(this.singularNoun, this.pluralNoun, opts)
return this.configure( opts)
}
get nonspecific (): Noun {
const opts: WordOptions = Object.assign({}, this.options )
get nonspecific (): Word {
const opts: WordOptions = Object.assign({}, this.opt)
opts.kind = NounKind.Nonspecific
return new Noun(this.singularNoun, this.pluralNoun, opts)
return this.configure( opts)
}
get all (): Noun {
const opts: WordOptions = Object.assign({}, this.options )
get all (): Word {
const opts: WordOptions = Object.assign({}, this.opt)
opts.kind = NounKind.All
return new Noun(this.singularNoun, this.pluralNoun, opts)
return this.configure( opts)
}
get uncountable (): Noun {
const opts: WordOptions = Object.assign({}, this.options )
get uncountable (): Word {
const opts: WordOptions = Object.assign({}, this.opt)
opts.count = false
return new Noun(this.singularNoun, this.pluralNoun, opts)
return this.configure(opts)
}
}
export class RandomWord extends Word {
private last: number
constructor (public choices: Array<Word>, opt: WordOptions = emptyConfig) {
super(opt)
this.last = -1
}
configure (opts: WordOptions): Word {
return new RandomWord(this.choices, opts)
}
toString (): string {
let choice
do {
choice = Math.floor(Math.random() * this.choices.length)
} while (choice === this.last)
this.last = choice
return this.choices[choice].configure(this.opt).toString()
}
}
export class Noun extends Word {
constructor (private singularNoun: string, private pluralNoun: string|null = null, private options: WordOptions = emptyConfig) {
super(options)
}
get isPlural (): boolean {
return this.options.plural
configure (opts: WordOptions): Word {
return new Noun(this.singularNoun, this.pluralNoun, opts)
}
toString (): string {
@@ -208,6 +254,20 @@ export class ProperNoun extends Noun {
}
}
export class Adjective extends Word {
constructor (private adjective: string, opt: WordOptions = emptyConfig) {
super(opt)
}
configure (opts: WordOptions): Word {
return new Adjective(this.adjective, opts)
}
toString (): string {
return this.adjective
}
}
interface PronounDict {
subjective: string;
objective: string;