rspamd-shiki-grammars
v0.2.0
Published
Shiki syntax highlighting grammars for Rspamd map formats
Maintainers
Readme
rspamd-shiki-grammars
Shiki syntax highlighting grammars for Rspamd map file formats.
Grammars
| Language name | Format |
|---|---|
| rspamd-map | Plain and key-value maps |
| rspamd-radix-map | IP/network (radix) maps |
| rspamd-regexp-map | Regular expression maps |
| rspamd-sa-rules | SpamAssassin-style rule files |
| rspamd-composites | Composite symbol definitions |
Installation
npm install rspamd-shiki-grammarsRequires shiki >= 1.0 as a peer dependency.
Usage
Register all grammars at once
import { createHighlighter } from 'shiki'
import { rspamdGrammars } from 'rspamd-shiki-grammars'
const hl = await createHighlighter({
langs: rspamdGrammars,
themes: ['github-dark'],
})
const html = hl.codeToHtml(mapContent, {
lang: 'rspamd-sa-rules',
theme: 'github-dark',
})Register individual grammars
import { createHighlighter } from 'shiki'
import {
rspamdMapGrammar,
rspamdRadixMapGrammar,
rspamdRegexpMapGrammar,
rspamdSaRulesGrammar,
} from 'rspamd-shiki-grammars'
const hl = await createHighlighter({
langs: [rspamdMapGrammar, rspamdRadixMapGrammar],
themes: ['nord'],
})With @shikijs/react (or any Shiki-based React library)
import { codeToHtml } from 'shiki'
import { rspamdGrammars } from 'rspamd-shiki-grammars'
export async function MapViewer({ code }: { code: string }) {
const html = await codeToHtml(code, {
lang: 'rspamd-map',
theme: 'github-light',
langs: rspamdGrammars,
})
return <div dangerouslySetInnerHTML={{ __html: html }} />
}Map format overview
rspamd-map — plain and key-value maps
Lines are either a bare key, a key value pair, or a comment. Quoted keys
("key with spaces") are supported.
# blocklist
spammer.example.com
"quoted domain.com"
trusted.host allowlistedrspamd-radix-map — IP/network maps
Keys are IPv4 or IPv6 addresses and CIDR prefixes. Multiple addresses per line can be comma-separated.
# local networks
10.0.0.0/8
192.168.0.0/16,172.16.0.0/12 internal
2001:db8::/32
[::1] loopbackrspamd-regexp-map — regular expression maps
Keys are PCRE patterns in any of the forms Rspamd accepts. An optional value follows the pattern.
# Rspamd regexp map
/\bviagra\b/i drug_spam
/\bclick\s+here\b/iu clickhere
m{https?://bit\.ly} shortlink
m!paypal\.com\.ru!i phishingSupported pattern flags: i m s x u r O L
rspamd-sa-rules — SpamAssassin-style rules
Supports all directives understood by Rspamd's multimap SA rules parser.
# Drug spam detection
header DRUG_SUBJ Subject =~ /\b(viagra|cialis|levitra)\b/i
rawbody DRUG_BODY /\b(buy now|order online)\b/i
uri DRUG_URI /pills?\.com/i
selector FROM_RU from.addr =~ /\.ru$/i
meta DRUG_COMBO DRUG_SUBJ && (DRUG_BODY || DRUG_URI)
score DRUG_COMBO 5.0
describe DRUG_COMBO Multiple drug spam signalsDirectives:
| Directive | Syntax |
|---|---|
| header | header ATOM Header-Name =~ /pattern/flags |
| body | body ATOM /pattern/flags |
| rawbody | rawbody ATOM /pattern/flags |
| uri | uri ATOM /pattern/flags |
| full | full ATOM /pattern/flags |
| selector | selector ATOM pipeline =~ /pattern/flags |
| meta | meta ATOM expr — boolean/arithmetic over atom names |
| score | score ATOM value |
| describe | describe ATOM text |
rspamd-composites — composite symbol definitions
UCL-style blocks (as used in local.d/composites.conf) defining composite
symbols. The expression value is highlighted as the composite expression
language: boolean operators, removal-policy prefixes, group references, and
symbol options.
# Combine related signals
PHISHING_COMBO {
expression = "PHISHING & (SUSPICIOUS_URL | REDIRECTOR_URL)";
score = 8.0;
}
WHITELIST_SENDER {
expression = "-FORGED_SENDER & g+:fuzzy & DMARC_POLICY_REJECT[sp]";
score = -10.0;
policy = "leave";
enabled = true;
}Expression language elements:
| Element | Syntax |
|---|---|
| Boolean operators | & \| !, or and or not (any case) |
| Grouping | ( ... ) |
| Removal-policy prefix | ~SYMBOL (keep weight), -SYMBOL (keep both), ^SYMBOL (force remove) |
| Group reference | g:name, g+:name, g-:name |
| Symbol options | SYMBOL[opt1,opt2], SYMBOL[/regex/i, opt] |
Block properties: expression, score, group, policy, enabled, description.
Development
npm run build # compile to dist/
npm test # run 114 Vitest unit tests
npm run test:watch # watch modeTests assert TextMate scope names directly via Shiki's includeExplanation
API, so grammar regressions are caught at the token level.
License
Apache 2.0 — see LICENSE.
