User:Epicgenius/capitalize.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump.
This code will be executed when previewing this page.
This code will be executed when previewing this page.
This user script seems to have a documentation page at User:Epicgenius/capitalize.
mw.loader.using("mediawiki.util", function () {
// Only run script if user is editing an article
if (!document.forms.editform || (mw.config.get("wgAction") !== "edit" && mw.config.get("wgAction") !== "submit")) {
return;
}
(function () {
'use strict';
// List of words to remain lowercased in title case mode
const smallWords = new Set([
'a',
'an',
'and',
'as',
'at',
'but',
'by',
'for',
'in',
'nor',
'of',
'on',
'or',
'the',
'to',
'up',
'via',
'with'
]);
// List of acronyms to remain uppercased in sentence,
// title, and capitalized case modes.
// I might add proper nouns later, too.
const largeWords = new Set([
// 'US$',
// 'CA$',
// 'NZ$',
'ASAP',
'ATM',
'CEO',
'CFO',
'CIA',
'COO',
'DIY',
'DVD',
'FAQ',
'FBI',
'FEMA',
'GPS',
'HTML',
'HTTP',
'MD',
'MI6',
'MP3',
'NASA',
'NATO',
'OSHA',
'PDF',
'PhD',
'POTUS',
'SCOTUS',
'TBA',
'TBD',
'URL',
'USA',
'USB',
'VIP',
'WiFi'
]);
// Map of lowercase form -> canonical capitalization, shared
// by all case-conversion functions below.
const largeWordsLower = new Map(
Array.from(largeWords, function (word) {
return [word.toLowerCase(), word];
})
);
// Regex that matches any acronym case-insensitively, used to restore
// its capitalization after a lowercase conversion.
const largeWordsPattern = new RegExp(
'\\b(' + Array.from(largeWords, function (word) {
return word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}).join('|') + ')\\b',
'gi'
);
// Restore the canonical capitalization of any acronyms
// found in the given (already case-converted) text.
function restoreLargeWords(text) {
return text.replace(largeWordsPattern, function (match) {
return largeWordsLower.get(match.toLowerCase()) || match;
});
}
// Convert text to sentence case.
// The first alphabetical character after the beginning of the
// selection, or after . ! ?, is capitalized. Other characters
// are converted to lowercase. Acronyms keep their defined
// capitalization regardless of where they appear.
function sentenceCase(text) {
text = text.toLowerCase();
let capitalizeNext = true;
text = text.replace(/[A-Za-zÀ-ÖØ-öø-ÿ]/g, function (char) {
if (capitalizeNext) {
capitalizeNext = false;
return char.toUpperCase();
}
return char;
}).replace(/([.!?]\s+)([a-zà-öø-ÿ])/g, function (match, punctuation, letter) {
return punctuation + letter.toUpperCase();
});
return restoreLargeWords(text);
}
// Convert text to title case.
// Small connecting words such as "a", "an", "the", "of",
// "and", etc. remain lowercase unless they are the first
// or last word.
function titleCase(text) {
const words = text.toLowerCase().split(/(\s+)/);
let wordIndex = 0;
const actualWords = words.filter(function (part) {
return /\S/.test(part);
}).length;
return words.map(function (part) {
// Preserve whitespace exactly as it was.
if (!/\S/.test(part)) {
return part;
}
const lowerWord = part;
const isFirstWord = wordIndex === 0;
const isLastWord = wordIndex === actualWords - 1;
wordIndex++;
// Remove punctuation from the beginning/end when
// determining the actual word.
const match = lowerWord.match(
/^([^A-Za-zÀ-ÖØ-öø-ÿ0-9]*)(.*?)([^A-Za-zÀ-ÖØ-öø-ÿ0-9]*)$/
);
if (!match) {
return lowerWord;
}
const prefix = match[1];
const word = match[2];
const suffix = match[3];
// Ordinals such as 1st, 2nd, 3rd, 4th, 21st, etc.
// are kept entirely lowercase.
if (/^\d+(?:st|nd|rd|th)$/.test(word)) {
return prefix + word + suffix;
}
// Preserve acronyms and other defined large words.
if (largeWordsLower.has(word)) {
return prefix + largeWordsLower.get(word) + suffix;
}
if (
!isFirstWord &&
!isLastWord &&
smallWords.has(word)
) {
return prefix + word + suffix;
}
return (
prefix +
word.charAt(0).toUpperCase() +
word.slice(1) +
suffix
);
}).join('');
}
function capitalizedCase(text) {
const words = text.toLowerCase().split(/(\s+)/);
return words.map(function (part) {
// Preserve whitespace exactly as it was.
if (!/\S/.test(part)) {
return part;
}
const lowerWord = part;
// Remove punctuation from the beginning/end when
// determining the actual word.
const match = lowerWord.match(
/^([^A-Za-zÀ-ÖØ-öø-ÿ0-9]*)(.*?)([^A-Za-zÀ-ÖØ-öø-ÿ0-9]*)$/
);
if (!match) {
return lowerWord;
}
const prefix = match[1];
const word = match[2];
const suffix = match[3];
// Ordinals such as 1st, 2nd, 3rd, 4th, 21st, etc.
// are kept entirely lowercase.
if (/^\d+(?:st|nd|rd|th)$/.test(word)) {
return prefix + word + suffix;
}
// Preserve acronyms and other defined large words.
if (largeWordsLower.has(word)) {
return prefix + largeWordsLower.get(word) + suffix;
}
return (
prefix +
word.charAt(0).toUpperCase() +
word.slice(1) +
suffix
);
}).join('');
}
// Convert the current selection in Wikipedia's source editor.
function convertSelection(mode) {
const textArea = document.getElementById('wpTextbox1');
if (!textArea) {
return;
}
const start = textArea.selectionStart;
const end = textArea.selectionEnd;
// Nothing has been selected.
if (start === end) {
return;
}
// Get the selected text.
const selectedText = textArea.value.substring(start, end);
let convertedText;
switch (mode) {
case 'upper':
convertedText = selectedText.toUpperCase();
break;
case 'lower':
convertedText = selectedText.toLowerCase();
break;
case 'sentence':
convertedText = sentenceCase(selectedText);
break;
case 'title':
convertedText = titleCase(selectedText);
break;
case 'capitalized':
convertedText = capitalizedCase(selectedText);
break;
default:
return;
}
// Replace the selection with the converted text.
//
// "select" keeps the newly converted text selected.
textArea.setRangeText(
convertedText,
start,
end,
'select'
);
// Return focus to the editing field.
textArea.focus();
}
// Add a link to the sidebar.
function addLink(id, label, tooltip, mode) {
const link = mw.util.addPortletLink(
'p-tb',
'#',
label,
id,
tooltip
);
if (!link) {
return;
}
link.addEventListener('click', function (event) {
event.preventDefault();
convertSelection(mode);
});
}
// Create the sidebar links.
function initialize() {
addLink(
'case-converter-uppercase',
'To UPPERCASE',
'Convert the selected text to uppercase',
'upper'
);
addLink(
'case-converter-lowercase',
'To lowercase',
'Convert the selected text to lowercase',
'lower'
);
addLink(
'case-converter-sentence',
'To Sentence case',
'Convert the selected text to sentence case',
'sentence'
);
addLink(
'case-converter-title',
'To Title Case',
'Convert the selected text to title case',
'title'
);
addLink(
'case-converter-capitalized',
'To Capitalized Case',
'Convert the selected text to capitalized case',
'capitalized'
);
}
// Wait until MediaWiki's interface is ready.
$(initialize);
})();
});