STL syntax highlighting
Apply 6-color token coloring to STL (Semantic Tension Language) code blocks in your
.md— making knowledge-graph STL fragments as readable as code, not a string of confusing brackets.
What this is / who uses it
STL is a small language for expressing "semantic relations" as readable strings:
[Source] -> [Target] ::mod(key=value, key=value)
It was originally the input format for the STG (Semantic Tension Graph) project — but anyone wanting to embed "knowledge graph fragments, citations, claims, thought nodes" inside markdown can use it.
You need this capability if:
- ✅ You write research notes that need to express relationships between nodes ("A entails B", "X refutes Y")
- ✅ You do knowledge management and want STL fragments inside your docs
- ✅ You write structured notes on complex topics (theory relationships, concept dependencies, decision chains)
- ✅ You want to feed structured semantics to AI agents (LLMs learn STL easily)
- ❌ You write regular articles — you probably don't need this, skip the page
Basic syntax
Wrap STL statements in a ```stl code block:
```stl
[REST_API] -> [HTTP_Layer] ::mod(rule="definitional", confidence=1.0, description="REST is built on HTTP semantics")
```
Renders: 6-color token highlighting that makes anchors / arrows / keys / values / keywords / comments visually distinct.
Token colors
Rho's built-in STL grammar tokenizes STL into 6 semantic categories, each with its own color:
| Token | Example | Color (typical dark theme) |
|---|---|---|
| Anchor | [User_Profile], [Module:Auth] |
Cyan |
| Arrow | ->, → |
Yellow |
| Modifier key | rule=, confidence=, action= |
Purple |
| Modifier value (string) | "depends_on" |
Green |
| Modifier value (number) | 0.99, 100 |
Orange |
| Comment | # this is a comment |
Gray |
Exact colors vary by theme (light / dark / custom), but the 6 semantic roles are fixed.
Different from Annotate: annotate is manual annotation of arbitrary text; stl is automatic highlighting by STL grammar. One manual, one automatic.
Examples
Example 1: simplest edge
```stl
[A] -> [B] ::mod(rule="causal", strength=0.8)
```
Renders: [A] and [B] in cyan, -> in yellow, rule= and strength= in purple, "causal" in green, 0.8 in orange. One line conveys "A causally drives B with strength 0.8."
Example 2: research notes with embedded semantic network
A causal-chain overview of climate change:
```stl
[Climate_Change] -> [Greenhouse_Gas_Emissions] ::mod(rule="causal", confidence=0.97, strength=0.92, description="primary causal driver")
[Greenhouse_Gas_Emissions] -> [CO2] ::mod(action="dominated_by", confidence=0.95)
[CO2] -> [Fossil_Fuel_Burning] ::mod(action="primarily_from", confidence=0.95)
[CO2] -> [Deforestation] ::mod(action="also_from", confidence=0.85)
[Climate_Change] -> [Sea_Level_Rise] ::mod(action="leads_to", confidence=0.90)
```
Note how confidence decreases from 0.97 (strong evidence) to 0.85 (secondary factor still being quantified).
Renders: 5 STL lines neatly highlighted; confidence numbers (orange) form a visual echo with the prose description.
Example 3: comments + multi-line modifier
```stl
# Database selection decision record (2026-05-14)
[Database_Choice] -> [PostgreSQL] ::mod(
rule="empirical",
confidence=0.95,
action="selected_over",
alternatives="MySQL, MongoDB, DynamoDB",
occurred_time="2026-05-14",
lesson="JSONB support + mature ecosystem + ACID compliance + team familiarity"
)
```
Renders: comment line in gray; multi-line modifier indented; every key/value pair color-coded. Easier to read than a single line for richer modifiers.
Example 4: same content with vs without lang label
A plain ` ```text ` block (no highlighting):
```text
[A] -> [B] ::mod(rule="causal")
```
The same in a Rho ` ```stl ` block (highlighted):
```stl
[A] -> [B] ::mod(rule="causal")
```
Renders: both blocks have identical text content, but the lower (stl) version color-codes every token; semantic structure is visible. The only difference is the fenced block's lang label.
Plain-text fallback behavior
stl is a standard markdown fenced-code-block lang label. In readers without STL grammar support:
```stl
[A] -> [B] ::mod(rule="causal")
```
→ shows as a plain code block (monospace, gray background) — content fully readable, only the 6-color token encoding is lost.
Per-reader breakdown:
| Reader | Render |
|---|---|
| Rho | Full 6-color highlighting |
| GitHub web | Plain code block (no STL highlighting, content clear) |
| Obsidian | Same (unless a STL highlight plugin is installed) |
| VS Code default preview | Same |
| Any markdown reader | At least recognized as a code block, monospace font |
Rho's STL grammar is built on highlight.js / lowlight token conventions and the tokenization rules described in the STL spec — any reader integrated with hljs / lowlight can implement compatible STL highlighting using that spec.
Common pitfalls
1. Confusing STL with markdown link syntax
[A] -> [B]
→ This looks like the markdown link [A], but it has no (url) part, so the markdown parser leaves it alone. No problem — it won't be misparsed as a link. But:
[A](http://...) -> [B] ← ❌ This becomes a real link, breaking STL parsing
STL [X] should not be immediately followed by (...).
2. Spaces in anchor names
[User Profile] -> [...] ← ⚠️ Some readers' parse behavior undefined
[User_Profile] -> [...] ← ✅ Recommended: use `_` instead of space
STL spec recommends anchor names contain only [A-Za-z0-9_:-], no spaces. When you want a "space-like look," use _, -, or :.
3. Double quotes in value
[A] -> [B] ::mod(description="he said "hello"") ← ❌ Nested quotes break parsing
→ Nested unescaped ASCII double quotes close the string early, breaking the rest of the statement. Fixes:
- Use CJK / full-width
「」/"" - Or escape
\"(parser-dependent) - Or wrap the outer string in single quotes (if supported)
4. Missing comma between modifiers
[A] -> [B] ::mod(rule="causal" confidence=0.8) ← ❌ Missing comma
[A] -> [B] ::mod(rule="causal", confidence=0.8) ← ✅
5. Highlighting non-STL content with stl
function foo() { return 1; } ← ❌ This isn't STL; highlighting goes weird
→ The STL grammar only recognizes STL syntax tokens. Feeding it JS / Python / anything else results in wrong colors or no colors. Only use ```stl lang label on real STL code.
6. Wanting "STL-styled emphasis" inline
Just writing [A] -> [B] inline in a paragraph and hoping for highlighting ← ❌ Doesn't work
→ STL highlighting only works inside fenced code blocks. Inline [A] -> [B] will be parsed by markdown as "broken link + text + text." For inline STL emphasis, use inline code: `[A] -> [B] ::mod(rule="causal")` — no highlighting, but at least it looks like code.
See also
- Annotate — Manual annotation of arbitrary text (vs STL is automatic by grammar)
- Callout — Wrap "this STL is important" inside a callout
- Layout — Multi-segment STL comparison with cards
- STL spec — External repo
- STG knowledge graph engine — Extract STL blocks from
.mdand build a knowledge graph (foundation for the future Rho graph feature)