use super::Model;
const NOTICE: &str =
"Generated by `rossi gen-grammars` from the canonical token tables. Do not edit by hand.";
pub fn render(model: &Model) -> String {
let mut out = String::new();
out.push_str("%YAML 1.2\n---\n");
out.push_str(&format!("# {NOTICE}\n"));
out.push_str("name: Event-B\n");
out.push_str("file_extensions:\n - eventb\n");
out.push_str("scope: source.eventb\n\n");
out.push_str("contexts:\n");
out.push_str(" main:\n");
rule(&mut out, "//.*$", "comment.line.double-slash.eventb");
push_match(
&mut out,
"/\\*",
Some("punctuation.definition.comment.eventb"),
Some("block_comment"),
);
push_match(
&mut out,
"\"",
Some("punctuation.definition.string.begin.eventb"),
Some("string"),
);
for group in &model.groups {
rule(&mut out, &group.regex_oniguruma(), group.scope.textmate());
}
rule(&mut out, "\\b[0-9]+\\b", "constant.numeric.eventb");
rule(&mut out, "@[A-Za-z0-9_]+", "entity.name.tag.eventb");
rule(
&mut out,
"[a-zA-Z_][a-zA-Z0-9_]*'?",
"variable.other.eventb",
);
out.push_str(" block_comment:\n");
out.push_str(" - meta_scope: comment.block.eventb\n");
push_pop(&mut out, "\\*/");
out.push_str(" string:\n");
out.push_str(" - meta_scope: string.quoted.double.eventb\n");
rule(&mut out, "\\\\.", "constant.character.escape.eventb");
push_pop(&mut out, "\"");
out
}
fn rule(out: &mut String, regex: &str, scope: &str) {
out.push_str(&format!(" - match: {}\n", squote(regex)));
out.push_str(&format!(" scope: {scope}\n"));
}
fn push_match(out: &mut String, regex: &str, scope: Option<&str>, push: Option<&str>) {
out.push_str(&format!(" - match: {}\n", squote(regex)));
if let Some(s) = scope {
out.push_str(&format!(" scope: {s}\n"));
}
if let Some(p) = push {
out.push_str(&format!(" push: {p}\n"));
}
}
fn push_pop(out: &mut String, regex: &str) {
out.push_str(&format!(" - match: {}\n", squote(regex)));
out.push_str(" pop: true\n");
}
fn squote(s: &str) -> String {
format!("'{}'", s.replace('\'', "''"))
}