cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
css_composer.h File Reference

Dynamic CSS Synthesis and Color Mathematics. More...

#include <cwist/core/sstring/sstring.h>
#include <stdbool.h>
Include dependency graph for css_composer.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  cwist_color_rgb
 RGB Color representation. More...
 
struct  cwist_color_hsl
 HSL Color representation for dynamic manipulation. More...
 
struct  cwist_css_config
 Dynamic CSS configuration parameters. Contains base metrics used to extrapolate an entire design system. More...
 
struct  cwist_css_scope
 Component-scoped class names and the rules attached to them. More...
 

Typedefs

typedef struct cwist_color_rgb cwist_color_rgb
 RGB Color representation.
 
typedef struct cwist_color_hsl cwist_color_hsl
 HSL Color representation for dynamic manipulation.
 
typedef struct cwist_css_config cwist_css_config
 Dynamic CSS configuration parameters. Contains base metrics used to extrapolate an entire design system.
 
typedef struct cwist_css_scope cwist_css_scope
 Component-scoped class names and the rules attached to them.
 

Functions

cwist_color_hsl cwist_color_rgb_to_hsl (cwist_color_rgb rgb)
 Converts an RGB color to HSL color space.
 
cwist_color_rgb cwist_color_hsl_to_rgb (cwist_color_hsl hsl)
 Converts an HSL color back to RGB color space.
 
cwist_color_rgb cwist_color_hex_to_rgb (const char *hex)
 Parses a hex string (e.g., "#FF0000", "FF0000", "#F00", or "F00") into an RGB struct.
 
void cwist_color_rgb_to_hex (cwist_color_rgb rgb, char out_hex[8])
 Formats an RGB struct into a 7-character hex string (e.g., "#FFFFFF").
 
void cwist_css_config_init (cwist_css_config *cfg)
 Initializes a CSS configuration with sensible defaults.
 
cwist_sstring * cwist_css_generate_variables (const cwist_css_config *cfg)
 Generates a CSS string containing CSS Custom Properties (:root variables). Extrapolates hover states, active states, and surface colors mathematically.
 
cwist_sstring * cwist_css_generate_utility_classes (const cwist_css_config *cfg)
 Generates a set of utility classes based on the design system configuration.
 
cwist_sstring * cwist_css_generate_stylesheet (const cwist_css_config *cfg)
 High-level helper to generate a complete stylesheet (Variables + Utilities).
 
cwist_sstring * cwist_css_minify (const char *css)
 Minify a stylesheet without changing what it means.
 
cwist_sstring * cwist_css_bundle (const char *const *parts, size_t count, bool minify)
 Concatenate stylesheets in order into one bundle, optionally minified.
 
void cwist_css_scope_init (cwist_css_scope *scope, const char *component_name)
 Initialise a scope for one component.
 
const char * cwist_css_scope_class (cwist_css_scope *scope, const char *base_class)
 Map a base class to its scoped name ("btn" -> "btn-a1b2c3d4").
 
int cwist_css_scope_add_rule (cwist_css_scope *scope, const char *base_class, const char *declarations)
 Attach declarations to a base class, replacing any earlier ones.
 
cwist_sstring * cwist_css_scope_generate_stylesheet (const cwist_css_scope *scope)
 Emit one rule per class that is both used and has declarations.
 
void cwist_css_scope_destroy (cwist_css_scope *scope)
 Release everything the scope owns and reset it to an empty state.
 

Detailed Description

Dynamic CSS Synthesis and Color Mathematics.

Definition in file css_composer.h.

Typedef Documentation

◆ cwist_color_hsl

HSL Color representation for dynamic manipulation.

◆ cwist_color_rgb

RGB Color representation.

◆ cwist_css_config

Dynamic CSS configuration parameters. Contains base metrics used to extrapolate an entire design system.

◆ cwist_css_scope

Component-scoped class names and the rules attached to them.

Every class handed out by a scope carries the same suffix, derived from the component name with a fixed (unseeded) 32-bit FNV-1a hash, so "btn" in scope "card" is always "btn-<8 hex digits>" in every process and every run. Only the fields below are public; treat them as read-only.

Function Documentation

◆ cwist_color_hex_to_rgb()

cwist_color_rgb cwist_color_hex_to_rgb ( const char *  hex)

Parses a hex string (e.g., "#FF0000", "FF0000", "#F00", or "F00") into an RGB struct.

Parameters
hexThe null-terminated hex string.
Returns
The parsed RGB color. Defaults to black on parse error.

Parses a hex string (e.g., "#FF0000", "FF0000", "#F00", or "F00") into an RGB struct.

