ipmtokens

package
v0.4.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 13, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package ipmtokens runs the ipmt semantic tokenizer used by both the LSP server (cmd/ipm-rpc) and the md-html exporter (pkg/mdhtml).

Token coordinates are 0-based UTF-16 columns, line-relative to the surrounding document — caller supplies `lineOffset` to position a block inside its containing markdown file.

The token kind is a uint32 INDEX into SemanticTokenTypes; the LSP protocol uses the same indexing so the encoder in cmd/ipm-rpc can pass values through unmodified. Callers that need the wire-format string (e.g. the JSON embed-buffer response, or pkg/mdhtml which keys off "ipmEvent" / "ipmThing" / …) use TypeName.

Index

Constants

View Source
const (
	ModAlias     uint32 = 1 << 0
	ModLeadsTo   uint32 = 1 << 1
	ModPartOf    uint32 = 1 << 2
	ModExpresses uint32 = 1 << 3
	ModNearTo    uint32 = 1 << 4
	ModHasAlias  uint32 = 1 << 5
	ModMarker    uint32 = 1 << 6
)

Modifier bitmask helpers — bit positions mirror SemanticTokenModifiers.

View Source
const (
	TypEvent      uint32 = 0
	TypThing      uint32 = 1
	TypConcept    uint32 = 2
	TypRelation   uint32 = 3
	TypArrow      uint32 = 4
	TypTypeMarker uint32 = 5
	TypComment    uint32 = 6
	TypString     uint32 = 7
	TypTooltip    uint32 = 8
	TypUnresolved uint32 = 9
)

Token type indices — mirror SemanticTokenTypes.

Variables

View Source
var Palette []PaletteRule

Palette is the ordered rule list parsed from palette.json.

View Source
var SemanticTokenModifiers = []string{
	"alias",
	"leadsTo",
	"partOf",
	"expresses",
	"nearTo",
	"hasAlias",
	"marker",
}

SemanticTokenModifiers is the LSP token-modifier legend. Index N here corresponds to bit (1<<N) in the Token.Mods field.

View Source
var SemanticTokenTypes = []string{
	"ipmEvent",
	"ipmThing",
	"ipmConcept",
	"ipmRelation",
	"ipmArrow",
	"ipmTypeMarker",
	"ipmComment",
	"ipmString",
	"ipmTooltip",
	"ipmUnresolved",
}

SemanticTokenTypes is the LSP token-type legend. Index order is part of the LSP wire contract — appending is OK, reordering is not.

Functions

func ClassSuffix

func ClassSuffix(tokenType string, mods uint32) string

ClassSuffix returns the `ipm-<suffix>` class suffix for an LSP semantic token (type + modifier bitmask), or "" if the type is unknown. The modifier bits a token actually carries are mutually exclusive within a type, so the first matching modifier rule wins; the base rule is the fallback.

func PaletteCSSRules

func PaletteCSSRules() string

PaletteCSSRules returns the generated `.ipm-<suffix> { ... }` rules (one per palette entry, in palette order) for embedding in HTML/preview CSS.

func TokenForClass

func TokenForClass(name string) (typ uint32, mods uint32, ok bool)

TokenForClass is the inverse of ClassSuffix: the (token-type index, modifier bits) that an `as-token:NAME` paints over its text. ok=false for an unknown name.

func TypeName

func TypeName(idx uint32) string

TypeName returns the wire-format string for a token-type index, or "" if the index is out of range.

Types

type PaletteRule

type PaletteRule struct {
	Type   string `json:"type"`
	Mod    string `json:"mod,omitempty"`
	Class  string `json:"class"`
	FG     string `json:"fg"`
	Bold   bool   `json:"bold,omitempty"`
	Italic bool   `json:"italic,omitempty"`
}

PaletteRule is one (type, optional modifier) styling entry.

type Token

type Token struct {
	Line     uint32
	StartCol uint32
	Length   uint32
	Type     uint32 // index into SemanticTokenTypes
	Mods     uint32 // bitmask matching SemanticTokenModifiers
}

Token is one un-encoded semantic token. Positions are 0-based UTF-16 columns; Collect adds the caller-supplied `lineOffset` so a block inside a markdown document carries whole-file coordinates.

func Collect

func Collect(wholeText, blockText string, lineOffset uint32) []Token

Collect parses the given ipmt source and emits semantic tokens for node names, alias spans, arrow spans, and quoted-tooltip spans. Positions are returned in whole-file LSP coordinates given the line offset of the block within its containing markdown document (0 for pure .ipmt files).

`wholeText` is currently unused: every span is sourced from the parser's graph.Src.Lex structure and positioned via a mapper built from blockText (plus lineOffset). The parameter is retained for call-site symmetry and a possible future cross-block mapper. Callers may pass blockText for it.

func Flatten

func Flatten(tokens []Token) []Token

Flatten resolves the intentionally-overlapping tokens Collect emits into a sorted, NON-OVERLAPPING stream — the canonical output every consumer (LSP wire encoder, md-html, preview) can use directly.

Resolution is per-character LAST-WINS BY EMISSION ORDER: for every UTF-16 column a later token in the input overwrites an earlier one on the columns they share. This is byte-for-byte the same rule pkg/mdhtml.HighlightTokens and previewHighlight.ts:renderFromLspTokens apply when rendering, so flattening here changes no rendered output — it only moves the resolution upstream so the LSP can ship a spec-clean (disjoint, sorted) token set instead of relying on client leniency.

Tokens that map to no CSS class (ClassSuffix == "") are skipped, never painting over a colored token — matching the `continue` both renderers do. Collect never emits such tokens (all its types are valid), but the guard keeps Flatten equivalent to the renderers for any input.

All Collect tokens are single-line (it clamps a range that crosses a newline to one character on the start line), so painting per line is exact.

func TokensForClass

func TokensForClass(name, visible string) ([]Token, bool)

TokensForClass supports the inline-ipmt `as-token:NAME` marker: it resolves the palette class suffix `name` (e.g. `e-marker`, `L`, `type-marker`) to a single synthetic token covering the whole visible text — `[0, utf16Len(visible))` carrying the (type, mods) that map to `ipm-<name>`. The visible text is NOT parsed as ipmt; only the named style is applied. Returns (nil, false) when `visible` is empty or `name` is not a known class suffix.

`TokenForClass` (the name → type+mods reverse map) is defined in palette.go and derived from the embedded palette.json — the single source of truth. Code generation flows the other way: vscode-ipm/scripts/gen-palette.ts consumes the same palette.json to produce the editor's src/palette.gen.ts. Guarded by the e2e drift test.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL