Completed
Push — master ( e025a9...54d0c4 )
by Kacper
04:20
created

Apache::setupRules()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 46
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 30
c 1
b 0
f 1
nc 1
nop 0
dl 0
loc 46
ccs 0
cts 34
cp 0
crap 2
rs 8.9411
1
<?php
2
/**
3
 * Highlighter
4
 *1
5
 * Copyright (C) 2016, Some right reserved.
6
 *
7
 * @author Kacper "Kadet" Donat <[email protected]>
8
 *
9
 * Contact with author:
10
 * Xmpp: [email protected]
11
 * E-mail: [email protected]
12
 *
13
 * From Kadet with love.
14
 */
15
16
namespace Kadet\Highlighter\Language;
17
18
use Kadet\Highlighter\Matcher\CommentMatcher;
19
use Kadet\Highlighter\Matcher\RegexMatcher;
20
use Kadet\Highlighter\Matcher\SubStringMatcher;
21
use Kadet\Highlighter\Matcher\WordMatcher;
22
use Kadet\Highlighter\Parser\CloseRule;
23
use Kadet\Highlighter\Parser\OpenRule;
24
use Kadet\Highlighter\Parser\Rule;
25
use Kadet\Highlighter\Parser\Token\Token;
26
27
class Apache extends GreedyLanguage
28
{
29
    const IDENTIFIER = '(?P<namespace>[\w\.-]+:)?(?P<name>[\w\.-]+)';
30
31
    /**
32
     * Tokenization rules
33
     */
34
    public function setupRules()
35
    {
36
        $this->rules->addMany([
37
            'tag.open'  => [
38
                new OpenRule(new RegexMatcher('/(<[\w\.-]+)[:\/>:\s]/')),
39
                new CloseRule(new SubStringMatcher('>'), ['context' => ['!string', '!comment']]),
40
            ],
41
            'tag.close' => new Rule(new RegexMatcher('/(<\/' . self::IDENTIFIER . '>)/')),
42
43
            'symbol.tag' => new Rule(new RegexMatcher('/<\\/?' . self::IDENTIFIER . '/', [
44
                'name'      => Token::NAME,
45
                'namespace' => '$.namespace',
46
            ]), ['context' => ['symbol.directive', '!string']]),
47
48
            'number'  => new Rule(new RegexMatcher('/\s(-?(?:0[0-7]+|0[xX][0-9a-fA-F]+|0b[01]+|\d+(?:\.\d+)?))/')),
49
            'comment' => new Rule(new CommentMatcher(['#'])),
50
            'string'  => [
51
                CommonFeatures::strings(['single' => '\'', 'double' => '"'], ['context' => ['!comment', '!operator.escape']]),
52
                'path' => new Rule(new RegexMatcher('/\B(\/[^\s\)\(]*)/'))
53
            ],
54
55
            'call'    => new Rule(new RegexMatcher('/^\s*(\w+)/mi')),
56
            'variable'   => new Rule(new RegexMatcher('/%\{([\w-]+)\}/i'), ['context' => ['expression']]),
57
58
            'expression' => new Rule(new RegexMatcher('/(%\{.*?\})/i'), ['context' => ['string']]),
59
            'expression.regex' => [
60
                new Rule(new RegexMatcher('/(\[(?>[^\[\]]+|(?1))*\])/'), ['context' => ['string']]),
61
            ],
62
63
            'number.ip' => [
64
                new Rule(new RegexMatcher('/(\d{1,3}(\.\d{1,3}){3})/i'), ['context' => ['!string']])
65
            ],
66
            'constant' => new Rule(new WordMatcher(['On', 'Off', 'None', 'All', 'Any'])),
67
68
            'operator.escape' => new Rule(new RegexMatcher('/(\\\(?:\R|.|[0-7]{3}|x\x{2}))/s'), [
69
                'context' => ['!comment'],
70
                'priority' => 10
71
            ]),
72
            'operator.punctuation' => new Rule(new RegexMatcher('/([\(\){},;])/i')),
73
            'keyword.format' => new Rule(
74
                new RegexMatcher('/(%[\w%][-+#0]?(?:[0-9]+|\*)?(?:\.(?:[0-9]+|\*))?)/'), [
75
                    'context' => ['string']
76
                ]
77
            ),
78
        ]);
79
    }
80
81
    /** {@inheritdoc} */
82
    public function getIdentifier()
83
    {
84
        return 'apache';
85
    }
86
87
    public static function getMetadata()
88
    {
89
        return [
90
            'name'      => ['apache'],
91
            'mime'      => ['application/xml', 'text/xml'],
92
            'extension' => ['.htaccess'],
93
        ];
94
    }
95
}
96