{
"$schema": "https://tree-sitter.github.io/tree-sitter/assets/schemas/grammar.schema.json",
"name": "haml",
"rules": {
"source_file": {
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "doctype"
},
{
"type": "SYMBOL",
"name": "tag"
},
{
"type": "SYMBOL",
"name": "comment"
},
{
"type": "SYMBOL",
"name": "ruby_block_output"
},
{
"type": "SYMBOL",
"name": "ruby_block_run"
},
{
"type": "SYMBOL",
"name": "ruby_interpolation"
},
{
"type": "SYMBOL",
"name": "filter"
}
]
}
},
"doctype": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "!!!"
},
{
"type": "SYMBOL",
"name": "_text"
}
]
},
"tag": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "tag_name"
},
{
"type": "SYMBOL",
"name": "id"
},
{
"type": "SYMBOL",
"name": "class"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "REPEAT1",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "tag_name"
},
{
"type": "SYMBOL",
"name": "id"
},
{
"type": "SYMBOL",
"name": "class"
}
]
}
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "attributes"
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "ALIAS",
"content": {
"type": "STRING",
"value": "/"
},
"named": true,
"value": "self_close_slash"
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "ruby_block_output"
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": " "
},
{
"type": "SYMBOL",
"name": "verbatim_string"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_newline"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_children"
},
{
"type": "BLANK"
}
]
}
]
}
]
}
]
},
"_children": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_indent"
},
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "_children_choice"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_dedent"
},
{
"type": "BLANK"
}
]
}
]
}
},
"_children_choice": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "tag"
},
{
"type": "SYMBOL",
"name": "ruby_block_output"
},
{
"type": "SYMBOL",
"name": "ruby_block_run"
},
{
"type": "SYMBOL",
"name": "ruby_interpolation"
},
{
"type": "SYMBOL",
"name": "filter"
},
{
"type": "SYMBOL",
"name": "verbatim_string"
},
{
"type": "SYMBOL",
"name": "comment"
},
{
"type": "SYMBOL",
"name": "_newline"
}
]
},
"html_attributes": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "attribute"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": " "
},
{
"type": "BLANK"
}
]
}
]
}
},
{
"type": "STRING",
"value": ")"
}
]
},
"attributes": {
"type": "REPEAT1",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "html_attributes"
},
{
"type": "SYMBOL",
"name": "ruby_attributes"
}
]
}
},
"tag_name": {
"type": "PATTERN",
"value": "%[-:\\w]+"
},
"class_or_id_value": {
"type": "PATTERN",
"value": "[-:_a-zA-Z0-9\\@]+"
},
"id": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "#"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "class_or_id_value"
},
"named": false,
"value": "id"
}
]
},
"class": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "."
},
{
"type": "SYMBOL",
"name": "class_name"
}
]
},
"class_name": {
"type": "PATTERN",
"value": "[-:_a-zA-Z0-9\\@]+"
},
"comment": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_comment_line"
},
{
"type": "SYMBOL",
"name": "_comment_block"
}
]
},
"_comment_line": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "/"
},
{
"type": "STRING",
"value": "-#"
}
]
},
{
"type": "SYMBOL",
"name": "_text"
},
{
"type": "SYMBOL",
"name": "_newline"
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_indent"
},
{
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_text"
},
{
"type": "SYMBOL",
"name": "_newline"
}
]
}
},
{
"type": "SYMBOL",
"name": "_dedent"
}
]
},
{
"type": "BLANK"
}
]
}
]
},
"_comment_block": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "/"
},
{
"type": "STRING",
"value": "-#"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "comment_condition"
},
{
"type": "BLANK"
}
]
},
{
"type": "SYMBOL",
"name": "_newline"
},
{
"type": "SYMBOL",
"name": "_indent"
},
{
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_text"
},
{
"type": "SYMBOL",
"name": "_newline"
}
]
}
},
{
"type": "SYMBOL",
"name": "_dedent"
}
]
},
"comment_condition": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "["
},
{
"type": "SYMBOL",
"name": "_text"
},
{
"type": "STRING",
"value": "]"
}
]
},
"attribute_name": {
"type": "PATTERN",
"value": "#?[\\w@\\-:]+"
},
"attribute": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "attribute_name"
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "="
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "quoted_attribute_value"
},
{
"type": "SYMBOL",
"name": "ruby_value_ref"
}
]
}
]
},
{
"type": "BLANK"
}
]
}
]
},
"quoted_attribute_value": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "'"
},
{
"type": "REPEAT1",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "ruby_interpolation"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_html_identifier"
},
"named": true,
"value": "attribute_value"
}
]
}
},
{
"type": "STRING",
"value": "'"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "\""
},
{
"type": "REPEAT1",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "ruby_interpolation"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_html_identifier"
},
"named": true,
"value": "attribute_value"
}
]
}
},
{
"type": "STRING",
"value": "\""
}
]
}
]
},
"_text": {
"type": "PATTERN",
"value": "[^\\n]*"
},
"verbatim_string": {
"type": "TOKEN",
"content": {
"type": "PREC",
"value": -1,
"content": {
"type": "PATTERN",
"value": "[^\\n]+"
}
}
},
"ruby_block_output": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "!"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "="
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_text"
},
"named": true,
"value": "ruby_code"
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_newline"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_children"
},
{
"type": "BLANK"
}
]
}
]
}
]
},
"ruby_block_run": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "-"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_text"
},
"named": true,
"value": "ruby_code"
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_newline"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_children"
},
{
"type": "BLANK"
}
]
}
]
}
]
},
"ruby_interpolation": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "#"
},
{
"type": "SYMBOL",
"name": "ruby_expression"
}
]
},
"ruby_expression": {
"type": "PATTERN",
"value": "\\{[^}]*\\}"
},
"ruby_class_variable": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "@@"
},
{
"type": "PATTERN",
"value": "[a-zA-Z0-9_]+"
}
]
},
"ruby_instance_variable": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "@"
},
{
"type": "PATTERN",
"value": "[_a-zA-Z0-9]+"
}
]
},
"ruby_global_variable": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "$"
},
{
"type": "PATTERN",
"value": "[a-zA-Z0-9_]+"
}
]
},
"ruby_constant": {
"type": "PATTERN",
"value": "[A-Z][a-zA-Z0-9_]+"
},
"ruby_local_variable": {
"type": "PATTERN",
"value": "[a-z_][a-zA-Z0-9_]+"
},
"ruby_value_ref": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "ruby_local_variable"
},
{
"type": "SYMBOL",
"name": "ruby_class_variable"
},
{
"type": "SYMBOL",
"name": "ruby_instance_variable"
},
{
"type": "SYMBOL",
"name": "ruby_global_variable"
},
{
"type": "SYMBOL",
"name": "ruby_constant"
}
]
},
"_html_identifier": {
"type": "PATTERN",
"value": "[-:\\w/.]+"
},
"filter": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ":"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_text"
},
"named": true,
"value": "filter_name"
},
{
"type": "SYMBOL",
"name": "_newline"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "filter_body"
},
{
"type": "BLANK"
}
]
}
]
},
"filter_body": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_indent"
},
{
"type": "REPEAT1",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_text"
},
{
"type": "SYMBOL",
"name": "_newline"
}
]
},
{
"type": "SYMBOL",
"name": "_newline"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_dedent"
},
{
"type": "BLANK"
}
]
}
]
}
}
},
"extras": [
{
"type": "PATTERN",
"value": "\\s"
}
],
"conflicts": [],
"precedences": [],
"externals": [
{
"type": "SYMBOL",
"name": "_newline"
},
{
"type": "SYMBOL",
"name": "_indent"
},
{
"type": "SYMBOL",
"name": "_dedent"
},
{
"type": "SYMBOL",
"name": "ruby_attributes"
}
],
"inline": [],
"supertypes": []
}