From 905897b3c4f37e2ec5c110e32358db731b46c0b7 Mon Sep 17 00:00:00 2001 From: Timothy DeHerrera Date: Sat, 31 Jan 2026 17:24:27 -0700 Subject: [PATCH] fix(highlight): complete markdown syntax highlighting with injections Fix markdown code block highlighting to properly support both markdown structure (headings, frontmatter) and language injection (rust, bash). The key fix uses `#set! injection.include-children` in the injection query to override tree-sitter-md's internal tokenization, enabling proper highlighting of embedded languages within code fences. Changes: - Use crate's HIGHLIGHT_QUERY_BLOCK for base markdown highlighting - Add custom injection query with include-children directive - Add YAML/TOML frontmatter and HTML block injection rules - Add text.* highlight names (title, literal, uri, reference) - Add string.escape highlight name - Add CSS styles for new highlight classes - Remove unused custom md-highlights.scm --- docs/static/style.css | 23 +++++++++++++++++++++++ queries/md-highlights.scm | 35 ----------------------------------- queries/md-injections.scm | 19 ++++++++++++++++++- src/highlight.rs | 12 +++++++++++- 4 files changed, 52 insertions(+), 37 deletions(-) delete mode 100644 queries/md-highlights.scm diff --git a/docs/static/style.css b/docs/static/style.css index bed9928..772fe9c 100644 --- a/docs/static/style.css +++ b/docs/static/style.css @@ -208,6 +208,29 @@ pre code { color: #ff79c6; } +/* Markdown-specific text highlighting */ +.hl-text-title { + color: #ff79c6; + font-weight: bold; +} + +.hl-text-literal { + color: #8be9fd; +} + +.hl-text-uri { + color: #8be9fd; + text-decoration: underline; +} + +.hl-text-reference { + color: #bd93f9; +} + +.hl-string-escape { + color: #ffb86c; +} + /* Section navigation */ .section-nav { display: flex; diff --git a/queries/md-highlights.scm b/queries/md-highlights.scm deleted file mode 100644 index a1d693c..0000000 --- a/queries/md-highlights.scm +++ /dev/null @@ -1,35 +0,0 @@ -; Minimal markdown block highlighting - only capture outside code blocks -; Removed all captures that could match inside code_fence_content - -(atx_heading (inline) @text.title) -(setext_heading (paragraph) @text.title) - -[ - (atx_h1_marker) - (atx_h2_marker) - (atx_h3_marker) - (atx_h4_marker) - (atx_h5_marker) - (atx_h6_marker) - (setext_h1_underline) - (setext_h2_underline) -] @punctuation.special - -(fenced_code_block_delimiter) @punctuation.delimiter -(info_string (language) @string) - -(link_title) @string -(link_destination) @text.uri -(link_label) @text.reference - -[ - (list_marker_plus) - (list_marker_minus) - (list_marker_star) - (list_marker_dot) - (list_marker_parenthesis) - (thematic_break) -] @punctuation.special - -(block_quote_marker) @punctuation.special -(backslash_escape) @string.escape diff --git a/queries/md-injections.scm b/queries/md-injections.scm index b819b84..0f675a6 100644 --- a/queries/md-injections.scm +++ b/queries/md-injections.scm @@ -1,7 +1,24 @@ -; Markdown injection queries - testing include-children directive +; Markdown injection queries with include-children directive +; Enables proper highlighting of embedded languages in code blocks and frontmatter +; Fenced code blocks - inject language specified in info string (fenced_code_block (info_string (language) @injection.language) (code_fence_content) @injection.content (#set! injection.include-children)) + +; YAML frontmatter (--- delimited at start of document) +((minus_metadata) @injection.content + (#set! injection.language "yaml") + (#set! injection.include-children)) + +; TOML frontmatter (+++ delimited) +((plus_metadata) @injection.content + (#set! injection.language "toml") + (#set! injection.include-children)) + +; HTML blocks +((html_block) @injection.content + (#set! injection.language "html") + (#set! injection.include-children)) diff --git a/src/highlight.rs b/src/highlight.rs index 125f97d..cddbc26 100644 --- a/src/highlight.rs +++ b/src/highlight.rs @@ -25,9 +25,14 @@ const HIGHLIGHT_NAMES: &[&str] = &[ "punctuation.delimiter", "punctuation.special", "string", + "string.escape", "string.special", "string.special.path", "string.special.uri", + "text.literal", + "text.reference", + "text.title", + "text.uri", "type", "type.builtin", "variable", @@ -57,9 +62,14 @@ const HTML_ATTRS: &[&[u8]] = &[ b" class=\"hl-punctuation-delimiter\"", b" class=\"hl-punctuation-special\"", b" class=\"hl-string\"", + b" class=\"hl-string-escape\"", b" class=\"hl-string-special\"", b" class=\"hl-string-special-path\"", b" class=\"hl-string-special-uri\"", + b" class=\"hl-text-literal\"", + b" class=\"hl-text-reference\"", + b" class=\"hl-text-title\"", + b" class=\"hl-text-uri\"", b" class=\"hl-type\"", b" class=\"hl-type-builtin\"", b" class=\"hl-variable\"", @@ -189,7 +199,7 @@ static MARKDOWN_CONFIG: LazyLock = LazyLock::new(|| { make_config( tree_sitter_md::LANGUAGE.into(), "markdown", - include_str!("../queries/md-highlights.scm"), + tree_sitter_md::HIGHLIGHT_QUERY_BLOCK, include_str!("../queries/md-injections.scm"), ) });