User:LOL/mmarecordcolumns.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
function rearrangeMMARecordTable() {
    var tb = document.getElementById('wpTextbox1');
    var s = tb.value;

    // A 'Record' object should exist in the headings array!
    var RECORD_COL_NAME = 'Record';
    var RESULT_COL_NAME = 'Result';

    var tableStart = s.indexOf('\n{|');
    var tableEnd = s.indexOf('\n|}', tableStart);
    if (tableStart == -1 || tableEnd == -1) {
        // Evil replacement of S-(start|end)
        s = s.replace(/\{\{ *[Ss]-start *\}\}/, '{|');
        s = s.replace(/\{\{ *[Ss]-end *\}\}/, '|}');
        tableStart = s.indexOf('\n{|');
        tableEnd = s.indexOf('\n|}', tableStart);
        if (tableStart == -1 || tableEnd == -1) {
            alert('"{|" or "|}" not found');
            return;
        }
    }

    var headings = [{name: RESULT_COL_NAME},
            {name: RECORD_COL_NAME, align: 'center'}, {name: 'Opponent'},
            {name: 'Method'}, {name: 'Event'}, {name: 'Date'},
            {name: 'Round', align: 'center'}, {name: 'Time', align: 'center'},
            {name: 'Location'}, {name: 'Notes'}];

    var output = s.substring(0, tableStart) + '\n{{MMA record start}}\n';
    var sTable = s.substring(tableStart, tableEnd);

    // Evil splitting of multi-cell lines
    sTable = sTable.replace(/\| *(?:align|style[^\|]+)?\|/g, '\n|');

    // Evil separation of merged Round-Time columns
    sTable = sTable.replace(/Round[ ']*(?:,[ ']*)?[Tt]ime/, 'Round\n!Time');
    sTable = sTable.replace(/\| *(?:[Rr]ound *)?(\d)[ ,']+(\d{1,2}:\d{2}|[Nn]\/[Aa])/g, '| $1\n| $2');

    var lines = sTable.split('\n');

    // Get heading order of nonstandard table
    var i;
    var headingCount = 0;
    for (i = 0; i < lines.length; i++) {
        var line = lines[i];
        if (line.substring(0, 2) == '|-') {
            if (headingCount > 0) {
                // Alert user of any missing columns
                var missing = [];
                for (var j = 0; j < headings.length; j++) {
                    if (headings[j].index === undefined) {
                        missing.push(headings[j].name);
                    }
                }
                if (missing.length > 0) {
                    alert('Missing columns: ' + missing);
                }
                break;
            }
        } else if (/[\|!]/.test(line[0])) {
            for (var j = 0; j < headings.length; j++) {
                if (line.indexOf(headings[j].name) > -1) {
                    headings[j].index = headingCount++;
                }
            }
        }
    }

    var rows = [];
    var cell = [];
    for (; i < lines.length; i++) {
        var line = lines[i];
        if (line.substring(0, 2) == '|-') {
            if (cell.length > 0) {
                rows.push(cell);
                cell = [];
            }
        } else if (line[0] == '|') {
            // Evil removal of pipe after cell attributes
            if (/^\|[^\|\[\{]+\|/.test(line)) {
                line = line.substring(line.indexOf('|', 1));
            }

            // replace = trim
            cell.push(line.substring(1).replace(/^\s+|\s+$/g, ''));
        }
    }
    if (cell.length > 0) {
        rows.push(cell);
    }

    // Check if the 'Record' column is missing
    var missingRecords = false, recordIndexH = -1;
    for (var j = 0; j < headings.length; j++) {
        if (headings[j].name == RECORD_COL_NAME) {
            recordIndexH = j;
            missingRecords = headings[j].index === undefined;
            break;
        }
    }

    // Attempt to construct it if the 'Result' column exists
    var record = [];
    if (missingRecords) {
        var resultIndex = -1;
        for (var j = 0; j < headings.length; j++) {
            if (headings[j].name == RESULT_COL_NAME) {
                if (headings[j].index !== undefined) {
                    resultIndex = headings[j].index;
                }
                break;
            }
        }

        if (resultIndex > -1) {
            // 'Result' column exists, so go backwards through the rows and
            // interpret the 'Result' cells

            // Record before their career started--all zeroes
            record[rows.length] = {wins: 0, losses: 0, draws: 0, nc: 0};
            for (var j = rows.length - 1; j >= 0; j--) {
                var result = rows[j][resultIndex];
                record[j] = {wins: record[j + 1].wins,
                        losses: record[j + 1].losses,
                        draws: record[j + 1].draws, nc: record[j + 1].nc};
                if (/\bwin\b/i.test(result)) {
                    record[j].wins++;
                } else if (/\bloss\b/i.test(result)) {
                    record[j].losses++;
                } else if (/\bdraw\b/i.test(result)) {
                    record[j].draws++;
                } else if (/\b(?:NC|[Nn]o +[Cc]ontest)\b/.test(result)) {
                    record[j].nc++;
                } else if (result == '') {
                    record[j] = null;
                } else {
                    // Ask user for input on an unrecognized result
                    var input = '';
                    while (!/^[ '"]*[WLDN][ '"]*$/i.test(input)) {
                        input = prompt('What kind of result is "' + result
                                + '"?\nEnter "W" for win, "L" for loss, "D" for draw, or "N" for no contest',
                                '');
                    }
                    if (/^[ '"]*W[ '"]*$/i.test(input)) {
                        record[j].wins++;
                    } else if (/^[ '"]*L[ '"]*$/i.test(input)) {
                        record[j].losses++;
                    } else if (/^[ '"]*D[ '"]*$/i.test(input)) {
                        record[j].draws++;
                    } else {
                        record[j].nc++;
                    }
                }
            }
        }
    }

    // Iterate through stored rows and output them according to the headings
    // array
    for (i = 0; i < rows.length; i++) {
        output += '|-\n';
        var cell = rows[i];
        for (var j = 0; j < headings.length; j++) {
            output += '| ';
            if (!!headings[j].align && !/\{\{N\/A\}\}\s*$/.test(cell[headings[j].index])) {
                output += 'align="' + headings[j].align + '" | ';
            }
            if (headings[j].index !== undefined) {
                if (!!cell[headings[j].index]) {
                    output += cell[headings[j].index];
                }
            } else if (j == recordIndexH && !!record[i]) {
                output += record[i].wins + '\u2013' + record[i].losses;
                if (record[i].draws > 0 || record[i].nc > 0) {
                    output += '\u2013' + record[i].draws;
                    if (record[i].nc > 0) {
                        output += ' (' + record[i].nc + ')';
                    }
                }
            }
            output += '\n';
        }
    }

    tb.value = output + '{{end}}' + s.substring(tableEnd + 3);
}

addOnloadHook(function() {
    if (document.forms.editform) {
        mw.util.addPortletLink('p-tb', 'javascript:rearrangeMMARecordTable()', 'MMA record columns', 't-mmarecordcolumns', 'Rearrange the columns in accordance with {{MMA record start}}', '', '');
    }
});