Rand Stats

CSS::Module

zef:dwarring

[Raku CSS Project] / [CSS-Module]

CSS::Module

# Parse a sample stylesheet as CSS 2.1. Dump the AST.
use v6;
use CSS::Module::CSS21;
my $css = 'h1 { color: orange; text-align: center }';
my $module = CSS::Module::CSS21.module;
my $actions = $module.actions.new;
$module.grammar.parse( $css, :$actions);
say $/.ast.raku;

CSS::Module is a set of Raku classes for parsing and manipulation of CSS Levels 1, 2.1 and 3, and SVG.

It contains modules CSS::Module::CSS1, CSS::Module::CSS21 and CSS::Module::CSS3 for CSS levels 1.0, 2.1 and 3.0, along with CSS::Module::SVG, which is a CSS3 extension for styling SVG.

Each of these classes has a module method which produces an object that encapsulates grammars, actions and property metadata. It has aproperty-metadata method that can be used to introspect properties. For example

% raku -M CSS::Module::CSS3 -e'say CSS::Module::CSS3.module.property-metadata<azimuth>.raku'
{:default("center"), :inherit, :synopsis("<angle> | [[ left-side | far-left | left | center-left | center | center-right | right | far-right | right-side ] || behind ] | leftwards | rightwards")}

Note: CSS::Module::CSS3.module is composed from the following grammars.

This corresponds to the sub-modules described in CSS Snapshot 2010.

Installation

You can use the Raku zef module installer to test and install CSS::Module:

% zef install CSS::Module

Examples

use v6;
use CSS::Module::CSS21;

my $css = 'H1 { color: blue; foo: bar; background-color: zzz }';
my $module  = CSS::Module::CSS21.module;
my $grammar = $module.grammar;
my $actions = $module.actions.new;
my $p = $grammar.parse($css, :$actions);
note $_ for $actions.warnings;
say "declaration: " ~ $p.ast[0]<ruleset><declarations>.raku;
# output:
# unknown property: foo - declaration dropped
# usage background-color: <color> | transparent | inherit
# declaration: {"color" => {"expr" => [{"rgb" => [{"num" => 0}, {"num" => 0}, {"num" => 255}]}]}
    use v6;
    use CSS::Module::CSS21;
    my $ast = CSS::Module::CSS21.module.parse-property('azimuth', 'center-left behind');

Property Definitions

Property definitions are built from the sources in the src directory using the CSS::Specification tools. These implement the W3C Property Definition Syntax.

Generated modules are written under the gen/lib directory.

For example CSS::Module:CSS1::Spec::Grammar, CSS::Module:CSS1::Spec::Actions and CSS::Module:CSS1::Spec::Interface are generated from etc/css1-properties.txt.

See make-modules.pl.

Actions Options

    my $module  = CSS::Module::CSS21.module;
    my $grammar = $module.grammar;
    my $actions = $module.actions.new( :lax );

    say $grammar.parse('{bad-prop: 12mm}', :$actions, :rule<declarations>).ast.raku;
    # output {"property:unknown" => {:expr[{ :mm(12) }], :ident<bad-prop>}}

    say $grammar.parse('{ @guff {color:red} }', :$actions, :rule<declarations>).ast.raku;
    # output: {"margin-rule:unknown" =>  { :declarations[ { :ident<color>,
                                                          :expr[ { :rgb[ { :num(255) }, { :num(0) }, { :num(0) } ] } ] } ],
                                         :at-keyw<guff> } }

lax mode likewise returns quantities with unknown dimensions:

    say $grammar.parse('{margin: 12mm .1furlongs}', :$actions, :rule<declarations>).ast.raku;
    # output {"property" => {:expr[{ :mm(12) }, { :num(0.12), "units:unknown" => <furlongs>}], :ident<margin>}}

Custom Properties

Properties may be added, or overriden via an :%extensions option to the new() method.

subset MyAlignment of Str where 'left'|'middle'|'right';
sub coerce(MyAlignment:D $keyw --> Pair) { :$keyw }

my %extensions =  %(
    '-my-align' => %(:synopsis("left | middle | right"), :default<middle>, :&coerce),
    '-my-misc' => %(), # can hold any value
);

my $module = CSS::Module::CSS3.module: :%extensions;
say $module.property-metadata<-my-align>.raku;

See Also

References