Cooklang

A raku variant of Cooklang

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

  • Ingredients @salt, @ground black pepper{}, @potato{2}, @flour{200%g}, with an optional note @salt{1%tsp;fine}

  • Cookware #pot, #frying pan{}, #pan{2} (cookware has no units)

  • Timers ~{25%minutes}, ~eggs{3%minutes}

  • Quantities as numbers 2, fractions 1/2, mixed numbers 1 1/2, ranges 1-2 or text a pinch

  • Steps: paragraphs separated by a blank line; a single line break is a space, unless the line ends with \

  • Comments -- to end of line and [- block -]

  • Metadata as YAML front matter between --- lines, and >> key: value lines; keys are case-insensitive and the last value wins (spec proposal 0007)

  • Optional ingredients and cookware @?thyme, #?splatter guard{} (spec proposal 0018)

  • Scaling with factor or servings; fixed quantities @salt{=1%tsp}, cookware and timers are not scaled (spec proposal 0010)

  • Notes: a paragraph starting with > (spec proposal 0005)

  • Sections = Dough, == Filling == (spec proposal 0006)

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 - [email protected]

COPYRIGHT

Erik Johansen 2023-2026

LICENSE

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

Cooklang v2.2.0

A raku variant of Cooklang

Authors

    License

    Artistic-1.0-Perl OR GPL-1.0-or-later

    Dependencies

    AttrX::MooishYAMLish

    Test Dependencies

    Provides

    • Cooklang

    The Camelia image is copyright 2009 by Larry Wall. "Raku" is a trademark of the Yet Another Society. All rights reserved.

    Built with Podlite — the markup and publishing tools behind this site.