Jump to content

User:IceWelder/citationstyle.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.
// <nowiki>
// NOTICE: This script is a fork of Meteor sandwich yum's Tidy citations script, all credit goes to them
/**
 * This script is used to clean up whitespace in citation templates
 * Please leave bug reports and suggestions on my talk page
 */

/**
 * TemplateScript adds configurable templates and scripts to the sidebar, and adds an example regex editor.
 * @see https://meta.wikimedia.org/wiki/TemplateScript
 * @update-token [[File:Pathoschild/templatescript.js]]
 */
$.ajax('//tools-static.wmflabs.org/meta/scripts/pathoschild.templatescript.js', {
    dataType: 'script',
    cache: true
}).then(function () {
    pathoschild.TemplateScript.add([
        {
            category: 'Citation Style', name: '{{Tidy}}', isMinorEdit: true, script: function (editor) {
                format_citations(editor, 'tidy', false);
            }
        },
        {
            category: 'Citation Style', name: '{{Tidy}} (vertically)', isMinorEdit: true, script: function (editor) {
                format_citations(editor, 'tidy', true);
            }
        },
        {
            category: 'Citation Style', name: '{{Crammed}}', isMinorEdit: true, script: function (editor) {
                format_citations(editor, 'crammed', false);
            }
        },
        {
            category: 'Citation Style', name: '{{Crammed}} (vertically)', isMinorEdit: true, script: function (editor) {
                format_citations(editor, 'crammed', true);
            }
        },
        {
            category: 'Citation Style', name: '{{Roomy}}', isMinorEdit: true, script: function (editor) {
                format_citations(editor, 'roomy', false);
            }
        },
        {
            category: 'Citation Style', name: '{{Roomy}} (vertically)', isMinorEdit: true, script: function (editor) {
                format_citations(editor, 'roomy', true);
            }
        }
    ]);
});

/** ------------------------------------------------------------------------ **/

function format_citations(editor, variation, vertical) {
    var text = editor.get();
    var original = text;

    // Fill an array with one entry per each recognized citation template
    var originalTemplates = text.match(/\s*{{[Cc]it(?:ation|e[a-zA-Z0-9\-_\s]+)\s*\|(?:{{[^}]*}}|[^}])+}}\s*/g) || [];

    // Duplicate the array for editing; we need to keep the original strings for the replacement step
    var tweakedTemplates = originalTemplates.slice();

    var replace_regex = /\s*\|\s*([a-zA-Z0-9\-_\s]+(?: [a-zA-Z0-9\-_\s])*)\s*=\s*/g;
    var format_parameter = function (prefix, group, suffix) {
        return (vertical ? '\n' : '') + prefix + group.replace(/(?:^\s*|\s*$)/g, '') + suffix;
    };

    for (var i = 0; i < originalTemplates.length; ++i) {
        // Normalize spaces around the pipes and equals signs
        switch (variation) {
            case 'tidy':
                tweakedTemplates[i] = tweakedTemplates[i].replace(replace_regex, function (match, group) {
                    return format_parameter(' |', group, '=');
                });
                break;
            case 'crammed':
                tweakedTemplates[i] = tweakedTemplates[i].replace(replace_regex, function (match, group) {
                    return format_parameter('|', group, '=');
                });
                break;
            case 'roomy':
                tweakedTemplates[i] = tweakedTemplates[i].replace(replace_regex, function (match, group) {
                    return format_parameter(' | ', group, ' = ');
                });
                break;
        }

        // Prepend newlines for vertical align
        if (vertical) {
            tweakedTemplates[i] = '\n' + tweakedTemplates[i];
        }

        // Align end of the template
        if (!vertical) {
            tweakedTemplates[i] = tweakedTemplates[i].replace(/\s*}}(\s*)$/g, '}}$1');
        } else {
            tweakedTemplates[i] = tweakedTemplates[i].replace(/\s*}}(\s*)$/g, '\n}}$1');
        }

        // Normalize multiple spaces to one
        tweakedTemplates[i] = tweakedTemplates[i].replace(/  +/g, ' ');

        // Replace the original templates with the tweaked versions
        text = text.replace(originalTemplates[i], tweakedTemplates[i]);
    }

    // Normalize ref tag capitalization
    text = text.replace(/<ref/gi, '<ref');
    text = text.replace(/<\/ref/gi, '</ref');

    // Normalize newlines between citation templates and ref tags
    text = text.replace(/(<ref(?:(?!>|\/>).)*>)\s*{{/g, '$1{{');
    text = text.replace(/}}\s*<\/ref>/g, '}}</ref>');

    // Only insert the edit summary when something has changed
    if (text !== original) {
        editor.set(text);
        editor.appendEditSummary('harmonize whitespace in citation templates by [[w:User:IceWelder/citationstyle.js|script]]');
        editor.clickDiff();
    }
}
// </nowiki>