package cascade

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Module Cascade.StylesheetSource

CSS stylesheet interface.

This module models stylesheet syntax and CSS-file-local structure: construction, parsing, printing, traversal helpers, and context-free cascade ordering helpers. Operations that need information beyond stylesheet text should take an explicit closed context record from a dedicated module, such as Context.

include module type of Stylesheet_intf
type layer_name = string list
type import_rule = Cascade__Stylesheet_intf.import_rule = {
  1. url : string;
  2. layer : layer_name option;
  3. supports : Supports.t option;
  4. media : Media.t option;
}
type !'a property_rule = 'a Cascade__Stylesheet_intf.property_rule = {
  1. name : string;
  2. syntax : 'a Variables.syntax;
  3. inherits : bool;
  4. initial_value : 'a option;
}
type cascade_origin = Cascade__Stylesheet_intf.cascade_origin =
  1. | User_agent
  2. | User
  3. | Author_presentational_hint
  4. | Author
  5. | Animation
  6. | Transition
type cascade_layer_candidate = Cascade__Stylesheet_intf.cascade_layer_candidate = {
  1. layer : string option;
  2. important : bool;
  3. source_order : int;
  4. value : string;
}
type cascade_origin_candidate = Cascade__Stylesheet_intf.cascade_origin_candidate = {
  1. origin : cascade_origin;
  2. important : bool;
  3. source_order : int;
  4. value : string;
}
type declared_value = Cascade__Stylesheet_intf.declared_value = {
  1. property : string;
  2. value : string;
  3. important : bool;
  4. source_order : int;
}
type value_source = Cascade__Stylesheet_intf.value_source =
  1. | Cascaded
  2. | Initial_default
  3. | Inherited_default
  4. | Initial_keyword
  5. | Inherit_keyword
  6. | Unset_initial
  7. | Unset_inherited
type value = Cascade__Stylesheet_intf.value = {
  1. value : string;
  2. value_source : value_source;
}
type value_processing_stage = Cascade__Stylesheet_intf.value_processing_stage =
  1. | Declared_value
  2. | Cascaded_value
  3. | Specified_value
  4. | Computed_value
  5. | Used_value
  6. | Actual_value
type url_form = Cascade__Stylesheet_intf.url_form =
  1. | Bare
  2. | Quoted of char
type namespace_url = Cascade__Stylesheet_intf.namespace_url =
  1. | Url of string * url_form
  2. | Quoted of string
type cascade_candidate = Cascade__Stylesheet_intf.cascade_candidate = {
  1. origin : cascade_origin;
  2. layer : string option;
  3. important : bool;
  4. specificity : int;
  5. scope_hops : int option;
  6. source_order : int;
  7. value : string;
}
type rule = Cascade__Stylesheet_intf.rule = {
  1. selector : Selector.t;
  2. declarations : Declaration.declaration list;
  3. nested : statement list;
  4. merge_key : string option;
}
and statement = Cascade__Stylesheet_intf.statement =
  1. | Rule of rule
  2. | Declarations of Declaration.declaration list
  3. | Bang_comment of string
  4. | Charset of string
  5. | Import of import_rule
  6. | Namespace of string option * namespace_url
  7. | Property : 'a property_rule -> statement
  8. | Layer_decl of layer_name list
  9. | Layer of layer_name option * block
  10. | Media of Media.t * block
  11. | Container of string option * Container.t option * block
  12. | Supports of Supports.t * block
  13. | Moz_document of moz_document_condition list * block
  14. | Starting_style of block
  15. | When of conditional * block
  16. | Else of conditional option * block
  17. | Supports_condition of string * Declaration.declaration list
  18. | Origin of cascade_origin * block
  19. | Scope of Selector.t option * Selector.t option * block
  20. | Keyframes of string * keyframe list
  21. | Webkit_keyframes of string * keyframe list
  22. | Moz_keyframes of string * keyframe list
  23. | Font_face of font_face_descriptor list
  24. | Counter_style of string * counter_style_descriptor list
  25. | Page of page_selector list * Declaration.declaration list
  26. | Page_with_margins of page_selector list * page_descriptor list * page_margin_rule list
  27. | Font_palette_values of string * font_palette_descriptor list
  28. | Font_feature_values of Properties.font_family list * font_feature_values_block list
  29. | View_transition of view_transition_descriptor list
  30. | Position_try of string * Declaration.declaration list
  31. | Viewport of viewport_prefix * viewport_descriptor list
  32. | Unknown_at_rule of {
    1. name : string;
    2. prelude : string;
    3. block : string option;
    }