Parameters
hexHex string in "#rrggbb", "rrggbb", "#rgb", or "rgb" form. A leading '#' is optional.
Returns
Parsed RGB color. Returns black ({0, 0, 0}) if hex is NULL or malformed (wrong length or non-hex characters).

Definition at line 121 of file css_composer.c.

References cwist_color_rgb::b, cwist_color_rgb::g, and cwist_color_rgb::r.

Referenced by cwist_css_config_init().

◆ cwist_color_hsl_to_rgb()

cwist_color_rgb cwist_color_hsl_to_rgb ( cwist_color_hsl  hsl)

Converts an HSL color back to RGB color space.

Parameters
hslThe HSL color to convert.
Returns
The corresponding RGB representation.

Converts an HSL color back to RGB color space.

Parameters
hslHue in degrees (0-360), saturation and lightness in 0-1.
Returns
RGB components in the range 0-255, rounded to the nearest integer. A saturation of 0 yields a grayscale color.

Definition at line 76 of file css_composer.c.

References cwist_color_rgb::b, cwist_color_rgb::g, cwist_color_hsl::h, cwist_color_hsl::l, cwist_color_rgb::r, and cwist_color_hsl::s.

◆ cwist_color_rgb_to_hex()

void cwist_color_rgb_to_hex ( cwist_color_rgb  rgb,
char  out_hex[8] 
)

Formats an RGB struct into a 7-character hex string (e.g., "#FFFFFF").

Parameters
rgbThe RGB color.
out_hexA character array of at least 8 bytes to hold the result.

Formats an RGB struct into a 7-character hex string (e.g., "#FFFFFF").

Parameters
rgbRGB components in the range 0-255.
out_hexOutput buffer of at least 8 bytes; left untouched if NULL.

Definition at line 156 of file css_composer.c.

References cwist_color_rgb::b, cwist_color_rgb::g, and cwist_color_rgb::r.

Referenced by cwist_css_generate_variables().

◆ cwist_color_rgb_to_hsl()

cwist_color_hsl cwist_color_rgb_to_hsl ( cwist_color_rgb  rgb)

Converts an RGB color to HSL color space.

Parameters
rgbThe RGB color to convert.
Returns
The corresponding HSL representation.

Converts an RGB color to HSL color space.

Parameters
rgbRGB components in the range 0-255.
Returns
HSL with hue in degrees (0-360), saturation and lightness in 0-1. Achromatic colors yield saturation and hue of 0.

Definition at line 24 of file css_composer.c.

References cwist_color_rgb::b, cwist_color_rgb::g, cwist_color_hsl::h, cwist_color_hsl::l, MAX3, MIN3, cwist_color_rgb::r, and cwist_color_hsl::s.

◆ cwist_css_bundle()

cwist_sstring * cwist_css_bundle ( const char *const *  parts,
size_t  count,
bool  minify 
)

Concatenate stylesheets in order into one bundle, optionally minified.

Parts are joined with a newline so the end of one part and the start of the next can never merge into one token. NULL entries are skipped. The bundle is a plain concatenation: @import rules are not resolved and an @charset or @import in a later part stays where it is.

Parameters
partsStylesheets to join, in order.
countNumber of entries in parts; parts may be NULL only when 0.
minifyRun cwist_css_minify() over the result.
Returns
A dynamically allocated string (empty for no parts), or NULL on invalid arguments or allocation failure. Must be destroyed.

Concatenate stylesheets in order into one bundle, optionally minified.

Parameters
partsArray of CSS text fragments; may be NULL only if count is 0.
countNumber of entries in parts.
minifyIf true, the concatenated result is passed through cwist_css_minify().
Returns
Newly created sstring with the bundled CSS, or NULL on invalid input or allocation failure. Caller owns the returned string.

Definition at line 654 of file css_composer.c.

References count, cwist_css_minify(), cwist_error_dispose(), cwist_sstring_assign(), cwist_sstring_create(), cwist_sstring_destroy(), and cwist_sstring::data.

◆ cwist_css_config_init()

void cwist_css_config_init ( cwist_css_config *  cfg)

Initializes a CSS configuration with sensible defaults.

Parameters
cfgPointer to the configuration struct to initialize.

Initializes a CSS configuration with sensible defaults.

Parameters
cfgConfiguration to fill. No-op if NULL.

Defaults: Tailwind blue primary, Tailwind green secondary, 8px roundness, 4px spacing base, light mode.

Definition at line 168 of file css_composer.c.

References cwist_color_hex_to_rgb(), cwist_css_config::is_dark_mode, cwist_css_config::primary_color, cwist_css_config::roundness_px, cwist_css_config::secondary_color, and cwist_css_config::spacing_base_px.

