use serde_json::{Map, Value, json};
use super::Model;
const SCHEMA: &str =
"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json";
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 repository = Map::new();
let mut includes: Vec<Value> = Vec::new();
repository.insert("comments".into(), comments());
includes.push(json!({ "include": "#comments" }));
repository.insert("strings".into(), strings());
includes.push(json!({ "include": "#strings" }));
for (i, group) in model.groups.iter().enumerate() {
let key = format!("tokens_{i}");
repository.insert(
key.clone(),
json!({ "name": group.scope.textmate(), "match": group.regex_oniguruma() }),
);
includes.push(json!({ "include": format!("#{key}") }));
}
repository.insert(
"numbers".into(),
single("constant.numeric.eventb", "\\b[0-9]+\\b"),
);
includes.push(json!({ "include": "#numbers" }));
repository.insert(
"labels".into(),
single("entity.name.tag.eventb", "@[A-Za-z0-9_]+"),
);
includes.push(json!({ "include": "#labels" }));
repository.insert(
"identifiers".into(),
single("variable.other.eventb", "[a-zA-Z_][a-zA-Z0-9_]*'?"),
);
includes.push(json!({ "include": "#identifiers" }));
let doc = json!({
"$schema": SCHEMA,
"name": "Event-B",
"scopeName": "source.eventb",
"information_for_contributors": [NOTICE],
"patterns": includes,
"repository": Value::Object(repository),
});
let mut out = serde_json::to_string_pretty(&doc).expect("serializable grammar");
out.push('\n');
out
}
fn single(scope: &str, regex: &str) -> Value {
json!({ "patterns": [ { "name": scope, "match": regex } ] })
}
fn comments() -> Value {
json!({
"patterns": [
{ "name": "comment.line.double-slash.eventb", "match": "//.*$" },
{ "name": "comment.block.eventb", "begin": "/\\*", "end": "\\*/" }
]
})
}
fn strings() -> Value {
json!({
"patterns": [
{
"name": "string.quoted.double.eventb",
"begin": "\"",
"end": "\"",
"patterns": [
{ "name": "constant.character.escape.eventb", "match": "\\\\." }
]
}
]
})
}