User:Jeblad/ve-autocorrect/script.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
// @provenance [[Benutzer:Schnark/js/veAutocorrect.js]]
/*global mediaWiki, OO, ve*/
(function (mw) {
"use strict";
var VISUAL = 1, SOURCE = 2, deps;
function initAutoCorrect (lang, wiki) {
var autoCorrectCommandCount = 0, quotes, i;
//like ve.ui.Sequence, with the difference that for regular expressions
//of the form /foo(bar)/ only the parentheses is used as Range, not the whole expression
function ReSequence () {
ReSequence.parent.apply(this, arguments);
}
OO.inheritClass(ReSequence, ve.ui.Sequence);
ReSequence.prototype.match = function (data, offset, plaintext) {
var execResult;
if (this.data instanceof RegExp) {
execResult = this.data.exec(plaintext);
return execResult && new ve.Range(offset - execResult[1].length, offset);
}
return ReSequence.parent.prototype.match.apply(this, arguments);
};
//when the user enters "from" change it to "to"
//from can be a string, a regular expression of the form /foo(bar)/ or an array of data
//to can be a string or an array of data
//strip is the number of chars to strip
//mode defaults to both VISUAL and SOURCE
function autoCorrectFromTo (from, to, strip, mode) {
//get a unique name, we use it for both the command and the sequence
var name = 'veAutoCorrectCommand-' + (autoCorrectCommandCount++), seq;
//create and register the command
ve.ui.commandRegistry.register(
//1st true: annotate, 2nd true: collapse to end
new ve.ui.Command(name, 'content', 'insert', {args: [to, true, true]})
);
//create and register the sequence
seq = new ReSequence(/*sequence*/ name, /*command*/ name, from, strip);
if (!mode || mode === VISUAL) {
ve.ui.sequenceRegistry.register(seq);
}
if ((!mode || mode === SOURCE) && ve.ui.wikitextSequenceRegistry) {
ve.ui.wikitextSequenceRegistry.register(seq);
}
}
//define what should be autocorrected
quotes = {
de: ['„', '“'],
en: ['“', '”'],
no: ['«', '»'],
nn: ['«', '»']
};
//test
//autoCorrectFromTo(/\s"/, 'c\1', 2, VISUAL);
//for all languages and projects
autoCorrectFromTo(/(?:^|[^!])(--)$/, '–', 2); //don't mess with <!--
autoCorrectFromTo('–>', '-->', 2, SOURCE); //fix --> (only needed for source code)
autoCorrectFromTo('–-', '—', 2); //--- with -- turned into –
autoCorrectFromTo('—-', '----', 2, SOURCE); //keep ---- in source code
autoCorrectFromTo('...', '…', 3);
autoCorrectFromTo('<<', '«', 2);
autoCorrectFromTo('>>', '»', 2);
autoCorrectFromTo('->', '→', 2);
autoCorrectFromTo(' 1/2 ', ' ½ ', 5);
autoCorrectFromTo(' 1/4 ', ' ¼ ', 5);
autoCorrectFromTo(' 3/4 ', ' ¾ ', 5);
autoCorrectFromTo('+-', '±', 2);
autoCorrectFromTo(/\d(')$/, '′', 1);
for (i = 0; i <= 9; i++) { //fix 1'234'567
autoCorrectFromTo('′' + i, '\'' + i, 2);
}
autoCorrectFromTo(/\D(')$/, '’', 1, VISUAL);
autoCorrectFromTo(/[^0-9'](')$/, '’', 1, SOURCE); //italic/bold syntax
autoCorrectFromTo(/([′’]\')$/, '\'\'', 2, SOURCE); //fix italic/bold syntax
autoCorrectFromTo(/\d(")$/, '″', 1, VISUAL);
autoCorrectFromTo(/(?:^|=\s*"[^"]*")[^=]*(?:=\s*(?:[^" ]|"[^"]*")[^=]*)*\d(")$/, '″', 1, SOURCE); //not in attributes
//(?:^|=\s*"[^"]*") - anchor at the start of the line or a quoted attribute
//[^=]* - skip chars that aren't equal signs
//=\s*(?:[^" ]|"[^"]*") - equal sign either not followed by quote mark or with complete quoted attribute
//depending on the content language
if (quotes.hasOwnProperty(lang)) {
autoCorrectFromTo(/(?:^|[( \n])(")$/, quotes[lang][0], 1, VISUAL);
autoCorrectFromTo(/(?:^|=\s*"[^"]*")[^=]*(?:=\s*(?:[^" ]|"[^"]*")[^=]*)*(?:^|[( \n])(")$/, quotes[lang][0], 1, SOURCE);
autoCorrectFromTo(/[^\d( \n](")$/, quotes[lang][1], 1, VISUAL);
autoCorrectFromTo(/(?:^|=\s*"[^"]*")[^=]*(?:=\s*(?:[^" ]|"[^"]*")[^=]*)*[^\d( \n=](")$/, quotes[lang][1], 1, SOURCE);
}
//depending on the wiki
/*jshint onecase: true*/
switch (wiki) {
case 'nowiki':
autoCorrectFromTo([{type: 'paragraph'}, '=', 'r', 'e' ], [
{type: 'heading', attributes: { level: 2 } },
'Referanser',
{type: '/heading'},
{type: 'mwReferencesList', attributes: { refGroup: '' } },
{type: '/mwReferencesList'}
], 3, VISUAL);
autoCorrectFromTo([{type: 'paragraph'}, '=', 'n', 'o' ], [
{type: 'heading', attributes: { level: 2 } },
'Noter',
{type: '/heading'},
{type: 'mwReferencesList', attributes: { refGroup: 'note' } },
{type: '/mwReferencesList'}
], 3, VISUAL);
autoCorrectFromTo([{type: 'paragraph'}, '=', 'o', 'g' ], [
{type: 'heading', attributes: { level: 2 } },
'Se også',
{type: '/heading'},
], 3, VISUAL);
autoCorrectFromTo([{type: 'paragraph'}, '=', 'l', 'i' ], [
{type: 'heading', attributes: { level: 2 } },
'Litteratur',
{type: '/heading'},
], 3, VISUAL);
autoCorrectFromTo([{type: 'paragraph'}, '=', 'e', 'k' ], [
{type: 'heading', attributes: { level: 2 } },
'Eksterne lenker',
{type: '/heading'},
{type: 'mwTransclusionInline',
attributes: {
mw: {
parts: [
{
template: {
target: {
href: 'Template:Offisielt nettsted',
wt: 'Offisielt nettsted'
},
params: {}
}
}
]
}
}
}
], 3, VISUAL);
}
}
deps = ['ext.visualEditor.core'];
if (mw.libs.ve.isWikitextAvailable) {
deps.push('ext.visualEditor.mwwikitext');
}
mw.loader.using(deps).done(function () {
initAutoCorrect(mw.config.get('wgContentLanguage'), mw.config.get('wgDBname'));
mw.hook('userjs.script-ready.veAutocorrect').fire();
});
})(mediaWiki);