Implement RNG format blocks in sentences
The RNG blocks follow a slightly different format than the word blocks. They are wrapped in square brackets instead of curly braces. The format is as follows: [cmd:arguments] `cmd` can be one of either "rng" or "hide". "rng" takes a comma separated list as its arguments and will choose one option from the list. Only raw words are accepted here (word blocks are not parsed). "hide" will randomly hide its arguments in the output string. The arguments for this command *are* parsed, so {word} and {{new_word}} blocks can be used.
This commit is contained in:
parent
92e3a5aeb0
commit
71a0c01db9
85
english.go
85
english.go
|
@ -30,22 +30,31 @@ func NewEnglish(db database.DB) (HackerQuotes, error) {
|
|||
}
|
||||
|
||||
/*
|
||||
|
||||
Sentence format
|
||||
|
||||
bare words
|
||||
{word_type:options}
|
||||
{{word_type:new word:properties}}
|
||||
|
||||
[rng:random,choice,list] // one word is chosen from the comma-separated list
|
||||
|
||||
// Randomly hide/show the enclosed definition
|
||||
[hide:{word_type:options}]
|
||||
[hide:{{word_type:new word:options}}]
|
||||
|
||||
{pronoun} can't {verb:i,present} {noun_phrase}, it {verb:it,future} {noun_phrase}!
|
||||
{verb:you,present} {noun_phrase:indefinite}, then you can {verb:you,present} {noun_phrase:definite}!
|
||||
{noun_phrase} {verb}. With {noun_phrase:indifinite,noadj,compound}!
|
||||
|
||||
{pronoun} {{verb:need:from_pronoun,present}} to {verb:i,present} {noun_phrase:definite}!
|
||||
|
||||
{pronoun} [rng:can,may] {verb:i,present} {noun_phrase} [hide:{noun_phrase:singlular}], it {verb:it,future} {noun_phrase:definite}.
|
||||
*/
|
||||
|
||||
func (g *english) Hack() (string, error) {
|
||||
//var fmtString string = `{verb:you,present} {noun_phrase:definite} then you can {verb:you,present} {noun_phrase:definite}!`
|
||||
//var str string = `{pronoun} {{verb:need:from_pronoun,present}} to {verb:i,present} {noun_phrase:definite}!`
|
||||
//var str string = `{pronoun} [rng:can,may] {verb:i,present} {noun_phrase}[hide: {noun_phrase:singlular}], it {verb:it,future} {noun_phrase:definite}.`
|
||||
str, err := g.randomSentence()
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -63,21 +72,20 @@ func (g *english) HackThis(fmtString string) (string, error) {
|
|||
|
||||
for idx < len(fmtString) {
|
||||
if fmtString[idx] == '{' {
|
||||
if fmtString[idx+1] == '{' {
|
||||
nidx, err = g.consumeNewWord(fmtString, idx, output)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
idx = nidx
|
||||
continue
|
||||
}
|
||||
|
||||
nidx, err = g.consumeWord(fmtString, idx, output)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
idx = nidx
|
||||
continue
|
||||
|
||||
} else if fmtString[idx] == '[' {
|
||||
nidx, err = g.consumeRng(fmtString, idx, output)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
idx = nidx
|
||||
continue
|
||||
}
|
||||
|
||||
nidx, err = g.consumeRaw(fmtString, idx, output)
|
||||
|
@ -90,8 +98,57 @@ func (g *english) HackThis(fmtString string) (string, error) {
|
|||
return toCap(output.String()), nil
|
||||
}
|
||||
|
||||
func (g *english) consumeRng(fmtString string, idx int, output *strings.Builder) (int, error) {
|
||||
idx++
|
||||
def := strings.Index(fmtString[idx:], ":")
|
||||
if def == -1 {
|
||||
return 0, fmt.Errorf("Missing command separator in RNG block")
|
||||
}
|
||||
def += idx
|
||||
|
||||
end := strings.Index(fmtString[idx:], "]")
|
||||
if end == -1 {
|
||||
return 0, fmt.Errorf("Unclosed RNG block starting at offset %d", idx-1)
|
||||
}
|
||||
end += idx
|
||||
|
||||
if def > end {
|
||||
return 0, fmt.Errorf("Missing command separator in RNG block")
|
||||
}
|
||||
|
||||
switch fmtString[idx:def] {
|
||||
case "rng":
|
||||
choices := strings.Split(fmtString[def+1:end], ",")
|
||||
ridx := rand.Intn(len(choices))
|
||||
output.WriteString(choices[ridx])
|
||||
|
||||
case "hide":
|
||||
if rand.Int() % 2 == 0 {
|
||||
return end+1, nil
|
||||
}
|
||||
|
||||
var newEnd int = def+1
|
||||
var err error
|
||||
for newEnd < end {
|
||||
if fmtString[newEnd] == '{' {
|
||||
newEnd, err = g.consumeWord(fmtString, newEnd, output)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
} else {
|
||||
newEnd, err = g.consumeRaw(fmtString, newEnd, output)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return 0, fmt.Errorf("RNG type %q is not implemented", fmtString[idx:def])
|
||||
}
|
||||
|
||||
return end+1, nil
|
||||
}
|
||||
|
||||
func (g *english) consumeRaw(fmtString string, idx int, output *strings.Builder) (int, error) {
|
||||
end := strings.Index(fmtString[idx:], "{")
|
||||
end := strings.IndexAny(fmtString[idx:], "{[")
|
||||
if end == -1 {
|
||||
output.WriteString(fmtString[idx:len(fmtString)])
|
||||
return len(fmtString), nil
|
||||
|
@ -243,6 +300,10 @@ func (g *english) consumeNewWord(fmtString string, idx int, output *strings.Buil
|
|||
}
|
||||
|
||||
func (g *english) consumeWord(fmtString string, idx int, output *strings.Builder) (int, error) {
|
||||
if fmtString[idx+1] == '{' {
|
||||
return g.consumeNewWord(fmtString, idx, output)
|
||||
}
|
||||
|
||||
idx++
|
||||
var wordtype string
|
||||
var options string
|
||||
|
@ -275,7 +336,7 @@ func (g *english) consumeWord(fmtString string, idx int, output *strings.Builder
|
|||
var plural bool = rand.Int() % 2 == 0
|
||||
if sliceContains(opts, "plural") {
|
||||
plural = true
|
||||
} else if sliceContains(opts, "singular")
|
||||
} else if sliceContains(opts, "singular") {
|
||||
plural = false
|
||||
}
|
||||
|
||||
|
|
|
@ -419,6 +419,7 @@
|
|||
"{pronoun} can't {verb:i,present} {noun_phrase}, it {verb:it,future} {noun_phrase}!",
|
||||
"{verb:you,present} {noun_phrase:definite}, then you can {verb:you,present} {noun_phrase:definite}!",
|
||||
"{noun_phrase:it,past} {verb}. With {noun_phrase:indifinite,noadj,compound}!",
|
||||
"{pronoun} {{verb:need:from_pronoun,present}} to {verb:i,present} {noun_phrase:definite}!"
|
||||
"{pronoun} {{verb:need:from_pronoun,present}} to {verb:i,present} {noun_phrase:definite}!",
|
||||
"{pronoun} [rng:can,may] {verb:i,present} {noun_phrase} [hide:{noun_phrase:singlular}], it {verb:it,future} {noun_phrase:definite}."
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue