From 2e4649e5f9e0cae0533e9f674634973a112f77d7 Mon Sep 17 00:00:00 2001 From: Malay Satapathy Date: Fri, 16 Oct 2026 00:33:50 +0530 Subject: [PATCH] Fix #209: Syntax Highlighting for GitHub --- integration/textmate/BUILD | 25 +++ integration/textmate/README.md | 10 ++ integration/textmate/emboss.tmLanguage.json | 160 ++++++++++++++++++++ integration/textmate/textmate_test.py | 57 +++++++ 4 files changed, 252 insertions(+) create mode 100644 integration/textmate/BUILD create mode 100644 integration/textmate/README.md create mode 100644 integration/textmate/emboss.tmLanguage.json create mode 100644 integration/textmate/textmate_test.py diff --git a/integration/textmate/BUILD b/integration/textmate/BUILD new file mode 100644 index 00000000..80b154d0 --- /dev/null +++ b/integration/textmate/BUILD @@ -0,0 +1,25 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +load("@rules_python//python:py_test.bzl", "py_test") + +package(default_visibility = ["//visibility:public"]) + +exports_files(["emboss.tmLanguage.json"]) + +py_test( + name = "textmate_test", + srcs = ["textmate_test.py"], + data = ["emboss.tmLanguage.json"], +) diff --git a/integration/textmate/README.md b/integration/textmate/README.md new file mode 100644 index 00000000..9df7f3a7 --- /dev/null +++ b/integration/textmate/README.md @@ -0,0 +1,10 @@ +# TextMate Grammar for Emboss + +This directory contains the TextMate grammar (`emboss.tmLanguage.json`) for the Emboss language. + +It provides syntax highlighting for tools that support TextMate grammars, such as: +- VS Code (via extensions) +- GitHub (via Linguist) +- Sublime Text + +To add Emboss syntax highlighting to GitHub, this file can be used by GitHub's [Linguist](https://github.com/github-linguist/linguist) library. diff --git a/integration/textmate/emboss.tmLanguage.json b/integration/textmate/emboss.tmLanguage.json new file mode 100644 index 00000000..e5b50771 --- /dev/null +++ b/integration/textmate/emboss.tmLanguage.json @@ -0,0 +1,160 @@ +{ + "name": "Emboss", + "scopeName": "source.emboss", + "fileTypes": [ + "emb" + ], + "patterns": [ + { + "include": "#strings" + }, + { + "include": "#comments" + }, + { + "include": "#doc-comments" + }, + { + "include": "#keywords" + }, + { + "include": "#builtins" + }, + { + "include": "#types" + }, + { + "include": "#constants" + }, + { + "include": "#numbers" + }, + { + "include": "#operators" + }, + { + "include": "#punctuation" + } + ], + "repository": { + "comments": { + "patterns": [ + { + "name": "comment.line.number-sign.emboss", + "match": "#.*$" + } + ] + }, + "doc-comments": { + "patterns": [ + { + "name": "comment.line.double-dash.documentation.emboss", + "match": "--(?: .*|)$" + }, + { + "name": "invalid.illegal.documentation.emboss", + "match": "--[^ ].*$" + } + ] + }, + "strings": { + "patterns": [ + { + "name": "string.quoted.double.emboss", + "begin": "\"", + "end": "\"", + "patterns": [ + { + "name": "constant.character.escape.emboss", + "match": "\\\\[n\\\\\"]" + } + ] + } + ] + }, + "keywords": { + "patterns": [ + { + "name": "keyword.control.emboss", + "match": "\\b(struct|enum|bits|external|import|as|if|let)\\b" + }, + { + "name": "constant.language.emboss", + "match": "\\b(true|false)\\b" + } + ] + }, + "builtins": { + "patterns": [ + { + "name": "variable.language.emboss", + "match": "(?=|<|>|&&|\\|\\||\\+|-|\\*|\\?|=" + } + ] + }, + "punctuation": { + "patterns": [ + { + "name": "punctuation.separator.emboss", + "match": "[:,]" + }, + { + "name": "punctuation.section.brackets.emboss", + "match": "\\[|\\]" + }, + { + "name": "punctuation.section.parens.emboss", + "match": "\\(|\\)" + }, + { + "name": "punctuation.accessor.emboss", + "match": "\\." + } + ] + } + } +} diff --git a/integration/textmate/textmate_test.py b/integration/textmate/textmate_test.py new file mode 100644 index 00000000..06c91976 --- /dev/null +++ b/integration/textmate/textmate_test.py @@ -0,0 +1,57 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import re +import unittest + + +class TextmateTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + json_path = os.path.join(os.path.dirname(__file__), "emboss.tmLanguage.json") + with open(json_path, encoding="utf-8") as f: + cls.data = json.load(f) + + def test_valid_json(self): + self.assertEqual(self.data.get("name"), "Emboss") + self.assertEqual(self.data.get("scopeName"), "source.emboss") + self.assertIn("emb", self.data.get("fileTypes", [])) + + def test_all_includes_exist_and_regexes_compile(self): + repository = self.data.get("repository", {}) + + def check_pattern(pattern): + if "include" in pattern: + include = pattern["include"] + if include.startswith("#"): + self.assertIn(include[1:], repository) + for regex_key in ("match", "begin", "end"): + if regex_key in pattern: + re.compile(pattern[regex_key]) + if "patterns" in pattern: + for p in pattern["patterns"]: + check_pattern(p) + + if "patterns" in self.data: + for p in self.data["patterns"]: + check_pattern(p) + for val in repository.values(): + check_pattern(val) + + +if __name__ == "__main__": + unittest.main()