summaryrefslogtreecommitdiff
path: root/proselight.js
blob: d92797b2b8bae218eded493aa544ad9b321cd9e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/**
 * @fileoverview proselight, based on microlight - syntax highlightning library
 * @version 0.0.7
 *
 * @license MIT, see http://github.com/asvd/microlight
 * @copyright 2016 asvd <heliosframework@gmail.com>
 *
 * Code structure aims at minimizing the compressed library size
 */


( function () {
    // for better compression
    var _window       = window,
        _document     = document,
        appendChild   = 'appendChild',
        test          = 'test',

        i, j,
        proselighted,
        cna, //child node array
        cn,  //child node
        el;  // current proselighted element to run through

    // nodes to highlight
    proselighted = _document.querySelectorAll('p');

    for (i = 0; el = proselighted[i++];) {
        cna = Array.from(el.childNodes);
        for (j = 0; cn = cna[j++];) {
            el[appendChild](cn);
            if (cn.nodeType == Node.TEXT_NODE) {
                el.removeChild(cn);
                var text  = cn.textContent,
                    pos   = 0,         // current position
                    next1 = text[0],   // next character
                    chr   = 1,         // current character
                    prev1,             // previous character
                    prev2,             // the one before the previous
                    token = '',        // current token content
                    
                    // current token type:
                    tokenType = 0,

                    // flag determining if token is multi-character
                    multichar,
                    node;

                // running through characters and highlighting
                while (prev2 = prev1, prev1 = chr) {
                    chr = next1;
                    next1=text[++pos];
                    multichar = token.length > 1;

                    // checking if current token should be finalized
                    if (!chr  || // end of content
                        [ // finalize conditions for other token types
                            // 0: unformatted
                            /[":;,\\.?!\])\/{}[(|]/[test](chr),
                            // 1: parentesis or braces
                            /[\]){}[(]/[test](prev1) && multichar,
                            // 2: terminators
                            1,                // consist of a single character
                            // 3: separators
                            1,                // consist of a single character
                            // 4: quotes
                            prev1 == '"' && multichar,
                        ][tokenType]
                    ) {
                        // appending the token to the result
                        if (token) {
                            // map token type into class
                            el[appendChild](
                                node = _document.createElement('span')
                            ).setAttribute('class', 'ph'+tokenType);

                            node[appendChild](_document.createTextNode(token));
                        }

                        // initializing a new token
                        token = '';

                        // determining the new token type (going up the
                        // list until matching a token type start
                        // condition)
                        tokenType = 5;
                        while (![
                            1,                         //  0: unformatted
                            /[\]){}[(]/[test](chr),    //  1: parenthesis or braces
                            /[\\.?!]/[test](chr),      //  2: terminators
                            /[:;,]/[test](chr),        //  3: separators
                            chr == '"',                //  4: quotes
                        ][--tokenType]);
                    }

                    token += chr;
                }
            }
        }
    }
} )();