///|
pub(all) enum OutputFormat {
Css
CssMinified
Json
JsonLines
MoonBit
Markdown
} derive(Debug, Eq)
///|
pub fn OutputFormat::label(self : OutputFormat) -> String {
match self {
Css => "css"
CssMinified => "css-minified"
Json => "json"
JsonLines => "json-lines"
MoonBit => "moonbit"
Markdown => "markdown"
}
}
///|
pub(all) struct BuildOptions {
canonicalize : Bool
resolve_aliases : Bool
output_format : OutputFormat
} derive(Debug, Eq)
///|
pub fn BuildOptions::default() -> BuildOptions {
{ canonicalize: true, resolve_aliases: false, output_format: Css }
}
///|
pub fn BuildOptions::with_format(
self : BuildOptions,
output_format : OutputFormat,
) -> BuildOptions {
{ ..self, output_format, }
}
///|
pub fn BuildOptions::with_alias_resolution(
self : BuildOptions,
enabled : Bool,
) -> BuildOptions {
{ ..self, resolve_aliases: enabled }
}
///|
pub fn BuildOptions::without_canonicalization(
self : BuildOptions,
) -> BuildOptions {
{ ..self, canonicalize: false }
}
///|
pub struct BuildResult {
tokens : Array[Token]
parse_problems : Array[ParseProblem]
token_problems : Array[TokenProblem]
alias_problems : Array[String]
output : String
format : OutputFormat
} derive(Debug, Eq)
///|
pub fn BuildResult::tokens(self : BuildResult) -> Array[Token] {
self.tokens
}
///|
pub fn BuildResult::parse_problems(self : BuildResult) -> Array[ParseProblem] {
self.parse_problems
}
///|
pub fn BuildResult::token_problems(self : BuildResult) -> Array[TokenProblem] {
self.token_problems
}
///|
pub fn BuildResult::alias_problems(self : BuildResult) -> Array[String] {
self.alias_problems
}
///|
pub fn BuildResult::output(self : BuildResult) -> String {
self.output
}
///|
pub fn BuildResult::format(self : BuildResult) -> OutputFormat {
self.format
}
///|
pub fn BuildResult::ok(self : BuildResult) -> Bool {
self.parse_problems.length() == 0 &&
self.token_problems.length() == 0 &&
self.alias_problems.length() == 0
}
///|
pub fn BuildResult::summary(self : BuildResult) -> String {
"tokens=\{self.tokens.length()}, parse=\{self.parse_problems.length()}, token=\{self.token_problems.length()}, aliases=\{self.alias_problems.length()}, format=\{self.format.label()}"
}
///|
pub fn BuildResult::diagnostics(self : BuildResult) -> String {
let lines : Array[String] = []
for problem in self.parse_problems {
lines.push("parse: \{problem.message()}")
}
for problem in self.token_problems {
lines.push("token: \{problem.message()}")
}
for problem in self.alias_problems {
lines.push("alias: \{problem}")
}
lines.join("\n")
}
///|
pub fn build_tokens(input : String, options~ : BuildOptions) -> BuildResult {
let parsed = parse_tokens(input)
let parsed_tokens = if options.canonicalize {
canonical_tokens(parsed.tokens)
} else {
parsed.tokens
}
let aliases = alias_problems(parsed_tokens)
let output_tokens = if options.resolve_aliases {
resolve_aliases(parsed_tokens)
} else {
parsed_tokens
}
let output = render_output(output_tokens, options.output_format)
{
tokens: output_tokens,
parse_problems: parsed.problems,
token_problems: validate_all(output_tokens),
alias_problems: aliases,
output,
format: options.output_format,
}
}
///|
pub fn build_text(input : String, format~ : OutputFormat) -> BuildResult {
build_tokens(input, options=BuildOptions::default().with_format(format))
}
///|
pub fn render_output(tokens : Array[Token], format : OutputFormat) -> String {
match format {
Css => to_css(tokens)
CssMinified => to_css_minified(tokens)
Json => to_json(tokens)
JsonLines => to_json_lines(tokens)
MoonBit => to_moonbit_constants(tokens)
Markdown => to_markdown_sorted(tokens)
}
}
///|
fn alias_problems(tokens : Array[Token]) -> Array[String] {
let problems : Array[String] = []
for problem in unresolved_aliases(tokens) {
problems.push(problem)
}
for problem in alias_cycles(tokens) {
problems.push(problem)
}
problems
}