◆ cwist_css_generate_stylesheet()

cwist_sstring * cwist_css_generate_stylesheet ( const cwist_css_config *  cfg)

High-level helper to generate a complete stylesheet (Variables + Utilities).

Parameters
cfgThe configuration parameters.
Returns
A dynamically allocated string containing the full stylesheet.

High-level helper to generate a complete stylesheet (Variables + Utilities).

Parameters
cfgTheme configuration; must not be NULL.
Returns
Newly created sstring with the concatenated CSS, or NULL if cfg is NULL or allocation fails. Caller owns the returned string.

Definition at line 294 of file css_composer.c.

References cwist_css_generate_utility_classes(), cwist_css_generate_variables(), cwist_sstring_append(), cwist_sstring_create(), cwist_sstring_destroy(), and cwist_sstring::data.

◆ cwist_css_generate_utility_classes()

cwist_sstring * cwist_css_generate_utility_classes ( const cwist_css_config *  cfg)

Generates a set of utility classes based on the design system configuration.

Parameters
cfgThe configuration parameters.
Returns
A dynamically allocated string containing the CSS classes. Must be destroyed.

Generates a set of utility classes based on the design system configuration.

Parameters
cfgTheme configuration (currently unused; classes reference CSS variables).
Returns
Newly created sstring with the generated CSS, or NULL on allocation failure. Caller owns the returned string.

Definition at line 248 of file css_composer.c.

References cwist_sstring_append(), and cwist_sstring_create().

Referenced by cwist_css_generate_stylesheet().

◆ cwist_css_generate_variables()

cwist_sstring * cwist_css_generate_variables ( const cwist_css_config *  cfg)

Generates a CSS string containing CSS Custom Properties (:root variables). Extrapolates hover states, active states, and surface colors mathematically.

Parameters
cfgThe configuration parameters.
Returns
A dynamically allocated string containing the CSS rules. Must be destroyed.

Generates a CSS string containing CSS Custom Properties (:root variables). Extrapolates hover states, active states, and surface colors mathematically.

Parameters
cfgTheme configuration; must not be NULL.
Returns
Newly created sstring with the generated CSS, or NULL if cfg is NULL or allocation fails. Caller owns the returned string.

Definition at line 195 of file css_composer.c.

References cwist_color_rgb_to_hex(), cwist_sstring_append(), cwist_sstring_create(), cwist_css_config::is_dark_mode, cwist_css_config::primary_color, cwist_css_config::roundness_px, cwist_css_config::secondary_color, and cwist_css_config::spacing_base_px.

Referenced by cwist_css_generate_stylesheet().

◆ cwist_css_minify()

cwist_sstring * cwist_css_minify ( const char *  css)

Minify a stylesheet without changing what it means.

  • Comments are removed, except those whose text starts with '!' (the usual marker for license notices), which are kept as written.
  • Whitespace is dropped after {, }, ;, ,, :, > and (, and before {, }, ;, ,, > and ). Any other run of whitespace becomes a single space, so the space in a descendant selector such as a :hover, before a media-query (, and around the + and - that calc() needs is kept.
  • The ; right before a } is dropped.
  • Strings and unquoted url(...) arguments are copied verbatim.