and block = statement list
and conditional = Cascade__Stylesheet_intf.conditional =
  1. | Media_condition of Media.t
  2. | Supports_condition_test of Supports.t
  3. | And of conditional * conditional
  4. | Or of conditional * conditional
and moz_document_condition = Cascade__Stylesheet_intf.moz_document_condition =
  1. | Url_exact of string
  2. | Url_prefix of string option
  3. | Domain of string
  4. | Media_document of string
  5. | Regexp of string
and viewport_prefix = Cascade__Stylesheet_intf.viewport_prefix =
  1. | Standard
  2. | Ms_prefixed
and viewport_descriptor = Cascade__Stylesheet_intf.viewport_descriptor = {
  1. name : string;
  2. value : string;
}
and keyframe = Cascade__Stylesheet_intf.keyframe = {
  1. selector : Keyframe.selector;
  2. declarations : Declaration.declaration list;
}
and page_pseudo = Cascade__Stylesheet_intf.page_pseudo =
  1. | First
  2. | Left
  3. | Right
  4. | Blank
and page_selector = Cascade__Stylesheet_intf.page_selector = {
  1. name : string option;
  2. pseudos : page_pseudo list;
}
and page_descriptor = Declaration.declaration
and font_palette_base = Cascade__Stylesheet_intf.font_palette_base =
  1. | Light
  2. | Dark
  3. | Index of int
  4. | Palette_ident of string
and font_palette_descriptor = Cascade__Stylesheet_intf.font_palette_descriptor =
  1. | Palette_font_family of Properties.font_family list
  2. | Base_palette of font_palette_base
  3. | Override_colors of (int * Values.color) list
and font_feature_values_block = string * (string * int list) list
and counter_style_system = Cascade__Stylesheet_intf.counter_style_system =
  1. | Cyclic
  2. | Numeric
  3. | Alphabetic
  4. | Symbolic
  5. | Fixed of int option
  6. | Additive
  7. | Extends of string
and counter_style_descriptor = Cascade__Stylesheet_intf.counter_style_descriptor =
  1. | System of counter_style_system
  2. | Symbols of string list
  3. | Suffix of string
  4. | Prefix of string
  5. | Fallback of string
  6. | Range of string
  7. | Pad of string
  8. | Negative of string
  9. | Additive_symbols of string
  10. | Speak_as of string
and view_transition_descriptor = Cascade__Stylesheet_intf.view_transition_descriptor =
  1. | Navigation of [ `Auto | `None ]
  2. | Types of string list option
and font_variant_descriptor = Cascade__Stylesheet_intf.font_variant_descriptor =
  1. | Normal
  2. | None
  3. | Values of font_variant_descriptor_value list
  4. | Var of font_variant_descriptor Values.var
and font_variant_descriptor_value = Cascade__Stylesheet_intf.font_variant_descriptor_value =
  1. | Ligature of Properties.font_variant_ligature
  2. | Caps of Properties.font_variant_caps
  3. | Numeric of Properties.font_variant_numeric_token
  4. | East_asian of Properties.east_asian_feature
and page_margin_rule = Cascade__Stylesheet_intf.page_margin_rule = {
  1. name : string;
  2. descriptors : Declaration.declaration list;
}
and font_face_descriptor = Cascade__Stylesheet_intf.font_face_descriptor =
  1. | Font_family of Properties.font_family list
  2. | Src of Font_face.src
  3. | Font_style of Properties.font_style
  4. | Font_style_auto
  5. | Font_weight of Properties.font_weight
  6. | Font_weight_range of Properties.font_weight * Properties.font_weight
  7. | Font_weight_auto
  8. | Font_stretch of Properties.font_stretch
  9. | Font_stretch_range of Properties.font_stretch * Properties.font_stretch
  10. | Font_stretch_auto
  11. | Font_display of Properties.font_display
  12. | Unicode_range of Properties.unicode_range list
  13. | Font_variant of font_variant_descriptor
  14. | Font_feature_settings of Properties.font_feature_settings
  15. | Font_variation_settings of Properties.font_variation_settings
  16. | Size_adjust of Font_face.size_adjust
  17. | Ascent_override of Font_face.metric_override
  18. | Descent_override of Font_face.metric_override
  19. | Line_gap_override of Font_face.metric_override
