///|
pub(all) enum TokenKind {
Color
FontSize
Spacing
Radius
Shadow
} derive(Debug, Eq)
///|
pub(all) struct Token {
name : String
kind : TokenKind
value : String
description : String
} derive(Debug, Eq)
///|
pub fn Token::color(
name : String,
value : String,
description~ : String,
) -> Token {
{ name, kind: Color, value, description }
}
///|
pub fn Token::font_size(
name : String,
value : String,
description~ : String,
) -> Token {
{ name, kind: FontSize, value, description }
}
///|
pub fn Token::spacing(
name : String,
value : String,
description~ : String,
) -> Token {
{ name, kind: Spacing, value, description }
}
///|
pub fn Token::radius(
name : String,
value : String,
description~ : String,
) -> Token {
{ name, kind: Radius, value, description }
}
///|
pub fn Token::shadow(
name : String,
value : String,
description~ : String,
) -> Token {
{ name, kind: Shadow, value, description }
}
///|
pub fn TokenKind::label(self : TokenKind) -> String {
match self {
Color => "color"
FontSize => "font-size"
Spacing => "spacing"
Radius => "radius"
Shadow => "shadow"
}
}
///|
pub fn Token::css_variable(self : Token) -> String {
"\{self.css_name()}: \{self.value};"
}
///|
pub fn Token::json_object(self : Token) -> String {
"{ \"name\": \"\{json_string(self.name)}\", \"kind\": \"\{json_string(self.kind.label())}\", \"value\": \"\{json_string(self.value)}\", \"description\": \"\{json_string(self.description)}\" }"
}
///|
fn json_string(value : String) -> String {
value.escape(quote=false)
}
///|
pub fn Token::moonbit_const(self : Token) -> String {
"pub let \{self.name.to_identifier()} : String = \"\{self.value.escape(quote=false)}\""
}
///|
pub fn Token::markdown_row(self : Token) -> String {
"| `\{markdown_escape(self.name)}` | \{self.kind.label()} | `\{markdown_escape(self.value)}` | \{markdown_escape(self.description)} |"
}
///|
fn markdown_escape(value : String) -> String {
value
.replace(old="|", new="\\|")
.replace(old="\n", new=" ")
.replace(old="\r", new=" ")
}
///|
pub fn to_css(tokens : Array[Token]) -> String {
let rows = [ for token in tokens => " \{token.css_variable()}" ]
":root {\n\{rows.join("\n")}\n}\n"
}
///|
pub fn to_json(tokens : Array[Token]) -> String {
let rows = [ for token in tokens => " \{token.json_object()}" ]
"[\n\{rows.join(",\n")}\n]\n"
}
///|
pub fn to_moonbit_constants(tokens : Array[Token]) -> String {
let rows = [ for token in tokens => token.moonbit_const() ]
"\{rows.join("\n")}\n"
}
///|
pub fn to_markdown_table(tokens : Array[Token]) -> String {
let header = "| Name | Kind | Value | Description |\n| --- | --- | --- | --- |"
let rows = [ for token in tokens => token.markdown_row() ]
"\{header}\n\{rows.join("\n")}\n"
}
///|
pub fn sample_tokens() -> Array[Token] {
[
Token::color("brand-primary", "#4f46e5", description="Primary action color"),
Token::color("brand-success", "#16a34a", description="Positive state color"),
Token::font_size("font-body", "16px", description="Default body text"),
Token::font_size("font-title", "28px", description="Section title text"),
Token::spacing("space-2", "8px", description="Compact gap"),
Token::spacing("space-4", "16px", description="Default gap"),
Token::radius("radius-card", "8px", description="Standard card corner"),
Token::shadow(
"shadow-panel",
"0 8px 24px rgba(15, 23, 42, 0.12)",
description="Raised panel shadow",
),
]
}
///|
fn String::to_identifier(self : String) -> String {
let chars = [
for c in self => if c == '-' || c == '/' || c == '.' { "_" } else { "\{c}" }
]
chars.join("")
}