Inital commit
This commit is contained in:
186
parser/parser.go
Normal file
186
parser/parser.go
Normal file
@@ -0,0 +1,186 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"autobrew/action"
|
||||
"autobrew/ingredient"
|
||||
"autobrew/recipe"
|
||||
"autobrew/utils"
|
||||
"bufio"
|
||||
"io/fs"
|
||||
"log"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var add_to_cauldron = regexp.MustCompile(`(?mi)^Add (\d+ .+)+? to the cauldron\.$`)
|
||||
var add_to_mortar = regexp.MustCompile(`(?mi)^Add (\d+ .+)+? to the mortar, grind, and pour into the cauldron\.$`)
|
||||
var boil = regexp.MustCompile(`(?mi)^Boil for (\d+) turn[s]*\.$`)
|
||||
var boil_bellows = regexp.MustCompile(`(?mi)^Boil for (\d+) turn[s]* using bellows\.$`)
|
||||
var extract_amount = regexp.MustCompile(`(?mi)^(\d+) (.*)$`)
|
||||
|
||||
func transformStep(lines []string) (name string, steps []recipe.Step, err error) {
|
||||
|
||||
name, lines = lines[0], lines[1:]
|
||||
|
||||
var ingredients []ingredient.Ingredient
|
||||
|
||||
for index, line := range lines {
|
||||
if strings.HasPrefix(line, "Liquid Base:") {
|
||||
i, err := ingredient.IngredientFromString(strings.TrimSpace(strings.Split(line, ": ")[1]))
|
||||
utils.Check(err)
|
||||
|
||||
ingredients = append(ingredients, i)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(line, "Ingredients:") {
|
||||
parts := strings.TrimSpace(strings.Split(line, ":")[1])
|
||||
for _, i := range strings.Split(parts, ",") {
|
||||
|
||||
a := strings.Split(strings.TrimSpace(i), " x")
|
||||
i, err := ingredient.IngredientFromString(strings.TrimSpace(a[0]))
|
||||
utils.Check(err)
|
||||
|
||||
amount, err := strconv.Atoi(a[1])
|
||||
utils.Check(err)
|
||||
|
||||
for range amount {
|
||||
ingredients = append(ingredients, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(line, "Recipe") {
|
||||
lines = lines[index+1:]
|
||||
}
|
||||
}
|
||||
|
||||
steps = append(steps, recipe.Step{
|
||||
Action: action.Prepare,
|
||||
Ingredients: ingredients,
|
||||
})
|
||||
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if match := add_to_cauldron.FindStringSubmatch(line); match != nil {
|
||||
parts := strings.Split(match[1], " and ")
|
||||
var ingredients []ingredient.Ingredient
|
||||
for _, part := range parts {
|
||||
if match := extract_amount.FindStringSubmatch(part); match != nil {
|
||||
i, err := strconv.Atoi(match[1])
|
||||
utils.Check(err)
|
||||
|
||||
for range i {
|
||||
i, err := ingredient.IngredientFromString(strings.TrimSpace(match[2]))
|
||||
utils.Check(err)
|
||||
|
||||
ingredients = append(ingredients, i)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
steps = append(steps, recipe.Step{
|
||||
Action: action.AddToCauldron,
|
||||
Ingredients: ingredients,
|
||||
})
|
||||
}
|
||||
|
||||
if match := add_to_mortar.FindStringSubmatch(line); match != nil {
|
||||
parts := strings.Split(match[1], " and ")
|
||||
var ingredients []ingredient.Ingredient
|
||||
for _, part := range parts {
|
||||
if match := extract_amount.FindStringSubmatch(part); match != nil {
|
||||
i, err := strconv.Atoi(match[1])
|
||||
utils.Check(err)
|
||||
|
||||
for range i {
|
||||
i, err := ingredient.IngredientFromString(strings.TrimSpace(match[2]))
|
||||
utils.Check(err)
|
||||
|
||||
ingredients = append(ingredients, i)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
steps = append(steps, recipe.Step{
|
||||
Action: action.GrindIngredients,
|
||||
Ingredients: ingredients,
|
||||
})
|
||||
}
|
||||
|
||||
if match := boil.FindStringSubmatch(line); match != nil {
|
||||
i, err := strconv.Atoi(match[1])
|
||||
utils.Check(err)
|
||||
steps = append(steps, recipe.Step{
|
||||
Action: action.Boil,
|
||||
Turns: i,
|
||||
})
|
||||
}
|
||||
|
||||
if match := boil_bellows.FindStringSubmatch(line); match != nil {
|
||||
i, err := strconv.Atoi(match[1])
|
||||
utils.Check(err)
|
||||
steps = append(steps, recipe.Step{
|
||||
Action: action.BoilBellows,
|
||||
Turns: i,
|
||||
})
|
||||
}
|
||||
|
||||
if strings.HasPrefix(line, "Pour into phial.") {
|
||||
steps = append(steps, recipe.Step{
|
||||
Action: action.PourPhial,
|
||||
})
|
||||
}
|
||||
|
||||
if strings.HasPrefix(line, "Prepare phial and distill.") {
|
||||
steps = append(steps, recipe.Step{
|
||||
Action: action.Distill,
|
||||
})
|
||||
}
|
||||
|
||||
if strings.HasPrefix(line, "Pour into a mortar and grind.") {
|
||||
steps = append(steps, recipe.Step{
|
||||
Action: action.GrindPotion,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func FromText(file fs.File) map[string][]recipe.Step {
|
||||
scanner := bufio.NewScanner(file)
|
||||
// optionally, resize scanner's capacity for lines over 64K, see next example
|
||||
recipes := make(map[string][]recipe.Step, 0)
|
||||
lines := make([]string, 0)
|
||||
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if line == "--" {
|
||||
name, recipe, err := transformStep(lines)
|
||||
utils.Check(err)
|
||||
recipes[name] = recipe
|
||||
lines = make([]string, 0)
|
||||
continue
|
||||
}
|
||||
|
||||
lines = append(lines, line)
|
||||
|
||||
}
|
||||
|
||||
if len(lines) > 0 {
|
||||
name, recipe, err := transformStep(lines)
|
||||
utils.Check(err)
|
||||
recipes[name] = recipe
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return recipes
|
||||
}
|
||||
Reference in New Issue
Block a user