npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

tree-sitter-svg

v0.2.0

Published

SVG grammar for Tree-sitter

Readme

tree-sitter-svg

Crates.io NPM License: MIT

A Tree-sitter grammar for SVG (Scalable Vector Graphics), built against the SVG2 specification.

[!IMPORTANT] Pre-1.0 (0.x): the grammar and CST shape are still evolving and subject to breaking changes between releases.

What This Parser Does

Most XML parsers treat SVG as generic markup. This grammar parses SVG-specific structure in three layers:

  1. XML document and tag syntax
  2. Typed SVG attribute-value sub-grammars
  3. Embedded language regions (CSS, JavaScript, HTML)

Element names stay mostly generic. SVG-specific behavior is split between the grammar (grammar.js), scanner (src/scanner.c), and query files (queries/*.scm).

Element Structure

The parser uses five parsing paths for elements:

| Path | Purpose | | --------------- | ------------------------------------------ | | svg root gate | Enforces local name svg at document root | | path tags | Dedicated path-element parse path | | script tags | Raw text content (no XML parsing inside) | | style tags | Raw text content (no XML parsing inside) | | generic tags | All other elements as XML structure |

Structured Path Data

The d attribute on <path> elements is parsed into its constituent parts:

d="M 10 20 L 30 40 A 5 5 0 0 1 50 60 Z"

moveto_segment
  command: path_command (M)
  args:    path_coordinate_pair
             path_number (10)
             path_number (20)

lineto_segment
  command: path_command (L)
  args:    path_coordinate_pair
             path_number (30)
             path_number (40)

elliptical_arc_segment
  command:  path_command (A)
  radii:    path_coordinate x2
  rotation: path_rotation
  flags:    path_arc_flag, path_sweep_flag
  target:   path_coordinate_pair

closepath_segment
  command: path_command (Z)

This enables queries and tools to operate on individual path segments rather than treating d as an opaque string.

Typed Attributes

Attributes with meaningful value sub-grammars get dedicated parsing. All others are parsed as generic attribute_name/quoted_attribute_value pairs.

| Attribute | Sub-grammar | | --------------------------- | -------------------------------------------------- | | d | Full SVG path data (commands, coordinates, arcs) | | viewBox | Four-number box | | preserveAspectRatio | Optional defer, alignment, optional meet/slice | | transform and variants | Function list (matrix, translate, rotate, ...) | | points | Coordinate pair list | | style | CSS injection point | | on* events | JavaScript injection point | | href/xlink:href | IRI reference or structured data URI | | id, class | Identity tokens | | Paint attributes | url(), keywords, rgb()/hsl() decomposed | | IRI attributes | none, iri_reference, or url(...) server | | clip | rect() function with length arguments | | Length attributes | Length, percentage, or auto (24 attribute names) | | offset | Number or percentage | | opacity and variants | Number or percentage | | Number attributes | Pure numeric (pathLength, k1–k4, seed, ...) | | dx, dy | Space/comma-separated length lists | | stroke-dasharray | none, inherit, or length list | | stdDeviation, rotate, … | Space/comma-separated number lists | | dur, repeatDur | Time value, indefinite, or media | | repeatCount | Number or indefinite | | keyTimes | Semicolon-separated numbers | | keySplines | Semicolon-separated control point tuples | | enable-background | new with optional coords, or accumulate |

Language Injections

Embedded languages are injected via queries/injections.scm:

| Context | Injected Language | | -------------------------------------------- | ----------------- | | <style> element content (including CDATA) | CSS | | Typed style="..." attribute value | CSS | | Generic style="..." attribute fallback | CSS | | <script> element content (including CDATA) | JavaScript | | Event handler attribute values | JavaScript | | <foreignObject> element children | HTML | | <foreignObject> text children | HTML |

Query Files

| File | Purpose | | ----------------- | -------------------------------------------------- | | highlights.scm | Syntax highlighting captures | | injections.scm | Language injection rules (CSS, JS, HTML) | | locals.scm | Local scope/reference tracking (id ↔ href/url) | | tags.scm | Symbol navigation with @doc docstrings | | indents.scm | Auto-indentation (Helix, Neovim, Zed) | | textobjects.scm | Vim-style selections (elements, attributes, paths) | | outline.scm | Symbol outline / code folding with id context | | brackets.scm | Bracket matching and rainbow pairs |

Development

Prerequisites

  • Tree-sitter CLI
  • Node.js 22 (grammar generation, Node binding tests)
  • C compiler (parser + external scanner)

Commands

tree-sitter generate          # regenerate src/parser.c from grammar.js
tree-sitter test              # run corpus + highlight assertions
bun run test                  # Node binding tests
bun run test:regex            # regex sample harness
bun start                     # build WASM + open playground

Project Structure

grammar.js                    # grammar definition (source of truth)
src/
  scanner.c                   # external scanner — tag matching, raw text capture
  parser.c                    # generated (do not edit)
  node-types.json             # generated node type metadata
queries/
  highlights.scm              # syntax highlighting
  injections.scm              # CSS/JS/HTML injection
  locals.scm                  # scope tracking
  tags.scm                    # symbol navigation (with `@doc`)
  indents.scm                 # auto-indentation
  textobjects.scm             # vim-style text object selections
  outline.scm                 # symbol outline / code folding
  brackets.scm                # bracket matching
bindings/
  c/                          # C header + pkg-config
  go/                         # Go binding + test
  java/                       # Java binding + test
  node/                       # Node.js binding + types + test
  python/                     # Python binding + test
  rust/                       # Rust binding + build script
  swift/                      # Swift binding + test
  zig/                        # Zig binding + test
test/corpus/                  # tree-sitter corpus tests
test/highlight/               # highlight query assertions
test/tags/                    # tag query assertions
test/regex_samples/           # regex harness fixtures/tests

Contributing

  1. Edit grammar.js (and src/scanner.c for tag matching changes)
  2. Run tree-sitter generate && tree-sitter test
  3. Add or update tests in test/corpus/ and test/highlight/
  4. Open a pull request

Spec Compliance

This parser targets SVG2 syntax and uses SVG 1.1 DTD tables as supporting reference data.

Element parsing stays mostly XML-generic, with explicit typed coverage for selected SVG value grammars (for example path data, transforms, and paint/IRI families).

License

MIT or Apache-2.0 © Kaj Kowalski