type stylesheet = statement list
type !'a edit = 'a Cascade__Stylesheet_intf.edit =
  1. | Keep
  2. | Replace of 'a
  3. | Drop
type mode = Cascade__Stylesheet_intf.mode =
  1. | Variables
  2. | Inline
val equal_cascade_origin : cascade_origin -> cascade_origin -> bool
val equal : stylesheet -> stylesheet -> bool

Stylesheet value type.

Construction Functions

Sourceval rule : selector:Selector.t -> ?nested:statement list -> ?merge_key:string -> Declaration.declaration list -> rule

rule ~selector ?nested ?merge_key declarations creates a CSS rule with optional nested rules/at-rules and an optional merge key for combining rules with identical declarations.

Sourceval property : syntax:'a Variables.syntax -> ?initial_value:'a -> ?inherits:bool -> string -> statement

property ~syntax ?initial_value ?inherits name creates a @property rule with typed syntax and initial value.

Sourceval layer_decl : layer_name list -> statement

layer_decl names creates a layer declaration statement.

Sourceval layer : ?name:layer_name -> block -> statement

layer ?name content creates a @layer rule.

Sourceval media : condition:Media.t -> block -> statement

media ~condition content creates a @media rule.

Sourceval media_nested : condition:Media.t -> Declaration.declaration list -> statement

media_nested ~condition declarations creates a @media rule for CSS nesting, containing bare declarations (no selector). Used inside rules where the selector is inherited from the parent.

Sourceval container : ?name:string -> ?condition:Container.t -> block -> statement

container ?name ~condition content creates a @container rule.

Sourceval supports : condition:Supports.t -> block -> statement

supports ~condition content creates a @supports rule.

Sourceval starting_style : block -> statement

starting_style content creates a @starting-style rule.

Sourceval unknown_at_rule : name:string -> prelude:string -> ?block:string -> unit -> (statement, Error.t) result

unknown_at_rule ~name ~prelude ?block () is the at-rule \@name prelude with block as its body, or the reason its parts cannot make one. Omitting block gives the statement form, \@name prelude;.

name is the at-keyword without its @. An unknown at-rule has no grammar to re-serialise a body from, so block is the text between its braces, the same text read slices out of the source. Pass to_string ~minify:true statements to put a block cascade does model inside one.

