Rand Stats

Cooklang

zef:uniejo

NAME

Cooklang - Raku Cooklang parser

SYNOPSIS

    use Cooklang;

    # Parse a recipe from text, a file, or a list of files (joined before parsing)
    my $recipe = Cooklang.new( recipe => "Mix @flour{200%g} and @water{1/2%l}.\n" );
    my $recipe = Cooklang.new( recipe_file => 'recipe.cook' );
    my $recipe = Cooklang.new( recipe_file => <recipe1.cook recipe2.cook> );

    # Recipe parts
    my %metadata    = $recipe.metadata;      # Front matter (YAML) and '>> key: value' lines; keys are case-insensitive
    my @ingredients = $recipe.ingredients;   # Cooklang::Ingredient objects
    my @cookware    = $recipe.cookware;      # Cooklang::Cookware objects
    my @comments    = $recipe.comments;      # Cooklang::Comment objects
    my @steps       = $recipe.steps;         # Steps (paragraphs) as lists of hashes
    my @flat        = $recipe.steps_flat;    # All steps as one list of hashes
    my @sections    = $recipe.sections;      # Steps grouped by section: { name => ..., steps => [...] }
    my @notes       = $recipe.notes;         # Cooklang::Note objects
    my %data        = $recipe.data;          # { metadata => ..., steps => ... } as in the spec tests
    my $ast_tree    = $recipe.match;         # The grammar match

    # Ingredient details
    for $recipe.ingredients {
        say .name, ' ', .quantity, ' ', .units;
        say .human;                          # "200 g flour"
        say 'optional' if .optional;         # @?name
        say 'not scaled' if .fixed;          # @name{=1%tsp}
    }

    # Scale the recipe
    $recipe.factor   = 2;                    # Double all scalable quantities
    $recipe.servings = 4;                    # Scale to 4 servings (relative to the 'servings' or 'serves' metadata)

    # Output
    say $recipe.human;                       # Readable text
    say $recipe.cook;                        # The original Cooklang text

    # A recipe that can not be parsed throws Cooklang::ParseError
    CATCH { when Cooklang::ParseError { note .message } }

VERSION

version 2.2.0

DESCRIPTION

Cooklang is a markup language for recipes, see Cooklang and the specification.

This module parses a Cooklang recipe with a Raku grammar and grammar actions, and gives access to its metadata, ingredients, cookware, timers, comments and steps. The specification tests (t/spec, a git submodule of the specification) are part of the test suite.

SUPPORTED SYNTAX

Not supported yet: short-hand preparations (@onion{1}(chopped)) and references to other recipes (@./sauces/pesto{}). They are parsed as plain text or as an ordinary ingredient.

DOCUMENTATION

Cooklang documentation is available as POD6. You can run raku --doc from a shell to read the documentation:

    % raku --doc lib/Cooklang.rakumod
    % raku --doc=Markdown lib/Cooklang.rakumod     # zef install Pod::To::Markdown
    % raku --doc=HTML lib/Cooklang.rakumod         # zef install Pod::To::HTML

INSTALLATION

Installing Cooklang is straightforward.

Installation with zef from CPAN6

If you have zef, you only need one line:

    % zef install Cooklang

Installation with zef from git repository

    % zef install https://github.com/uniejo/cooklang-raku.git

Running the tests

The specification tests are in a git submodule:

    % git submodule update --init
    % prove -e 'raku -Ilib' t

COMMUNITY

SEE ALSO

AUTHOR

Erik Johansen - uniejo@users.noreply.github.com

COPYRIGHT

Erik Johansen 2023-2026

LICENSE

This software is licensed under the same terms as Perl itself.