···1111 // The name of the recipe
1212 Name() string
1313 // The format this recipe is in
1414- Format() Format
1414+ Format() *Format
1515 // Returns the stored filename (with extension), or an appropriate generated one
1616 Filename() string
1717 // Destructively applies all standardizations to this recipe, returning
···3131 // The name of the recipe collection
3232 Name() string
3333 // The format this recipe collection is in
3434- Format() Format
3434+ Format() *Format
3535 // Returns the stored filename (with extension), or an appropriate generated one
3636 Filename() string
3737 // Adds the provided recipe to this collection
···11+{
22+ "description": "A list of the recipes being converted.",
33+ "type": "array",
44+ "items": {
55+ "type": "object",
66+ "properties": {
77+ "title": {
88+ "type": "string",
99+ "description": "Title of the recipe"
1010+ },
1111+ "description": {
1212+ "type": "string",
1313+ "description": "A short description of the recipe which is displayed after the title. May include links to other recipes in markdown format."
1414+ },
1515+ "photos": {
1616+ "type": "array",
1717+ "items": {
1818+ "type": "string"
1919+ },
2020+ "description": "List of the paths to photos associated with this recipe"
2121+ },
2222+ "yield": {
2323+ "type": "string",
2424+ "description": "The recipe's yield or servings including the unit if known"
2525+ },
2626+ "prepTime": {
2727+ "type": "string",
2828+ "description": "How long it takes to prepare this recipe, eg. 3h30m"
2929+ },
3030+ "cookTime": {
3131+ "type": "string",
3232+ "description": "How long it takes to cook this recipe, eg. 1h15m"
3333+ },
3434+ "totalTime": {
3535+ "type": "string",
3636+ "description": "Total time it takes to prepare and cook the dish. This does not have to be the sum of prepTime and cookTime (but mostly is). eg. 4h45m"
3737+ },
3838+ "ingredients": {
3939+ "type": "array",
4040+ "items": {
4141+ "type": "object",
4242+ "properties": {
4343+ "groupName": {
4444+ "type": "string",
4545+ "description": "The name of the part of the recipe this group of ingredients makes. Empty if there's only one group"
4646+ },
4747+ "ingredients": {
4848+ "type": "array",
4949+ "items": {
5050+ "type": "string"
5151+ },
5252+ "description": "A list of ingredients, each one's quantity, unit and name"
5353+ }
5454+ }
5555+ },
5656+ "description": "The ingredients for the recipes, broken down into groups if needed"
5757+ },
5858+ "instructions": {
5959+ "type": "array",
6060+ "items": {
6161+ "type": "object",
6262+ "properties": {
6363+ "groupName": {
6464+ "type": "string",
6565+ "description": "The name of the part of the recipe this set of instructions is for. Empty if there's only one group"
6666+ },
6767+ "steps": {
6868+ "type": "array",
6969+ "items": {
7070+ "type": "string",
7171+ "description": "A single instruction step for making the recipe, without preceding bullet point or number."
7272+ }
7373+ }
7474+ }
7575+ },
7676+ "description": "The instructions for making the recipe"
7777+ },
7878+ "notes": {
7979+ "type": "string",
8080+ "description": "Any additional notes about the recipe that aren't a part of the description"
8181+ }
8282+ },
8383+ "required": [
8484+ "title",
8585+ "description",
8686+ "yield",
8787+ "ingredients",
8888+ "instructions"
8989+ ],
9090+ "additionalProperties": false
9191+ }
9292+}
···11package formats
2233-import (
44- "time"
55-)
33+import "github.com/jphastings/recipes/internal/llm"
6475// Details about a recipe format
86type Format struct {
···1715 // The file extension for the collection format (with period)
1816 ExtensionCollection string
1917 // Turns one interchange recipe format into this format
2020- New func(InterchangeRecipe) (Recipe, error)
1818+ New func(Recipe) (Recipe, error)
2119 // Turns one or more interchange recipes into this collection format
2220 // Will be nil if this is not a collection format
2323- NewCollection func(string, []InterchangeRecipe) (RecipeCollection, error)
2121+ NewCollection func(name string, recipes []Recipe) (RecipeCollection, error)
2422 // Parses a filesystem object into either a single Recipe *or* a single RecipeCollection.
2525- // A response of nil, nil, nil means the file is definitively not of this format.
2626- Parse func(Bundle) (Recipe, RecipeCollection, error)
2323+ Parse func(Bundle, ParseOptions) (Recipe, RecipeCollection, error)
2724 // Bundle must extract sets of recipe files for this format that *must* be processed together.
2825 // Eg. cooklang stores images adjacent to the recipe file:
2926 // lasagne.cook, lasagne.jpg, shakshouka.cook, random.jpg, ignored.crumb
···5148 return out
5249}
53505454-// A generic and internal structure for recipes that is used for conversion
5555-// ⚠️ This struct is highly likely to change subtly with each new recipe format added to this library.
5656-type InterchangeRecipe struct {
5757- Filename string
5858- ID string
5959- Title string
6060- Description string
6161-6262- PrepTime time.Duration
6363- CookTime time.Duration
6464- TotalTime time.Duration
5151+type ParseOptions struct {
5252+ LLM *llm.Connection
6553}