summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsblondon <sblondon@users.noreply.github.com>2020-01-04 17:08:42 +0100
committerMatthäus G. Chajdas <Anteru@users.noreply.github.com>2020-01-04 17:08:42 +0100
commit3b4a523858b94359da0e843ce8ccd5536228ac83 (patch)
treee57876122a008fc04ac7f46101d0e883d038e4b8
parent1547648c7d3381008137a5aea8558d3625acf87f (diff)
downloadpygments-git-3b4a523858b94359da0e843ce8ccd5536228ac83.tar.gz
Add Sieve lexer (#1257)
Add Sieve lexer
-rw-r--r--AUTHORS2
-rw-r--r--pygments/lexers/_mapping.py1
-rw-r--r--pygments/lexers/sieve.py68
-rw-r--r--tests/examplefiles/example.sieve56
4 files changed, 126 insertions, 1 deletions
diff --git a/AUTHORS b/AUTHORS
index 58968f50..9b6083e3 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -32,7 +32,7 @@ Other contributors, listed alphabetically, are:
* Sébastien Bigaret -- QVT Operational lexer
* Jarrett Billingsley -- MiniD lexer
* Adam Blinkinsop -- Haskell, Redcode lexers
-* Stéphane Blondon -- SGF lexer
+* Stéphane Blondon -- SGF and Sieve lexers
* Frits van Bommel -- assembler lexers
* Pierre Bourdon -- bugfixes
* Martijn Braam -- Kernel log lexer
diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py
index 1afd5df7..2ae0c375 100644
--- a/pygments/lexers/_mapping.py
+++ b/pygments/lexers/_mapping.py
@@ -398,6 +398,7 @@ LEXERS = {
'ScssLexer': ('pygments.lexers.css', 'SCSS', ('scss',), ('*.scss',), ('text/x-scss',)),
'ShExCLexer': ('pygments.lexers.rdf', 'ShExC', ('shexc', 'shex'), ('*.shex',), ('text/shex',)),
'ShenLexer': ('pygments.lexers.lisp', 'Shen', ('shen',), ('*.shen',), ('text/x-shen', 'application/x-shen')),
+ 'SieveLexer': ('pygments.lexers.sieve', 'Sieve', ('sieve',), ('*.siv', '*.sieve'), ()),
'SilverLexer': ('pygments.lexers.verification', 'Silver', ('silver',), ('*.sil', '*.vpr'), ()),
'SlashLexer': ('pygments.lexers.slash', 'Slash', ('slash',), ('*.sl',), ()),
'SlimLexer': ('pygments.lexers.webmisc', 'Slim', ('slim',), ('*.slim',), ('text/x-slim',)),
diff --git a/pygments/lexers/sieve.py b/pygments/lexers/sieve.py
new file mode 100644
index 00000000..9d7dba35
--- /dev/null
+++ b/pygments/lexers/sieve.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+"""
+ pygments.lexers.sieve
+ ~~~~~~~~~~~~~~~~~~~~~
+
+ Lexer for Sieve file format.
+
+ https://tools.ietf.org/html/rfc5228
+ https://tools.ietf.org/html/rfc5173
+ https://tools.ietf.org/html/rfc5229
+ https://tools.ietf.org/html/rfc5230
+ https://tools.ietf.org/html/rfc5232
+ https://tools.ietf.org/html/rfc5235
+ https://tools.ietf.org/html/rfc5429
+ https://tools.ietf.org/html/rfc8580
+
+ :copyright: Copyright 2006-2019 by the Pygments team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, bygroups
+from pygments.token import Comment, Name, Literal, String, Text, Punctuation, Keyword
+
+__all__ = ["SieveLexer"]
+
+
+class SieveLexer(RegexLexer):
+ """
+ Lexer for sieve format.
+ """
+ name = 'Sieve'
+ filenames = ['*.siv', '*.sieve']
+
+ tokens = {
+ 'root': [
+ (r'\s+', Text),
+ (r'[();,{}\[\]]', Punctuation),
+ # import:
+ (r'(?i)require',
+ Keyword.Namespace),
+ # tags:
+ (r'(?i)(:)(addresses|all|contains|content|create|copy|comparator|count|days|detail|domain|fcc|flags|from|handle|importance|is|localpart|length|lowerfirst|lower|matches|message|mime|options|over|percent|quotewildcard|raw|regex|specialuse|subject|text|under|upperfirst|upper|value)',
+ bygroups(Name.Tag, Name.Tag)),
+ # tokens:
+ (r'(?i)(address|addflag|allof|anyof|body|discard|elsif|else|envelope|ereject|exists|false|fileinto|if|hasflag|header|keep|notify_method_capability|notify|not|redirect|reject|removeflag|setflag|size|spamtest|stop|string|true|vacation|virustest)',
+ Name.Builtin),
+ (r'(?i)set',
+ Keyword.Declaration),
+ # number:
+ (r'([0-9.]+)([kmgKMG])?',
+ bygroups(Literal.Number, Literal.Number)),
+ # comment:
+ (r'#.*$',
+ Comment.Single),
+ (r'/\*.*\*/',
+ Comment.Multiline),
+ # string:
+ (r'"[^"]*?"',
+ String),
+ # text block:
+ (r'text:',
+ Name.Tag, 'text'),
+ ],
+ 'text': [
+ (r'[^.].*?\n', String),
+ (r'^\.', Punctuation, "#pop"),
+ ]
+ }
diff --git a/tests/examplefiles/example.sieve b/tests/examplefiles/example.sieve
new file mode 100644
index 00000000..8abed421
--- /dev/null
+++ b/tests/examplefiles/example.sieve
@@ -0,0 +1,56 @@
+# Based on examples included the RFC files.
+# It doesn't show cases for every token parsed by the lexer.
+
+require ["fileinto", "envelope"];
+
+if address :is "to" "demo@example.org" {
+ fileinto "demo-list";
+} elsif envelope :is "from" "owner@example.org" {
+ fileinto "lists.cipe";
+} elsif (exists "X-Cron-Env",
+ header :regex ["subject"] [".* A",
+ ".* B"]) {
+ addflag "Cron";
+ stop;
+} else {
+ keep;
+}
+
+if body :text :contains "project schedule" {
+ fileinto "project/schedule";
+}
+
+require "vacation";
+if header :contains "subject" "lunch" {
+ vacation :handle "ran-away" "I'm out and can't meet for lunch";
+} else {
+ vacation :handle "ran-away" "I'm out";
+}
+
+
+if virustest :value "eq" :comparator "i;ascii-numeric" "0" {
+ fileinto "Unscanned";
+ /* Infected with high probability (value range in 1-5) */
+}
+
+if envelope :detail "to" "spam"{
+ fileinto "Spam";
+}
+
+if size :over 100k {
+ discard;
+}
+elsif address :DOMAIN :is ["From", "To"] "example.com"
+{
+ keep;
+}
+
+require ["reject"];
+
+if size :over 1M {
+ reject text:
+Your message is too big. If you want to send me a big attachment,
+put it on a public web site and send me a URL.
+.
+;
+}