Documentation ¶
Index ¶
- Constants
- type FormType
- type Generator
- func (gen *Generator) Adjective(mods Mod) (string, error)
- func (gen *Generator) Adverb(mods Mod) (string, error)
- func (gen *Generator) All(wc WordClass) (iter.Seq2[int, *Word], error)
- func (gen *Generator) Find(word string, wc WordClass) (*Word, error)
- func (gen *Generator) Len(wc WordClass) (int, error)
- func (gen *Generator) Noun(mods Mod) (string, error)
- func (gen *Generator) Phrase(pattern string) (string, error)
- func (gen *Generator) Transform(word string, wc WordClass, mods Mod) (string, error)
- func (gen *Generator) TransformWord(word *Word, wc WordClass, mods Mod) (string, error)
- func (gen *Generator) Verb(mods Mod) (string, error)
- func (gen *Generator) Words(wc WordClass) (iter.Seq[*Word], error)
- type Mod
- type Word
- type WordClass
Examples ¶
- DefaultGenerator
- Generator.Adjective
- Generator.Adverb
- Generator.All
- Generator.Find
- Generator.Noun
- Generator.Phrase
- Generator.Transform
- Generator.TransformWord
- Generator.Verb
- Generator.Words
- Mod.Enabled
- Mod.Undefined
- NewGenerator
- NewGeneratorFromWord
- NewWord
- NewWordFromParams
- Word.Irr
- WordClass.CompatibleWith
Constants ¶
const DEFAULT_ITER_LIMIT int = 1000
Iteration limit used by the DefaultGenerator function. Exported as a reasonable default iterLimit value for the convenience of users who wish to work with a custom Generator.
Iteration limit is a safeguard for Generator.Adjective, Generator.Adverb and Generator.Noun methods. In presence of MOD_COMPARATIVE, MOD_SUPERLATIVE or MOD_PLURAL, those methods generate a word candidate until they find a comparable / countable one or until iteration limit is reached. If the chance of generating the right word is low, a high iterLimit may render application unresponsive.
iterLimit value should be set with regards to the size of your word base and the number of non-comparable adjectives, adverbs and uncountable nouns in it.
For example, to meet the default iterLimit of 1,000, the Generator would need to draw a non-comparable or uncountable word 1,000 times in a row. The embedded database contains approximately 10,000 adjectives, of which 2,700 are non-comparable, and 23,000 nouns, with 3,000 being uncountable. Given these numbers, it is unlikely that the iterLimit is reached.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type FormType ¶ added in v0.11.0
type FormType uint8
FormType (formation type). Indicates the effect that grammatical transformations have on a given word.
const ( // A regular word: // - adj, adv - forms comparative and superlative by adding // 'more' and 'most' before itself // - noun - can be both singular and plural // - verb - has regular past tense forms FT_REGULAR FormType = iota // An irregular word. It has its own special forms for: // - adj, adv - comparative, superlative // - noun - plural // - verb - Past Simple, Past Participle FT_IRREGULAR // A plural-only noun (e.g. scissors). It does not get picked // in absence of MOD_PLURAL. FT_PLURAL_ONLY // Adjective or adverb graded by appending '-er' and '-est' suffixes. FT_SUFFIXED // Non-comparable adjective or adverb. It does not get picked // if MOD_COMPARATIVE or MOD_SUPERLATIVE is requested. // An attempt to grade a non-comparable word results in an error. FT_NON_COMPARABLE // Uncountable noun. It does not get picked if MOD_PLURAL is requested. // An attempt to pluralize an uncountable noun results in an error. FT_UNCOUNTABLE )
type Generator ¶
type Generator struct {
// contains filtered or unexported fields
}
Generator creates and transforms random phrases or words.
func DefaultGenerator ¶ added in v0.5.0
DefaultGenerator returns a new Generator with default word lists.
It is safe to ignore the error value. The embedded word lists are guaranteed to work correctly and errors returned by the current version of the embed package (missing file, attempt to read a directory) cannot be triggered by neng. The error value remains exposed in case of future changes in the implementation of embed.
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { gen, _ := neng.DefaultGenerator() phrase, _ := gen.Phrase("The %tsa %tpn that %m %Npv the %n") fmt.Println(phrase) }
Output:
func NewGenerator ¶
NewGenerator initializes a Generator with the provided lists. Returns an error if any of the lists is empty or if any of their elements is incorrectly formatted.
Line structure:
<FormType><word>[,irr1][,irr2]
Base:
- FormType - a single digit
- Word - the word itself
If FormType == FT_IRREGULAR:
- Irregular form 1 - separated from the word by a comma
- Irregular form 2 - separated from the first irregular form by a comma
The word and irregular forms must be at least one character long. The line must be lower case. Every slice must be sorted A-Z by word.
The safe parameter allows users to bypass word list checks.
If safe is false:
- empty or nil slices do not trigger an error
- slices are not sorted
Regardless of safe value:
- malformed lines trigger an error
- letter case is not checked
iterLimit is an adjustable safety mechanism to prevent inifinite loops during certain transformations. For more information, refer to DEFAULT_ITER_LIMIT in the section 'Constants'.
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { gen, _ := neng.NewGenerator( []string{"3strong"}, // Adjectives []string{"4optically"}, // Adverbs []string{"0moon"}, // Nouns []string{"0exist"}, // Verbs 2, // iterLimit false, // No need for sorting and length checks in this case ) adj, _ := gen.Adjective(0) adv, _ := gen.Adverb(neng.MOD_CASE_TITLE) noun, _ := gen.Noun(neng.MOD_PLURAL) verb, _ := gen.Verb(neng.MOD_PAST_SIMPLE) // Without iterLimit, this call to Adverb would cause an infinite loop, // because the only adverb present in the database is non-comparable. _, err := gen.Adverb(neng.MOD_SUPERLATIVE) fmt.Printf("%s %s %s once %s.\n", adv, adj, noun, verb) fmt.Printf("Non-comparable: %v", err) }
Output: Optically strong moons once existed. Non-comparable: iteration limit reached while trying to draw a comparable or countable word
func NewGeneratorFromWord ¶ added in v0.11.0
func NewGeneratorFromWord(adj, adv, noun, verb []*Word, iterLimit int, safe bool) (*Generator, error)
NewGeneratorFromWord returns Generator created using the provided lists of Word structs and iterLimit. Returns an error if any of the lists is empty or contains a nil pointer. If safe is false, empty / nil checks are omitted. It is assumed that Word structs are created using one of the safe constructors, therefore their validity is not verified. Those constructors do not check word case though - all words should be lower case. Every slice must be sorted A-Z by Word.word field. If safe is true, the function ensures the correct order. iterLimit is an adjustable safety mechanism to prevent inifinite loops during certain transformations. For more information, refer to DEFAULT_ITER_LIMIT in the section 'Constants'.
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { a, _ := neng.NewWord("0inclined") m, _ := neng.NewWord("0slowly") n, _ := neng.NewWordFromParams("hometown", 0, nil) v, _ := neng.NewWordFromParams("make", 1, []string{"made", "made"}) adj := []*neng.Word{a} adv := []*neng.Word{m} noun := []*neng.Word{n} verb := []*neng.Word{v} gen, _ := neng.NewGeneratorFromWord(adj, adv, noun, verb, neng.DEFAULT_ITER_LIMIT, true) phrase, _ := gen.Phrase("%tm, the %a %n was %2v.") fmt.Println(phrase) }
Output: Slowly, the inclined hometown was made.
func (*Generator) Adjective ¶
Adjective generates a single random adjective and transforms it according to mods.
Returns an error if:
- an undefined Mod is received (relays from Generator.Transform)
- an incompatible Mod is received (relays from Generator.Transform)
- Generator.iterLimit is reached while attempting to generate a comparable adjective (relevant for generators with customized word lists)
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { gen, _ := neng.DefaultGenerator() adj, _ := gen.Adjective(neng.MOD_COMPARATIVE) fmt.Println(adj) }
Output:
func (*Generator) Adverb ¶ added in v0.7.0
Adverb generates a single random adverb and transforms it according to mods.
Returns an error if:
- an undefined Mod is received (relays from Generator.Transform)
- an incompatible Mod is received (relays from Generator.Transform)
- Generator.iterLimit is reached while attempting to generate a comparable adverb (relevant for generators with customized word lists)
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { gen, _ := neng.DefaultGenerator() adv, _ := gen.Adverb(neng.MOD_NONE) fmt.Println(adv) }
Output:
func (*Generator) All ¶ added in v0.13.0
All returns an iterator that yields index-*Word pairs from the Generator's word list corresponding to wc in alphabetical order.
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { gen, _ := neng.DefaultGenerator() adj, _ := gen.All(neng.WC_ADJECTIVE) for i, a := range adj { if i > 3 { break } fmt.Printf("%d: %s\n", i, a.Word()) } }
Output: 0: abandoned 1: abashed 2: abatable 3: abbatial
func (*Generator) Find ¶ added in v0.11.0
Find searches the word list for the specified word. Returns an error if word is not found or if WordClass is undefined.
Assumes the following about the 'word' argument:
- Word is lower case
- Adjectives and adverbs are in their positive forms
- Nouns are in their singular forms
- Verbs are in their base forms
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { gen, _ := neng.DefaultGenerator() // Combine Find with TransformWord to efficiently // perform multiple transformations on a single word verb, _ := gen.Find("go", neng.WC_VERB) base := verb.Word() ger, _ := gen.TransformWord(verb, neng.WC_VERB, neng.MOD_GERUND) pas, _ := gen.TransformWord(verb, neng.WC_VERB, neng.MOD_PAST_SIMPLE) pap, _ := gen.TransformWord(verb, neng.WC_VERB, neng.MOD_PAST_PARTICIPLE) prs, _ := gen.TransformWord(verb, neng.WC_VERB, neng.MOD_PRESENT_SIMPLE) fmt.Printf("%s:\ng: %s\n2: %s\n3: %s\nN: %s\n", base, ger, pas, pap, prs) }
Output: go: g: going 2: went 3: gone N: goes
func (*Generator) Len ¶ added in v0.13.0
Len returns the length of the Generator's word list corresponding to wc.
func (*Generator) Noun ¶
Noun generates a single random noun and transforms it according to mods.
Returns an error if:
- an undefined Mod is received (relays from Generator.Transform)
- an incompatible Mod is received (relays from Generator.Transform)
- Generator.iterLimit is reached while attempting to generate a countable noun for MOD_PLURAL, or a countable, not plural-only noun for MOD_INDEF (relevant for generators with customized word lists)
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { gen, _ := neng.DefaultGenerator() noun, _ := gen.Noun(neng.MOD_PLURAL) fmt.Println(noun) }
Output:
func (*Generator) Phrase ¶
Phrase generates a phrase given the pattern.
Syntax:
Insertion: %% - inserts '%' sign %a - inserts a random adjective %m - inserts a random adverb %n - inserts a random noun %v - inserts a random verb Transformation: %2 - transforms a verb into its Past Simple form (2nd form) %3 - transforms a verb into its Past Participle form (3rd form) %N - transforms a verb into its Present Simple form (now) %c - transforms an adjective or an adverb into comparative (better) %g - transforms a verb into gerund %i - inserts an indefinite article before an adjective, adverb or a noun %p - transforms a noun or a verb (Present Simple) into its plural form %s - transforms an adjective or an adverb into superlative (best) %l - transforms a word to lower case %t - transforms a word to Title Case %u - transforms a word to UPPER CASE
Error is returned if:
- provided pattern is empty
- character other than the above is escaped with a '%' sign
- a single '%' ends the pattern
- transformation specifier ends the group ("%t2 - bad, %t2v - ok")
- transformation modifier assigned to a word is not compatible with its WordClass
Example phrase:
"%tn %2v a %ua %un" may produce "Serenade perplexed a STRAY SUPERBUG"
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { gen, _ := neng.DefaultGenerator() phrase, _ := gen.Phrase("%tpn %Npv %n") fmt.Println(phrase) }
Output:
func (*Generator) Transform ¶ added in v0.2.0
Transform searches (Generator.Find) for the specified word and, if found, calls Generator.TransformWord to transform it.
Assumes the following about the 'word' argument:
- It is lower case
- Adjectives and adverbs are in their positive forms
- Nouns are in their singular forms
- Verbs are in their base forms
Returns an error if:
- word of the WordClass wc does not exist in the database
- undefined WordClass value is specified
Relays an error from Generator.TransformWord if:
- WordClass of the word is not compatible with any Mod in mods
- transformation into comparative or superlative form is requested for a non-comparable adjective or adverb
- transformation into plural form is requested for an uncountable noun
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { gen, _ := neng.DefaultGenerator() // Suitable for one-time modification. Inefficient when transforming the same word multiple times, // because it searches the database for the specified string every time. Refer to Generator.Find // for an example of bulk transformation. a, _ := gen.Transform("delightful", neng.WC_ADJECTIVE, neng.MOD_INDEF|neng.MOD_CASE_SENTENCE) n, _ := gen.Transform("muffin", neng.WC_NOUN, neng.MOD_INDEF_SILENT) fmt.Printf("%s %s\n", a, n) }
Output: A delightful muffin
func (*Generator) TransformWord ¶ added in v0.11.0
TransformWord modifies the Word according to specified mods. Not all mods are compatible with every WordClass.
Assumes the following about Word.word:
- It is lower case
- Adjectives and adverbs are in their positive forms
- Nouns are in their singular forms
- Verbs are in their base forms
Returns an error if:
- undefined WordClass value is specified
- mods parameter contains an undefined Mod value
- WordClass of the word is not compatible with any Mod value in mods
- transformation into comparative or superlative form is requested for a non-comparable adjective or adverb
- transformation into plural form is requested for an uncountable noun
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { gen, _ := neng.DefaultGenerator() w, _ := gen.Find("write", neng.WC_VERB) t, _ := gen.TransformWord(w, neng.WC_VERB, neng.MOD_PAST_PARTICIPLE) fmt.Printf("%s : %s\n", w.Word(), t) }
Output: write : written
func (*Generator) Verb ¶ added in v0.2.0
Verb generates a single random verb and transforms it according to mods. Returns an error if an undefined Mod is received.
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { gen, _ := neng.DefaultGenerator() verb, _ := gen.Verb(neng.MOD_PAST_SIMPLE) fmt.Println(verb) }
Output:
func (*Generator) Words ¶ added in v0.13.0
Words returns an iterator that yields words from the Generator's list corresponding to wc in alphabetical order.
Example ¶
package main import ( "fmt" "iter" "github.com/Zedran/neng" ) func main() { gen, _ := neng.DefaultGenerator() noun, _ := gen.Words(neng.WC_NOUN) next, stop := iter.Pull(noun) defer stop() if n, ok := next(); ok { fmt.Println(n.Word()) } }
Output: aa
type Mod ¶ added in v0.2.0
type Mod uint
Mod holds modification parameters for a generated word.
const ( // Transform a noun or a verb (Past Simple, Present Simple) // into its plural form. MOD_PLURAL Mod = 1 << iota // Transform a verb into its Past Simple form. MOD_PAST_SIMPLE // Transform a verb into its Past Participle form. MOD_PAST_PARTICIPLE // Add Present Simple suffix to a verb (-s, -es). MOD_PRESENT_SIMPLE // Create gerund form of a verb (-ing). MOD_GERUND // Transform an adjective or an adverb into comparative (good -> better). MOD_COMPARATIVE // Transform an adjective or an adverb into superlative (good -> best). MOD_SUPERLATIVE // Insert an indefinite article before an adjective, adverb or a noun. MOD_INDEF // Pick a noun that is compatible with MOD_INDEF (not uncountable, // not plural-only). Helpful when the user wants to add the indefinite // article before an adjective describing a noun. MOD_INDEF_SILENT // Transform a word to lower case. MOD_CASE_LOWER // In a group of words, transform the first one to title case // and everything that follows to lower case. If there is only // one word (no spaces), MOD_CASE_TITLE is applied. MOD_CASE_SENTENCE // Transform a word to Title Case. MOD_CASE_TITLE // Transform a word to UPPER CASE. MOD_CASE_UPPER )
const MOD_NONE Mod = 0
Do not transform the word in any way.
func (Mod) Enabled ¶ added in v0.12.0
Enabled returns true if any of the specified mods are enabled in m. Do not use this method to test for MOD_NONE. Use a simple comparison instead.
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { mods := neng.MOD_GERUND | neng.MOD_CASE_UPPER fmt.Println(mods.Enabled(neng.MOD_GERUND)) fmt.Println(mods.Enabled(neng.MOD_PLURAL)) // Returns true if any Mod value is enabled fmt.Println(mods.Enabled(neng.MOD_GERUND | neng.MOD_PAST_PARTICIPLE)) fmt.Println(mods.Enabled(neng.MOD_COMPARATIVE | neng.MOD_PLURAL)) // If you need to test for MOD_NONE, use comparison instead of Mod.Enabled fmt.Println(mods == neng.MOD_NONE) }
Output: true false true false false
func (Mod) Undefined ¶ added in v0.12.0
Undefined returns true if m holds an undefined Mod value.
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { def := neng.MOD_GERUND ndef := neng.Mod(65536) fmt.Println(def.Undefined()) fmt.Println(ndef.Undefined()) }
Output: false true
type Word ¶ added in v0.11.0
type Word struct {
// contains filtered or unexported fields
}
Word represents a single word list entry.
func NewWord ¶ added in v0.11.0
NewWord parses a single word list line into a new word struct. Returns an error if malformed line is encountered.
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { w, _ := neng.NewWord("1write,wrote,written") fmt.Println(w.Word()) }
Output: write
func NewWordFromParams ¶ added in v0.11.0
NewWordFromParams returns a Word struct built from the specified parameters, or error, if the following conditions are not met:
- word must be at least 1 character long
- ft must be in range of the defined FormType values
- for irregular words, the length of irr must be 1 or 2 and the elements cannot be empty strings
- for non-irregular words, irr must be empty
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { // Regular verb rv, _ := neng.NewWordFromParams("create", neng.FT_REGULAR, nil) // Irregular verb iv, _ := neng.NewWordFromParams("think", neng.FT_IRREGULAR, []string{"thought", "thought"}) // Plural-only noun pn, _ := neng.NewWordFromParams("odds", neng.FT_PLURAL_ONLY, nil) // Adjective that forms comparative and superlative by adding '-er' and '-est' sa, _ := neng.NewWordFromParams("strong", neng.FT_SUFFIXED, nil) // Non-comparable adjective na, _ := neng.NewWordFromParams("tenth", neng.FT_NON_COMPARABLE, nil) // Uncountable noun un, _ := neng.NewWordFromParams("magnesium", neng.FT_UNCOUNTABLE, nil) for _, w := range []*neng.Word{rv, iv, pn, sa, na, un} { fmt.Println(w.Word()) } }
Output: create think odds strong tenth magnesium
func (*Word) Irr ¶ added in v0.15.2
Returns an irregular form of the Word at index i of the underlying slice of irregular forms. Returns an error if called for a non-irregular word or if i is out of bounds of the slice.
Example ¶
package main import ( "errors" "fmt" "log" "github.com/Zedran/neng" "github.com/Zedran/neng/symbols" ) func main() { word, _ := neng.NewWord("1good,better,best") irr1, _ := word.Irr(0) irr2, err := word.Irr(1) if err != nil { if errors.Is(err, symbols.ErrNonIrregular) { log.Fatal("Non-irregular word") } log.Fatal("Out of bounds") } fmt.Printf("%s, %s, %s\n", word.Word(), irr1, irr2) }
Output:
type WordClass ¶ added in v0.10.0
type WordClass uint8
WordClass helps the Generator to differentiate parts of speech.
func (WordClass) CompatibleWith ¶ added in v0.10.0
CompatibleWith returns true if WordClass is compatible with all of the received mods. This method tests defined Mod values only - undefined Mod values have undefined compatibility. Use Mod.Undefined to ensure that all bits in Mod have defined values.
Example ¶
package main import ( "fmt" "github.com/Zedran/neng" ) func main() { wc := neng.WC_VERB fmt.Println(wc.CompatibleWith(neng.MOD_PLURAL | neng.MOD_PRESENT_SIMPLE)) fmt.Println(wc.CompatibleWith(neng.MOD_PLURAL)) }
Output: true false
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
examples
|
|
internal
|
|
scripts/audit
Script audit creates a standardized snapshot of all transformed words, which can be used to evaluate transformation quality and analyze the impact of new features and modifications.
|
Script audit creates a standardized snapshot of all transformed words, which can be used to evaluate transformation quality and analyze the impact of new features and modifications. |
scripts/common
Package common contains functions shared by scripts.
|
Package common contains functions shared by scripts. |
scripts/embed
Script embed builds the embedded files from resource files created with github.com/Zedran/neng/internal/scripts/res.
|
Script embed builds the embedded files from resource files created with github.com/Zedran/neng/internal/scripts/res. |
scripts/res
Script res builds the resource files from WordNet database.
|
Script res builds the resource files from WordNet database. |
tests
Package tests contains common functions used by test
|
Package tests contains common functions used by test |
Package symbols provides an access to additional symbols which are not vital when working with neng, but can be useful in certain situations.
|
Package symbols provides an access to additional symbols which are not vital when working with neng, but can be useful in certain situations. |