From 2d2c8761ccd07a6e596f0b73758963cf21dc9ccf Mon Sep 17 00:00:00 2001 From: "Gabriel Silva (Gabe)" <192261+gabeidx@users.noreply.github.com> Date: Wed, 16 Oct 2024 15:10:36 +0200 Subject: [PATCH] feat: add syntax highlighting for `.d2` and markdown (#1) --- .gitignore | 3 ++ examples/basic.d2 | 4 +++ examples/chess.d2 | 21 +++++++++++++ examples/class.d2 | 30 ++++++++++++++++++ examples/code.d2 | 17 +++++++++++ examples/containers.d2 | 8 +++++ examples/icons.d2 | 41 +++++++++++++++++++++++++ examples/latex.d2 | 6 ++++ examples/markdown.md | 10 ++++++ examples/sequence.d2 | 5 +++ examples/shapes.d2 | 19 ++++++++++++ examples/state.d2 | 16 ++++++++++ examples/tables.d2 | 30 ++++++++++++++++++ examples/text.d2 | 11 +++++++ examples/trees.d2 | 13 ++++++++ examples/wiiu.d2 | 47 ++++++++++++++++++++++++++++ languages/d2/highlights.scm | 61 +++++++++++++++++++++++++++++++++++++ languages/d2/indents.scm | 19 ++++++++++++ languages/d2/injections.scm | 48 +++++++++++++++++++++++++++++ 19 files changed, 409 insertions(+) create mode 100644 examples/basic.d2 create mode 100644 examples/chess.d2 create mode 100644 examples/class.d2 create mode 100644 examples/code.d2 create mode 100644 examples/containers.d2 create mode 100644 examples/icons.d2 create mode 100644 examples/latex.d2 create mode 100644 examples/markdown.md create mode 100644 examples/sequence.d2 create mode 100644 examples/shapes.d2 create mode 100644 examples/state.d2 create mode 100644 examples/tables.d2 create mode 100644 examples/text.d2 create mode 100644 examples/trees.d2 create mode 100644 examples/wiiu.d2 create mode 100644 languages/d2/highlights.scm create mode 100644 languages/d2/indents.scm create mode 100644 languages/d2/injections.scm diff --git a/.gitignore b/.gitignore index 8fdea6f..bf3703f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +*.wasm +grammars/ + ### JetBrains ### # User-specific stuff .idea diff --git a/examples/basic.d2 b/examples/basic.d2 new file mode 100644 index 0000000..166cd3e --- /dev/null +++ b/examples/basic.d2 @@ -0,0 +1,4 @@ +hello +w: world + +hello -> w: there diff --git a/examples/chess.d2 b/examples/chess.d2 new file mode 100644 index 0000000..8c2cedd --- /dev/null +++ b/examples/chess.d2 @@ -0,0 +1,21 @@ +# Actors +hans: Hans Niemann + +defendants: { + mc: Magnus Carlsen + playmagnus: Play Magnus Group + chesscom: Chess.com + naka: Hikaru Nakamura + + mc -> playmagnus: Owns majority + playmagnus <-> chesscom: Merger talks + chesscom -> naka: Sponsoring +} + +# Accusations +hans -> defendants: 'sueing for $100M' + +# Offense +defendants.naka -> hans: Accused of cheating on his stream +defendants.mc -> hans: Lost then withdrew with accusations +defendants.chesscom -> hans: 72 page report of cheating diff --git a/examples/class.d2 b/examples/class.d2 new file mode 100644 index 0000000..45f15e7 --- /dev/null +++ b/examples/class.d2 @@ -0,0 +1,30 @@ +Duck: { + shape: class + beakColor: String + swim(): void + quack(): void +} + +Fish: { + shape: class + -sizeInFeet: int + -canEat(): boolean +} + +Zebra: { + shape: class + is_wild: bool + run(): void +} + +Animal: { + shape: class + age: int + gender: String + isMammal(): bool + mate(): void +} + +Duck -> Animal +Fish -> Animal +Zebra -> Animal diff --git a/examples/code.d2 b/examples/code.d2 new file mode 100644 index 0000000..f506cd3 --- /dev/null +++ b/examples/code.d2 @@ -0,0 +1,17 @@ +hash: |go + // RegisterHash registers a function that returns a new instance of the given + // hash function. This is intended to be called from the init function in + // packages that implement hash functions. + func RegisterHash(h Hash, f func() hash.Hash) { + if h >= maxHash { + panic("crypto: RegisterHash of unknown hash function") + } + hashes[h] = f + } +| +hello world: |python + def hello(): + print "world" +| +x -> hash -> y +x -> hello world diff --git a/examples/containers.d2 b/examples/containers.d2 new file mode 100644 index 0000000..5015518 --- /dev/null +++ b/examples/containers.d2 @@ -0,0 +1,8 @@ +parent: { + childB: { + grandchild + } + childA -> childB.grandchild +} + +foo -> parent.childA diff --git a/examples/icons.d2 b/examples/icons.d2 new file mode 100644 index 0000000..cbbca81 --- /dev/null +++ b/examples/icons.d2 @@ -0,0 +1,41 @@ +aws: { + db: "" { + icon: https://icons.terrastruct.com/azure/Databases%20Service%20Color/Azure%20Database%20for%20PostgreSQL%20servers.svg + shape: image + } + + cache: "" { + icon: https://icons.terrastruct.com/azure/_Companies/Azure%20Cache%20Redis%20Product%20icon.svg + shape: image + } + + ec2: "" { + icon: https://icons.terrastruct.com/aws/_Group%20Icons/EC2-instance-container_light-bg.svg + shape: image + } + + ec2 <-> db: get persisted data + ec2 <-> cache: get temporal data +} + +gcloud: { + db: "" { + icon: https://icons.terrastruct.com/azure/Databases%20Service%20Color/Azure%20Database%20for%20PostgreSQL%20servers.svg + shape: image + } +} + +aws.db -> gcloud.db: backup + +dev: "" { + icon: https://icons.terrastruct.com/essentials/005-programmer.svg + shape: image +} + +github: "" { + icon: https://icons.terrastruct.com/dev/github.svg + shape: image +} + +dev -> aws.ec2: ssh +dev -> github: version control diff --git a/examples/latex.d2 b/examples/latex.d2 new file mode 100644 index 0000000..cee30ea --- /dev/null +++ b/examples/latex.d2 @@ -0,0 +1,6 @@ +plankton -> formula: will steal +formula: { + equation: |latex + \\lim_{h \\rightarrow 0 } \\frac{f(x+h)-f(x)}{h} + | +} diff --git a/examples/markdown.md b/examples/markdown.md new file mode 100644 index 0000000..e993e36 --- /dev/null +++ b/examples/markdown.md @@ -0,0 +1,10 @@ +This is a markdown example of the D2 code block highlighting. + +```d2 +Duck: { + shape: class + beakColor: String + swim(): void + quack(): void +} +``` diff --git a/examples/sequence.d2 b/examples/sequence.d2 new file mode 100644 index 0000000..e7ed6c1 --- /dev/null +++ b/examples/sequence.d2 @@ -0,0 +1,5 @@ +shape: sequence_diagram +Alice -> John: Hello John, how are you? +Alice -> John.ack: John, can you hear me? +John.ack -> Alice: Hi Alice, I can hear you! +John -> Alice: I feel great! diff --git a/examples/shapes.d2 b/examples/shapes.d2 new file mode 100644 index 0000000..4ff9832 --- /dev/null +++ b/examples/shapes.d2 @@ -0,0 +1,19 @@ +parse: { + shape: step +} +compile: { + shape: step +} +export: { + shape: step +} + +parse -> compile -> export + +doc: {shape: page} +cloud: {shape: cloud} + +doc -> cloud + +db: {shape: cylinder} +pipeline: {shape: queue} diff --git a/examples/state.d2 b/examples/state.d2 new file mode 100644 index 0000000..08ca2e0 --- /dev/null +++ b/examples/state.d2 @@ -0,0 +1,16 @@ +Start: "" { + shape: circle + width: 10 +} +End: "" { + shape: circle + width: 10 +} + +Start -> Still +Still -> End + +Still -> Moving +Moving -> Still +Moving -> Crash +Crash -> End diff --git a/examples/tables.d2 b/examples/tables.d2 new file mode 100644 index 0000000..893e291 --- /dev/null +++ b/examples/tables.d2 @@ -0,0 +1,30 @@ +car: { + shape: sql_table + + id: int {constraint: primary_key} + last_updated: timestamp with time zone + + make: string + model: string + year: int +} + +factory: { + shape: sql_table + + id: int {constraint: primary_key} + + country: string +} + +factory_car_support: { + shape: sql_table + + id: int {constraint: primary_key} + + factory: int {constraint: foreign_key} + car: int {constraint: foreign_key} +} + +factory_car_support.factory -> factory.id +factory_car_support.car -> car.id diff --git a/examples/text.d2 b/examples/text.d2 new file mode 100644 index 0000000..0690a97 --- /dev/null +++ b/examples/text.d2 @@ -0,0 +1,11 @@ +description: |md + # Hope is a good breakfast, but it is a bad supper + + - Look into my eyes and try to forget that you have a Macy's charge card! + - The **Tree of Learning** bears the noblest fruit, but noble fruit tastes bad. + + "There is nothing new under the sun, but there are lots of old things + we don't know yet." + - *Ambrose Bierce* +| +description -> x diff --git a/examples/trees.d2 b/examples/trees.d2 new file mode 100644 index 0000000..f4239a8 --- /dev/null +++ b/examples/trees.d2 @@ -0,0 +1,13 @@ +root + +root -> child A +root -> child B +root -> child C + +child A -> grand child AA +child A -> grand child AB +child A -> grand child AC +child A -> grand child AD + +child B -> grand child BA +grand child BA -> grand grand child BAA diff --git a/examples/wiiu.d2 b/examples/wiiu.d2 new file mode 100644 index 0000000..580c68b --- /dev/null +++ b/examples/wiiu.d2 @@ -0,0 +1,47 @@ +ibm: IBM "Espresso" CPU { + core0: IBM PowerPC "Broadway" Core 0 + core1: IBM PowerPC "Broadway" Core 1 + core2: IBM PowerPC "Broadway" Core 2 + + rom: 16 KB ROM + + core0 -- core2 + + rom -> core2 +} + +amd: AMD "Latte" GPU { + mem: Memory & I/O Bridge + dram: DRAM Controller + edram: 32 MB EDRAM "MEM1" + rom: 512 B SEEPROM + sata: SATA IF + exi: EXI + + gx: GX { + 3 MB 1T-SRAM + } + + radeon: AMD Radeon R7xx "GX2" + + mem -- gx + mem -- radeon + + rom -- mem + + mem -- sata + mem -- exi + + dram -- sata + dram -- exi +} + +ddr3: 2 GB DDR3 RAM "MEM2" + +amd.mem -- ddr3 +amd.dram -- ddr3 +amd.edram -- ddr3 + +ibm.core1 -- amd.mem + +amd.exi -- RTC diff --git a/languages/d2/highlights.scm b/languages/d2/highlights.scm new file mode 100644 index 0000000..b22e694 --- /dev/null +++ b/languages/d2/highlights.scm @@ -0,0 +1,61 @@ +;------------------------------------------------------------------------------- + +(container_key) @string.special +(shape_key) @variable +(attr_key) @property +(reserved) @error +(class_name) @constant + +[ + (keyword_style) + (keyword_classes) + (keyword_class) +] @keyword + +(keyword_underscore) @keyword.return + +; Literals +;------------------------------------------------------------------------------- + +(string) @string +(container_key (string (string_fragment) @string)) +(shape_key (string (string_fragment) @string)) +(escape_sequence) @string.escape +(label) @text.title +(attr_value) @string +(integer) @number +(float) @float +(boolean) @boolean + +; Comments +;------------------------------------------------------------------------------- + +[ + (language) + (line_comment) + (block_comment) +] @comment + +; Punctuation +;------------------------------------------------------------------------------- + +(arrow) @operator + +[ + (dot) + (colon) + ";" +] @punctuation.delimiter + +[ + "[" + "]" + "{" + "}" + "|" +] @punctuation.bracket + +; Special +;------------------------------------------------------------------------------- + +(ERROR) @error diff --git a/languages/d2/indents.scm b/languages/d2/indents.scm new file mode 100644 index 0000000..9c9bb65 --- /dev/null +++ b/languages/d2/indents.scm @@ -0,0 +1,19 @@ +[ + (block) + (class_block) + (class_list) + (attr_value_list) + (ERROR . "{") + (ERROR . "[") +] @indent.begin + +[ + "}" + "]" +] @indent.branch @indent.end + +[ + (line_comment) + (block_comment) + (ERROR) +] @indent.auto diff --git a/languages/d2/injections.scm b/languages/d2/injections.scm new file mode 100644 index 0000000..a99ca61 --- /dev/null +++ b/languages/d2/injections.scm @@ -0,0 +1,48 @@ +; for tree-sitter + +( + (text_block . (raw_text) @injection.content) + (#set! injection.language "markdown") +) + +(text_block + (language) @injection.language + (raw_text) @injection.content +) + +( + (line_comment) @injection.content + (#set! @injection.language "comment") +) +( + (block_comment) @injection.content + (#set! @injection.language "comment") +) + +;; ------------------------------------- +;; overwrite for nvim-treesitter +; use markdown as default +(text_block . (raw_text) @markdown) + +; add alias for markdown +(text_block + (language) @_language + (raw_text) @markdown + (#eq? @_language "md") +) + +; add alias for javascript +(text_block + (language) @_language + (raw_text) @javascript + (#eq? @_language "js") +) + +(text_block + (language) @language + (raw_text) @content +) + +(line_comment) @comment +(block_comment) @comment +