Shiki syntax highlighting grammars for Rspamd map file formats.
| 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 |
npm install rspamd-shiki-grammarsRequires shiki >= 1.0 as a peer dependency.
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',
})import { createHighlighter } from 'shiki'
import {
rspamdMapGrammar,
rspamdRadixMapGrammar,
rspamdRegexpMapGrammar,
rspamdSaRulesGrammar,
} from 'rspamd-shiki-grammars'
const hl = await createHighlighter({
langs: [rspamdMapGrammar, rspamdRadixMapGrammar],
themes: ['nord'],
})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 }} />
}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 allowlisted
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] loopback
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 phishing
Supported pattern flags: i m s x u r O L
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 signals
Directives:
| 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 |
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.
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.
Apache 2.0 — see LICENSE.