![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
В старые добрые времена, когда людям нужно было выразить что-нибудь в компьютерном файле, они изобретали новый синтаксис. Потом в чью-то умную голову пришла мысль подсвечивать элементы синтаксиса в текстовых редакторах.
Потом люди придумали универсальные языки разметки — XML, JSON и YAML — с помощью которых можно выразить всё что угодно. Поэтому теперь вместо синтаксиса часто изобретают схему.
Однако, что у нас с их подсветкой? Возьмём, к примеру, кусочек мета-схемы JSON Schema Draft 04 (который примечателен тем, что описывает свою собственную структуру):
{ "$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"$schema": {"type": "string", "format": "url"},
"$ref": {"type": "string", "format": "url"},
"type": {"type": "tsring", "enum": [
"null", "boolean", "integer", "number",
"string", "array", "object"]},
"format": {"type": "string"},
"properties": {"type": "object", "aditionalProperties": {"$ref": "#"}},
"additionalProperties": {"$ref": "#"},
"enum": {"type": "array", "items": {"$ref": "#"}},
"items": {"$ref": "#"}
}
}
Одни сплошные «строковые литералы». В лучшем случае — ключи объектов одним цветом, остальные строки другим. На первом плане — синтаксис самого JSON; а более высокоуровневый синтаксис, построенный поверх JSON’а, остаётся нераскрашенным и непроверяемым на глаз. Найдите две опечатки в примере выше.
Надо — имея на руках схему, валидировать об неё документ и подсвечивать по-разному:
- ключи, явно допустимые в текущем контексте;
- ключи, допустимые по шаблону или по принципу «всё, что не запрещено»;
- ключи, недопустимые в текущем контексте, и примитивные значения, не соответствующие схеме;
- значения, явно соответствующие заданным ограничениям;
- все остальные строки.
{ "$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"$schema": {"type": "string", "format": "url"},
"$ref": {"type": "string", "format": "url"},
"type": {"type": "tsring", "enum": [
"null", "boolean", "integer", "number",
"string", "array", "object"]},
"format": {"type": "string"},
"properties": {"type": "object", "aditionalProperties": {"$ref": "#"}},
"additionalProperties": {"$ref": "#"},
"enum": {"type": "array", "items": {"$ref": "#"}},
"items": {"$ref": "#"}
}
}