Input that ends inside a string or url( is copied through; an unterminated comment runs to the end of the input, as CSS defines.

Parameters
cssNUL-terminated stylesheet.
Returns
A dynamically allocated string, or NULL when css is NULL or allocation fails. Must be destroyed.

Minify a stylesheet without changing what it means.

Parameters
cssCSS source text; must not be NULL.
Returns
Newly created sstring with the minified CSS, or NULL on invalid input or allocation failure. Caller owns the returned string.

Preserves license comments (those opening with a '!'), quoted strings, escapes, and unquoted url() arguments verbatim. Whitespace around structural characters and comments is dropped unless removing it would glue two tokens.

Definition at line 547 of file css_composer.c.

References cwist_alloc(), cwist_error_dispose(), cwist_free(), cwist_sstring_assign_len(), cwist_sstring_create(), and cwist_sstring_destroy().

Referenced by cwist_css_bundle().

◆ cwist_css_scope_add_rule()

int cwist_css_scope_add_rule ( cwist_css_scope *  scope,
const char *  base_class,
const char *  declarations 
)

Attach declarations to a base class, replacing any earlier ones.

Registering a rule does not mark the class as used; a rule whose class is never requested through cwist_css_scope_class() is not emitted.

Parameters
scopeInitialised scope.
base_classCSS identifier, same rules as cwist_css_scope_class().
declarationsDeclaration block body, e.g. "padding: 4px; color: red;". Treated as trusted, application-authored CSS and emitted verbatim. '<' is rejected so the output can never end an enclosing <style> element; '{' and '}' are rejected to catch nested blocks. Nothing else is checked: an unterminated comment or string can still affect later rules, so do not pass untrusted input.
Returns
0 on success, -1 on invalid arguments or allocation failure.

Attach declarations to a base class, replacing any earlier ones.

Parameters
scopeScope to modify.
base_classBase class name; must be a valid CSS identifier.
declarationsDeclaration block text (e.g. "color: red;"). Must not contain '{', '}', or '<'.
Return values
0Declarations stored; any previous declarations are freed.
-1Invalid argument, unsafe declaration content, or allocation failure.

Definition at line 444 of file css_composer.c.

References cwist_free(), cwist_strdup(), and cwist_css_scope::suffix.

◆ cwist_css_scope_class()

const char * cwist_css_scope_class ( cwist_css_scope *  scope,
const char *  base_class 
)

Map a base class to its scoped name ("btn" -> "btn-a1b2c3d4").

Marks the class as used, so cwist_css_scope_generate_stylesheet() emits its rule. Repeated calls with the same base class return the same pointer.

Parameters
scopeInitialised scope.
base_classASCII CSS identifier: a letter or '_', optionally after one leading '-', then letters, digits, '_' or '-'. This is a strict subset of the CSS grammar: escapes, non-ASCII characters and "--" custom-property names are rejected.
Returns
Scope-owned string valid until cwist_css_scope_destroy(), or NULL for an invalid identifier or on allocation failure.

Map a base class to its scoped name ("btn" -> "btn-a1b2c3d4").

Parameters
scopeScope to query.
base_classBase class name; must be a valid CSS identifier.
Returns
Pointer to the scoped class name (e.g. "btn-a1b2c3d4") owned by the scope entry, or NULL on invalid input or allocation failure.

Definition at line 427 of file css_composer.c.

References cwist_css_scope::suffix.

◆ cwist_css_scope_destroy()

void cwist_css_scope_destroy ( cwist_css_scope *  scope)

Release everything the scope owns and reset it to an empty state.

Pointers returned by cwist_css_scope_class() become invalid. Calling it again on the same scope is harmless. A destroyed (or zero-initialised) scope rejects new classes and rules until cwist_css_scope_init() is called.

Parameters
scopeScope to release. NULL is ignored.

Release everything the scope owns and reset it to an empty state.

Parameters
scopeScope to tear down. No-op if NULL.

Frees all entry base names, scoped class strings, and declaration copies, then zeroes the scope struct.

Definition at line 496 of file css_composer.c.

References cwist_css_scope::count, cwist_free(), cwist_sstring_destroy(), and cwist_css_scope::entries.

◆ cwist_css_scope_generate_stylesheet()

cwist_sstring * cwist_css_scope_generate_stylesheet ( const cwist_css_scope *  scope)

Emit one rule per class that is both used and has declarations.

Rules appear in the order their base classes were first seen by the scope.

Parameters
scopeInitialised scope.
Returns
A dynamically allocated string (empty when nothing qualifies), or NULL when scope is NULL or allocation fails. Must be destroyed.

Emit one rule per class that is both used and has declarations.

Parameters
scopeScope to render; must not be NULL.
Returns
Newly created sstring with one ".<scoped-class> { ... }" rule per used entry, or NULL if scope is NULL or allocation fails. Caller owns the returned string.

Definition at line 468 of file css_composer.c.

References cwist_css_scope::count, cwist_error_dispose(), cwist_sstring_assign(), cwist_sstring_create(), cwist_sstring_destroy(), and cwist_css_scope::entries.

◆ cwist_css_scope_init()

void cwist_css_scope_init ( cwist_css_scope *  scope,
const char *  component_name 
)

Initialise a scope for one component.

Parameters
scopeCaller-owned storage to initialise. Release it with cwist_css_scope_destroy().
component_nameSeed for the class suffix; NULL is treated as "".

Initialise a scope for one component.

Parameters
scopeScope to initialize. No-op if NULL.
component_nameName used to derive the suffix; empty string if NULL.

The suffix is an unseeded FNV-1a 32-bit hash of the component name, so markup and stylesheets generated in different worker processes agree on the same suffix. Call cwist_css_scope_destroy() to release.

Definition at line 402 of file css_composer.c.

References cwist_css_scope::capacity, cwist_css_scope::count, cwist_css_scope::entries, and cwist_css_scope::suffix.