Supported Languages¶
t-linter supports syntax highlighting and validation for the following embedded languages in Python template strings.
Language Detection¶
Languages are detected through direct annotations, function parameter annotations, type aliases, and supported callee inference such as tdom.html(...).
from typing import Annotated
from string.templatelib import Template
# Direct annotation
template: Annotated[Template, "html"] = t"<p>{content}</p>"
# Type alias
type html = Annotated[Template, "html"]
page: html = t"<div>{content}</div>"
Supported Languages¶
| Language | Annotation | Check | Format | Highlight | Engine |
|---|---|---|---|---|---|
| HTML | "html" |
✅ | ✅ | ✅ | tstring-html backend |
| T-HTML | "thtml" |
✅ | ✅ | ✅ | tstring-thtml backend |
| TDOM | "tdom" |
✅ | ✅ | ✅ | tstring-tdom backend |
| JSON | "json" |
✅ | ✅ | ✅ | tstring-json backend |
| YAML | "yaml", "yml" |
✅ | ✅ | ✅ | tstring-yaml backend |
| TOML | "toml" |
✅ | ✅ | ✅ | tstring-toml backend |
| CSS | "css" |
✅ | — | ✅ | Tree-sitter |
| JavaScript | "javascript", "js" |
✅ | — | ✅ | Tree-sitter |
| SQL | "sql" |
✅ | — | ✅ | Tree-sitter |
- Check — syntax validation via
t-linter checkCLI and LSP diagnostics - Format — canonical formatting via
t-linter formatCLI and LSP formatting - Highlight — semantic tokens via LSP for editor syntax highlighting
Backend-powered vs Tree-sitter Languages¶
For backend-powered languages (HTML, T-HTML, TDOM, JSON, YAML, TOML), t-linter splits responsibilities:
- Highlighting: Tree-sitter only, for low-latency semantic tokens
- Validation: Strict parsing through the dedicated Rust backends (
tstring-*crates) - Formatting: Canonical formatting through the same Rust backends
For Tree-sitter-only languages (CSS, JavaScript, SQL), t-linter uses Tree-sitter for both highlighting and validation. Formatting is not yet available for these languages.
HTML Notes¶
For html, <title>{value}</title> is allowed and rendered as escaped text.
<script>, <style>, and <textarea> still reject interpolations.
Use these patterns:
- use
<title>{value}</title>for dynamic document titles - keep
<script>,<style>, and<textarea>static - move dynamic values into attributes
- move dynamic values into normal element content such as
<p>{content}</p>
Examples¶
from typing import Annotated
from string.templatelib import Template
def render_html(template: Annotated[Template, "html"]) -> None:
pass
def render_thtml(template: Annotated[Template, "thtml"]) -> None:
pass
def run_sql(template: Annotated[Template, "sql"]) -> None:
pass
def run_javascript(template: Annotated[Template, "javascript"]) -> None:
pass
type css = Annotated[Template, "css"]
type json_payload = Annotated[Template, "json"]
type yaml_config = Annotated[Template, "yaml"]
type toml_config = Annotated[Template, "toml"]
def load_css(template: css) -> None:
pass
def load_json(template: json_payload) -> None:
pass
def load_yaml(template: yaml_config) -> None:
pass
def load_toml(template: toml_config) -> None:
pass
def Card(*, title: str, children: str | None = None) -> object:
return None
def Badge(*, tone: str = "neutral", children: str | None = None) -> object:
return None
title = "Dashboard"
render_html(t"""
<html>
<body><h1>{title}</h1></body>
</html>
""")
status = "ready"
render_thtml(t"""
<Card title="{title}">
<Badge tone="success">{status}</Badge>
</Card>
""")
from tdom import html
page = html(t"""
<{Card} title={title}>
<span>{status}</span>
</{Card}>
""")
user_id = 42
run_sql(t"""
SELECT * FROM users WHERE id = {user_id}
""")
message = "'hello from t-linter'"
run_javascript(t"""
console.log({message});
""")
width = 1200
load_css(t"""
.container {{
max-width: {width}px;
}}
""")
name = "Ada"
age = 37
load_json(t"""
{{
"name": {name},
"age": {age}
}}
""")
app_name = "demo-app"
load_yaml(t"""
app:
name: {app_name}
debug: true
""")
project_name = "demo-project"
version = "0.1.0"
load_toml(t"""
[project]
name = "{project_name}"
version = "{version}"
""")
Use {{ and }} when the embedded language needs literal braces, such as CSS or JSON objects.