Jump to content

User:Quarl/date canonicalize.js

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by Quarl (talk | contribs) at 08:54, 1 February 2006 (〈"joinRE(" → "'\b'+joinRE(", ");" → ") + '\b';"〉word boundaries). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

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.
// [[User:Quarl/date_canonicalize.js]] - canonicalizes date WikiLinks

//  Example: July 17, 1982 becomes [[1982-07-17]]

// requires: wikipage.js, util.js, addlilink.js, datetime.js

// quarl 2006-01-31 initial version

//<pre><nowiki>

date_canonicalize = new Object();

date_canonicalize.run = function() {
    wikiPage.getEditorAsync(date_canonicalize.edit);
}

date_canonicalize.edit = function(editor) {
    // make changes

    var result = '';
    var input = editor.wpTextbox1;
    var changes = [];

    result = date_canonicalize.canonicalizeString(input, changes);

    if (changes.length) {
        editor.wpTextbox1 = result;
        editor.wpSummary = 'date canonicalization: ' + changes.join('; ');
        editor.wpMinoredit = true;
        editor.submit('wpDiff');
    } else {
        alert("No changes to make!");
    }
}

// Return a string for a regexp that matches possibly wiki-linked dates in
// various date formats.  This is a monster regexp, the hardest part of this
// script!
date_canonicalize.buildDateRegexp = function() {

    var groupIfNeccessary = function(s) {
        if (s.match(/\|/) && !s.match(/^\(/)) {
            return '(?:' + s + ')';
        } else {
            return s;
        }
    }

    var joinRE = function() {
        // desplice arguments
        var args = Array.concat.apply(Array, arguments).map(groupIfNeccessary);

        return '(?:' + args.join('|') + ')';
    }

    var linked = function(s) {
        return '\\[\\[ *'+s+' *\\]\\]';
    }

    var maybelinked = function(s) {
        return joinRE(s, linked(s));
    }

    var abbrevMonth = function(s) {
        return s.substr(0,3);
    }

    var year4 = '[012][0-9][0-9][0-9]';
    var year42 = joinRE(year4, '[890][0-9]');
    var month = joinRE('0?[1-9]', '1[012]');
    // monthnames is in datetime.js
    var monthS = joinRE(monthnames, monthnames.map(abbrevMonth));
    var day = '[0123]?[0-9](?:st|nd|th)?';

    var delimz = '[ ,/-]+';

    return '\b'+joinRE(
        // YYYY-MM-DD formats
        linked( year4 + '-' + month + '-' + day ),
        maybelinked(year4)+'-'+maybelinked(month+'-'+day),
        maybelinked(year4)+'/'+month+'/'+day,
        maybelinked(year4)+'\\.'+month+'\\.'+day,
        year4 + ' ' + month + ' ' + day,

        maybelinked(year4 + delimz + monthS + delimz + day),

        // MM-DD-YYYY formats
        month + '-' + day + '-' + year4,
        month + '/' + day + '/' + year42,

        linked(monthS + delimz + day + delimz + year42),
        maybelinked(monthS + delimz + day) + delimz + maybelinked(year42),

        // DD-MM-YYYY formats: only support monthS, because it's ambiguous
        // otherwise
        linked( day + delimz + monthS + delimz + year4 ),
        maybelinked(day + delimz + monthS) + delimz + maybelinked(year4)
        ) + '\b';
}

date_canonicalize.canonicalizeString = function(input, changes) {
    var result = '';

    var date_regexp = new RegExp(this.buildDateRegexp(),'i');

    while (input.match(date_regexp)) {
        var left = RegExp.leftContext;
        var match = RegExp.lastMatch;
        var right = RegExp.rightContext;

        var m = date_canonicalize.canonicalizeDate(match);
        if (!m) {
            m = match;
        } else if (m != match) {
            changes.push('"'+match+'" → "'+m+'"');
        }

        result += left;
        result += m;
        input = right;
    }
    result += input;
    return result;
}

date_canonicalize.canonicalizeDate = function(s) {
    s = s.replace(/[\[\]]/g, '');
    s = s.replace(/[-.]/g, '/'); // Date only understands '/' as delimiter
    var d = new Date(s); // parses date string

    if (!d.getFullYear()) {
        // couldn't parse
        return null;
    }

    return '[[' + datestampUTCISO(d) + ']]';
}

date_canonicalize.load = function() {
    if (wikiPage.nsSpecialP) return;
    addTab('javascript:date_canonicalize.run()', 'datez', 'ca-datez', 'Canonicalize dates');
}

addOnloadHook(date_canonicalize.load);

//</nowiki></pre>