Text ends the at-rule wherever CSS Syntax 3 says it does: at a top-level ; or { in the prelude (sec. 5.5.2), at the closer matching an opener in the block (sec. 5.5.9), at EOF once an unclosed /* has started (sec. 4.3.2). A part reaching one of those first prints a sheet that re-consumes to statements the caller never wrote, so the parts are read back and refused when they do. The refusal names one at-rule, so a caller keeps the rest of the sheet rather than losing it to one bad part.

Sourceval with_origin : cascade_origin -> block -> statement

with_origin cascade_origin content records the cascade origin for a stylesheet block. This is an API-level wrapper with no CSS syntax.

Sourceval origin_importance_rank : important:bool -> cascade_origin -> int

origin_importance_rank ~important origin returns the cascade precedence rank for the origin/importance criterion. Larger ranks have higher precedence.

Sourceval import_layer_name : import_rule -> layer_name option

import_layer_name rule returns the layer name declared by an @import rule: None means the import does not declare a layer, Some [] means the import declares an anonymous layer, and Some name is the declared layer name.

Sourceval equal_layer_name : layer_name -> layer_name -> bool

equal_layer_name a b is whether a and b are the same layer, that is the same idents in the same order. Two layers whose CSS text differs only in how an ident is escaped are the same layer; @layer a\2e b and @layer a.b are not.

Sourceval equal_statement : statement -> statement -> bool

equal_statement a b is whether a and b are the same statement. Every part is read through the equality its own module states, so two \@media blocks whose queries select the same media are one statement even where the two queries are spelled apart, while an \@supports guard naming a different value stays a second statement.

Sourceval hash_statement : statement -> int

hash_statement stmt is a fingerprint of stmt consistent with equal_statement: two statements that are equal always return the same value, and the converse may fail on a collision, so use it as a cheap pre-filter before falling back to equal_statement.

It reads the statement's shape, Declaration.hash of every declaration it holds, Selector.hash of every selector, the names and descriptors it carries, and, recursively, the statements of its block. It does not read the condition of an \@media, \@container or \@supports rule, since none of the three states a hash agreeing with its equality; two statements differing only in a condition share a bucket.

Sourceval layer_block_name : statement -> layer_name option

layer_block_name stmt returns the declared name for an @layer block rule. It returns Some [] for anonymous layer blocks, Some name for named layer blocks, and None for non-layer-block statements. The returned name is the at-rule's own declared name, not a parent-prefixed name.

Sourceval layer_statement_name_list : statement -> layer_name list option

layer_statement_name_list stmt returns the declared name list for statement-form @layer rules.

Sourceval cascade_layer_precedence_rank : layer_order:string list -> important:bool -> string option -> int

cascade_layer_precedence_rank ~layer_order ~important layer returns the same-origin layer precedence rank. For normal declarations, later explicit layers and then the implicit unlayered layer rank higher. For important declarations, that order is reversed, with important unlayered declarations ranked below important explicit layers.

Sourceval compare_cascade_layer_candidate : layer_order:string list -> cascade_layer_candidate -> cascade_layer_candidate -> int

compare_cascade_layer_candidate compares same-origin/same-specificity candidates by importance, layer precedence, then source order.

Sourceval winning_cascade_layer_candidate : layer_order:string list -> cascade_layer_candidate list -> cascade_layer_candidate option

winning_cascade_layer_candidate returns the winning candidate using compare_cascade_layer_candidate.

Sourceval cascade_revert_layer_candidates : layer_order:string list -> important:bool -> current_layer:string option -> cascade_layer_candidate list -> cascade_layer_candidate list

cascade_revert_layer_candidates returns the same-importance candidates in lower-priority layers than current_layer, modeling the candidate set used after revert-layer removes declarations from the current layer.

Sourceval compare_cascade_origin_candidate : cascade_origin_candidate -> cascade_origin_candidate -> int

compare_cascade_origin_candidate compares same-specificity candidates by origin/importance precedence, then source order.

Sourceval winning_cascade_origin_candidate : cascade_origin_candidate list -> cascade_origin_candidate option

winning_cascade_origin_candidate returns the winning candidate using compare_cascade_origin_candidate.

Sourceval cascade_revert_origin_candidates : important:bool -> current_origin:cascade_origin -> cascade_origin_candidate list -> cascade_origin_candidate list

cascade_revert_origin_candidates returns same-importance candidates in the origins exposed by a revert declaration from current_origin.

Sourceval declared_values : ?property:string -> Declaration.declaration list -> declared_value list

declared_values ?property declarations returns the declared values contributed by declarations, preserving declaration source order. When property is supplied, only declarations for that property are returned.

Sourceval cascaded_value : cascade_origin_candidate list -> string option

cascaded_value candidates returns the winning cascaded value payload, or None when no candidate contributes a value.

Sourceval compare_cascade_candidate : layer_order:string list -> cascade_candidate -> cascade_candidate -> int

compare_cascade_candidate ~layer_order a b compares full same-property cascade candidates by origin/importance, layer, specificity, scoping proximity, and source order.

Sourceval winning_cascade_candidate : layer_order:string list -> cascade_candidate list -> cascade_candidate option

winning_cascade_candidate ~layer_order candidates returns the highest priority full cascade candidate.

Sourceval value : inherits:bool -> initial:string -> inherited:string option -> cascaded:string option -> value

value ~inherits ~initial ~inherited ~cascaded models the defaulting step that produces a specified value from a cascaded value for initial, inherit, and unset. inherited = None means the element has no parent value and falls back to initial.

Sourceval specified_value_after_revert : inherits:bool -> initial:string -> inherited:string option -> cascade_origin_candidate list -> value

specified_value_after_revert resolves a chain of revert winners by rolling back to the next-lower origin until a non-revert candidate (or none) survives, then defaults the result. The rollback context is taken from each winning candidate, so callers do not need to pass current_origin.

Sourceval specified_value_after_revert_layer : inherits:bool -> initial:string -> inherited:string option -> layer_order:string list -> cascade_layer_candidate list -> value

specified_value_after_revert_layer is the revert-layer analogue of specified_value_after_revert: chains rollback through the lower-priority layers until a non-revert-layer winner remains.

Sourceval value_processing_requires_document_context : value_processing_stage -> bool

value_processing_requires_document_context stage is true for stages this parser/serializer cannot compute from CSS text alone without caller-supplied document, inheritance, layout, rendering, or device context.

Sourceval starting_style_nested : Declaration.declaration list -> statement

starting_style_nested declarations creates a @starting-style rule for CSS nesting, containing bare declarations (no selector). Used inside rules where the selector is inherited from the parent.

Sourceval keyframes : string -> keyframe list -> statement

keyframes name frames creates a @keyframes animation rule.

Sourceval v : statement list -> stylesheet

v statements creates a stylesheet from a list of statements.

Sourceval empty : t

empty is an empty stylesheet.

Accessors

Sourceval selector : rule -> Selector.t

selector rule returns the selector of a rule.

Sourceval declarations : rule -> Declaration.declaration list

declarations rule returns the run of declarations written before the rule's first nested statement. CSS Nesting 1 sec. 3.4 wraps a run written after one in a nested declarations rule, so it stays in nested at the position it was written; this is the whole body only for a rule that nests nothing.

Sourceval nested : rule -> statement list

nested rule returns the nested statements of a rule.

Sourceval statement_children : statement -> block

statement_children stmt is the block stmt wraps: a rule's nested statements, the body of a grouping at-rule (@media, @supports, @container, @layer, @scope, @starting-style, @when, @else, @-moz-document, and the Origin wrapper), and [] for a statement that holds no statements of its own. It is the one place that knows which at-rules nest, so a traversal written on top of it cannot miss one: the match is exhaustive, and a block at-rule added to the AST later does not compile until it is listed here.

Sourceval statement_declarations : statement -> Declaration.declaration list

statement_declarations stmt is the declarations stmt holds directly: a rule's or a bare Declarations block's own declarations, the descriptors of @page, @position-try and @supports-condition, the margin-rule descriptors of a @page with margins, and the concatenated declarations of every frame of @keyframes (and its -webkit-/-moz- spellings). It is [] for a grouping at-rule, whose declarations live in the block statement_children returns, and for a descriptor at-rule such as @font-face or @counter-style, which holds descriptor values rather than declarations. Paired with statement_children it visits every declaration in a stylesheet, and it is exhaustive for the same reason: a declaration-carrying at-rule added to the AST later does not compile until it is listed here.

Sourceval map_statement_children : (block -> block) -> statement -> statement

map_statement_children f stmt rebuilds stmt with f applied to the block statement_children reads, and returns a statement that holds no block unchanged. It is the rebuilding counterpart of statement_children, for a walk that rewrites the tree rather than only reading it. It preserves physical identity: when f returns the block it was given, the result is stmt itself.

Sourceval map_statement_declarations : (Declaration.declaration list -> Declaration.declaration list) -> statement -> statement

map_statement_declarations f stmt rebuilds stmt with f applied to the declarations it holds directly, and returns a statement that holds none unchanged. It is the rebuilding counterpart of statement_declarations, with one difference: f sees each declaration list as its own list rather than the concatenation, so every frame of @keyframes and every margin rule of @page keeps its own block. It preserves physical identity: when f returns every list it was given, the result is stmt itself.

Sourcetype declaration_sites = {
  1. element_rule : bool;
    (*

    A style rule or a bare nesting block: declarations that apply to an element.

    *)
  2. animation_frame : bool;
    (*

    A frame of @keyframes (and of its -webkit- / -moz- spellings): declarations in the animation origin.

    *)
  3. page_box : bool;
    (*

    @page and its margin boxes: declarations that apply to a page box rather than to an element.

    *)
  4. position_fallback : bool;
    (*

    @position-try: declarations in the position fallback origin.

    *)
  5. condition_test : bool;
    (*

    @supports-condition: declarations that are tested rather than applied.

    *)
}

The places a stylesheet holds declarations, grouped by what the declarations there mean rather than by which at-rule spells them. A walk that wants only some of them says so with this record instead of matching on the statements it expects to meet, which separates a narrow walk from one that forgot an at-rule, and makes a place added here a compile error in every walk that made a choice.

Sourceval at_declaration_site : declaration_sites -> statement -> bool

at_declaration_site sites stmt holds when the declarations stmt carries sit in one of the places sites names. It is the test fold_declarations makes, exposed for a walk that carries something down the tree, such as the cascade layer a declaration sits in or an @supports nesting depth. An accumulator travels sideways rather than down, so such a walk cannot be a fold and recurses on statement_children instead; this keeps the sites it reads as compile-checked as the fold's.

Sourceval fold_statements : ('a -> statement -> 'a) -> 'a -> block -> 'a

fold_statements f acc block folds f over block and over every statement reachable from it through statement_children, in source order, a statement before the statements it holds.

Sourceval iter_statements : (statement -> unit) -> block -> unit

iter_statements f block applies f to every statement fold_statements reaches.

Sourceval edit_statements : (statement -> statement edit) -> block -> block

edit_statements f block rewrites the statements fold_statements reaches: f keeps, replaces or drops each one, and the walk descends through map_statement_children into what survives, so a caller names only the statements it acts on rather than the at-rules they nest inside. Dropping a statement drops what it holds. f sees a statement before the statements it holds, and the walk continues into a replacement rather than into the statement it replaced. It preserves physical identity: when f keeps every statement, the result is block itself.

Sourceval fold_declarations : ?sites:declaration_sites -> ('a -> Declaration.declaration list -> 'a) -> 'a -> block -> 'a

fold_declarations f acc block folds f over the declarations of every statement fold_statements reaches, so a rule nested in a rule and an at-rule that holds declarations outside a block are both covered. f sees one statement's declarations at a time, as statement_declarations returns them. sites defaults to every place a declaration sits; pass it to fold over some of them, and write the record out in full so that a place added to it does not compile until this walk has been read again.

Sourceval iter_declarations : ?sites:declaration_sites -> (Declaration.declaration list -> unit) -> block -> unit

iter_declarations f block applies f to the declaration lists fold_declarations folds over.

Sourceval map_declarations : (Declaration.declaration list -> Declaration.declaration list) -> block -> block

map_declarations f block rewrites the declarations of every statement fold_statements reaches. f sees each declaration list as its own list, as map_statement_declarations hands them over, so every frame of @keyframes and every margin rule of @page keeps its own block. It preserves physical identity: when f returns every list it was given, the result is block itself.

Reading/Parsing

Sourceval read_rule : ?nested:bool -> Cursor.t -> rule

read_rule r reads a CSS rule from the reader. With ~nested:true the prelude is parsed as a CSS Nesting <relative-selector-list>, so it may start with a combinator (> .bar) taken relative to the parent &.

Sourceval read_block : Cursor.t -> block

read_block r reads a CSS block from the reader.

Sourceval read_font_variant_descriptor : Cursor.t -> font_variant_descriptor

read_font_variant_descriptor r reads the font-variant descriptor of an \@font-face rule, or a var() standing for one. Inline reads a custom property back through it when resolving such a reference.

Sourceval read : Cursor.t -> t

read r reads a complete CSS stylesheet from the cursor. Raises Cursor.Parse_error on the first validator failure; use parse_stylesheet_partial to get the recovered sheet with warnings instead.

Sourceval read_stylesheet_of_rules : ?source:string -> ?meta:Loc.meta_level -> Component.rule list -> stylesheet * Error.t list

read_stylesheet_of_rules ?source ?meta rules validates each Parser- recovered Component.rule to a typed statement independently. A validator failure on one rule is captured as a warning and the rule is dropped; the remaining rules are returned. Pass ?source (and keep ?meta at its default `Full) so dropped-rule warnings carry source- context snippets.

Sourcemodule Source : sig ... end

Immutable source fidelity captured by parse_stylesheet_partial ~on_source.

Sourceval parse_stylesheet_partial : ?meta:Loc.meta_level -> ?enforce_spec:bool -> ?on_source:(Source.t -> unit) -> string -> stylesheet * Error.t list

parse_stylesheet_partial ?meta source runs section 5.3 recovery via Parser.stylesheet and then typed-validates each recovered rule via read_stylesheet_of_rules. Warnings from both stages are combined in source order.

Pass ~on_source to opt into one immutable authored-syntax snapshot from the same parse. It retains the exact input, preprocessed input when different, located syntax tree, comment records, line index, and original- byte boundary map. Transforming the returned typed stylesheet never mutates the snapshot and deliberately creates no inferred source map for split, merged, dropped, or synthetic nodes.

Pretty Printing

Sourceval pp_rule : rule Pp.t

pp_rule pretty-prints CSS rules.

Sourceval pp_stylesheet : stylesheet Pp.t

pp_stylesheet pretty-prints CSS stylesheets.

Sourceval pp : t Pp.t

Variable Extraction

Sourceval vars_of_stylesheet : stylesheet -> Variables.any_var list

vars_of_stylesheet ss is every variable ss references, from the declarations fold_declarations reaches, so a rule nested in a rule and an at-rule carrying declarations of its own are both covered. Deduplicated, in source order.

Rendering

Sourceval to_string : ?minify:bool -> ?indent:int -> ?lossless:bool -> ?enforce_spec:bool -> t -> string

to_string ?minify ?indent stylesheet serialises a stylesheet to CSS. Pure formatter - no optimisation, no theme resolution.

Legacy Compatibility

Sourceval rules : t -> rule list

rules t returns the top-level rules from the stylesheet.

Sourceval layers : t -> layer_name list

layers t is every cascade layer t declares, one path per layer (a.b is the sublayer b of a, however it was written), in the order the sheet first names them. Each path is its idents, so a . one ident carries is not the separator between two. A layer named inside a conditional group counts: the group decides whether its contents apply, not whether the layer exists. A sublayer of an anonymous @layer { ... } has no name to report.

Sourceval layer_block : layer_name -> t -> block option

layer_block name t is the statements of the layer name, wherever it is declared and whatever form declares it: a dotted name, a nested block, or a block inside a conditional group. It is None when no @layer block opens that layer, so a name only an @layer a, b; statement declares is None as well.

Sourceval media_queries : t -> (Media.t * rule list) list

media_queries t is every @media in t, at any depth, paired with every rule below its brace. A query inside a group at-rule counts, and a rule nested in another rule or held by an inner group is one of the query's rules; a nested rule keeps the relative selector it was written with.

Sourceval container_queries : t -> (string option * Container.t option * rule list) list

container_queries t is every @container in t, paired with every rule below its brace, on the same terms as media_queries.

Parsing and Pretty-printing

Sourceval pp_import_rule : import_rule Pp.t

pp_import_rule pretty-prints an import rule.

Sourceval read_import_rule : Cursor.t -> import_rule

read_import_rule r parses an import rule.

Sourceval pp_layer_name : layer_name Pp.t

pp_layer_name prints a <layer-name>: each ident with the escapes that read it back (CSS Syntax 3 (ED) sec. 2.1), joined by the . separators of CSS Cascade 5 sec. 6.4.1. A . an ident carries is escaped, so it never reads back as a separator.

Sourceval read_layer_name : Cursor.t -> layer_name

read_layer_name r parses a <layer-name>. It rejects a CSS-wide keyword, which CSS Cascade 5 sec. 6.4.1 reserves.

Sourceval string_of_layer_name : layer_name -> string

string_of_layer_name name is what pp_layer_name prints. Two names never share their text, so it keys a layer.

Sourceval rule_hash : rule -> int

rule_hash r is a cheap hash that discriminates rules by their cached declaration hashes. Equal rules hash equally; unequal rules may collide, so callers still confirm with structural equality.