﻿exports.check = function(context, setting, data) {
    // context.report(msg)
};

exports.fix = function(setting, data) {
    return data;
};

exports.infer = function(data) {
    // return setting (e.g., true, false)
};

@@ -1,222 +1,1648 @@
 %EF%BB%BF
-exports.check = function(context, setting, data) %7B%0A    // context.report(msg)%0A%7D;%0A%0Aexports.fix = function(setting, data) %7B%0A    return data;%0A%7D;%0A%0Aexports.infer = function(data) %7B%0A    // return setting (e.g., true, false)
+var map = %7B%0A    // CR+LF: CR (U+000D) followed by LF (U+000A)%0A    crlf: '%5Cr%5Cn',%0A%0A    // LF: Line Feed, U+000A%0A    lf: '%5Cn',%0A%0A    // CR: Carriage Return, U+000D%0A    cr: '%5Cr',%0A%0A    // VT: Vertical Tab, U+000B%0A    vt: '%5Cu000B',%0A%0A    // FF: Form Feed, U+000C%0A    ff: '%5Cu000C',%0A%0A    // NEL: Next Line, U+0085%0A    nel: '%5Cu0085',%0A%0A    // LS: Line Separator, U+2028%0A    ls: '%5Cu2028',%0A%0A    // PS: Paragraph Separator, U+2029%0A    ps: '%5Cu2029'%0A%7D;%0A%0Avar reverseMap = %7B%7D;%0A%0Avar newlineCharacters = Object.keys(map).map(function(key) %7B%0A    var value = map%5Bkey%5D;%0A    reverseMap%5Bvalue%5D = key;%0A    return value;%0A%7D);%0A%0Avar newlineCharacterPat = new RegExp(%0A    '(' + newlineCharacters.join('%7C') + ')', 'g');%0A%0A%0Aexports.check = function(context, setting, data) %7B%0A    var matches = data.match(newlineCharacterPat);%0A    matches && matches.forEach(function(match) %7B%0A        if (match !== setting) %7B%0A            context.report('Incorrect line ending found: ' + reverseMap%5Bmatch%5D);%0A        %7D%0A    %7D);%0A%7D;%0A%0Aexports.fix = function(setting, data) %7B%0A    return data.replace(newlineCharacterPat, function() %7B%0A        return setting;%0A    %7D);%0A%7D;%0A%0Aexports.infer = function(data) %7B%0A    var inferred = %7B%7D;%0A    var matches = data.match(newlineCharacterPat);%0A%0A    matches && matches.forEach(function(match) %7B%0A        var setting = reverseMap%5Bmatch%5D;%0A        inferred%5Bsetting%5D = inferred%5Bsetting%5D %7C%7C 0;%0A        inferred%5Bsetting%5D++;%0A    %7D);%0A%0A    var result;%0A    var max = 0;%0A    Object.keys(inferred).forEach(function(setting) %7B%0A        var count = inferred%5Bsetting%5D;%0A        if (count %3E max) %7B%0A            max = count;%0A            result = setting;%0A        %7D%0A    %7D);%0A%0A    return result;
 %0A%7D;%0A

Introduce end_of_line rule