- Library code lives in
src/; DSL primitives are undersrc/css/with enums insrc/css/enums/, shared macros insrc/macros.cr, and the public entrypoint insrc/css.cr. - Specs are in
spec/, mirroring the feature areas (selector_spec.cr,media_spec.cr, etc.) and bootstrapped viaspec/spec_helper.cr. - Utility scripts sit in
scripts/;scripts/generate_props.cris a helper to print property declarations from MDN data.
- Install deps:
shards install. - Run the suite:
crystal spec(usecrystal spec spec/selector_spec.crto focus).- If you run into permission issues, create a temporary local cache directory - but make sure to delete it again afterwards.
- Format code:
crystal tool formatbefore opening a PR. - Optional:
crystal docsto build API docs locally.
- Crystal defaults: 2-space indentation, trailing commas avoided, and
requirepaths are relative tosrc/. - Types, modules, and DSL classes use
CamelCase; methods, variables, and files usesnake_case(mirrors existing files likemedia_query_evaluator.cr). - Prefer expressive DSL method names that match CSS terms; keep rule blocks small and composable.
- Be aware that the Crystal compiler automatically converts symbol literals to matching enum values in method arguments.
- Keep public API additions documented in comments only when behavior is non-obvious; otherwise rely on self-descriptive method names.
- Use the built-in
specframework; each feature gets a*_spec.crinspec/. - Name examples to describe rendered CSS output (see
nested_rule_spec.cr); include both structure and value assertions. - When adding syntax or properties, extend or add focused specs rather than modifying many files at once.
- Aim to cover both rendering and nesting/combination behaviors for new selectors or declarations.
- The repo uses only Crystal stdlib; avoid adding new networked dependencies without discussion.
- If you must refresh property data, run
crystal scripts/generate_props.crin a sandboxed environment and commit only the resulting code changes, not downloaded data.