User:Epicgenius/sortcategories.js: Difference between revisions
Appearance
Content deleted Content added
Epicgenius (talk | contribs) fix |
Epicgenius (talk | contribs) modify |
||
| Line 74: | Line 74: | ||
var preText = wpTextbox1_V.substr(0, categoriesStart); |
var preText = wpTextbox1_V.substr(0, categoriesStart); |
||
var trimmedPreText = preText.replace(/\s+$/, ""); |
var trimmedPreText = preText.replace(/\s+$/, ""); |
||
| ⚫ | |||
// Use no newline before categories if DEFAULTSORT exists; |
|||
var lastLine = |
|||
// otherwise, use exactly one newline. |
|||
lastNewLineIndex !== -1 |
|||
| ⚫ | |||
| ⚫ | |||
? "" |
|||
| ⚫ | |||
// Determine separator based on whether the line immediately |
|||
// above starts with a {{DEFAULTSORT}} template. |
|||
| ⚫ | |||
if (lastLine.trim().indexOf(defaultSort) === 0) { |
|||
| ⚫ | |||
| ⚫ | |||
var textWithCategories = wpTextbox1_V |
var textWithCategories = wpTextbox1_V |
||
| Line 173: | Line 165: | ||
textWithCategories = splitCategories.join("\n"); |
textWithCategories = splitCategories.join("\n"); |
||
// If a stub template occurs before the first category, |
|||
| ⚫ | |||
// ensure exactly one newline separates it from the category. |
|||
textWithCategories = "\n" + textWithCategories; |
|||
| ⚫ | |||
| ⚫ | |||
if ( |
if (lastStubIndex >= 0) { |
||
var textThroughLastStub = |
|||
| ⚫ | |||
textWithCategories + "\n\n"; |
|||
0, |
|||
lastStubIndex + stubTag.length |
|||
| ⚫ | |||
var textAfterLastStub = |
|||
trimmedPreText.substr( |
|||
lastStubIndex + stubTag.length |
|||
); |
|||
if (/^\s*$/.test(textAfterLastStub)) { |
|||
trimmedPreText = textThroughLastStub; |
|||
| ⚫ | |||
| ⚫ | |||
} |
} |
||
Revision as of 17:31, 9 October 2026
/*
See [[User:Alex 21/script-categoriessort.js]], original script by [[User:Alex 21]]
The main script page is [[User:Epicgenius/sortcategories.js]].
*/
// <nowiki>
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 ($) {
mw.loader.using(["mediawiki.util"]).then(function () {
var portletlink = mw.util.addPortletLink(
"p-tb",
"#",
"Sort categories"
);
$(portletlink).click(function (e) {
e.preventDefault();
var wpTextbox1 = document.getElementById("wpTextbox1");
var $wpTextbox1 = $("#wpTextbox1");
if (!wpTextbox1 || !$wpTextbox1.length) {
return;
}
// CodeMirror support, or an attempt at such
var activeElement = document.activeElement;
var inCodeMirror =
activeElement &&
activeElement.tagName === "DIV" &&
$(activeElement).hasClass("cm-content");
var wpTextbox1_V;
if (inCodeMirror) {
// Get the actual contents from CodeMirror.
wpTextbox1_V = $wpTextbox1.textSelection("getContents");
} else {
// Normal textarea.
wpTextbox1_V = wpTextbox1.value;
}
// Categories to check
var category = "[[Category:";
var categoryA = category + "A ";
var categoryAn = category + "An ";
var categoryThe = category + "The ";
var categoryEnd = "]]";
var categoryEponymous =
category + mw.config.get("wgTitle");
var defaultSort = "{{DEFAULTSORT:";
var stubTag = "-stub}}";
// Get the text up to the start of the categories,
// and then all of the text with the categories.
var categoriesStart = wpTextbox1_V.indexOf(category);
var categoriesEnd = wpTextbox1_V.lastIndexOf(categoryEnd);
// No categories found.
if (categoriesStart === -1 || categoriesEnd === -1) {
mw.notify("No categories found", { type: "info" });
return;
}
var preText = wpTextbox1_V.substr(0, categoriesStart);
var trimmedPreText = preText.replace(/\s+$/, "");
// Use no newline before categories if DEFAULTSORT exists;
// otherwise, use exactly one newline.
var separator = wpTextbox1_V.indexOf(defaultSort) >= 0
? ""
: "\n";
var textWithCategories = wpTextbox1_V
.substr(
categoriesStart,
categoriesEnd - categoriesStart + 2
)
.trim();
var textAfterCategories = wpTextbox1_V
.substr(categoriesEnd + 2)
.trim();
/*
* Categories should be on new lines, so split by new line,
* sort alphabetically with a few checks, then join again.
*
* Checks:
* - eponymous categories are listed first
* - categories are sorted without preceding "The", "A",
* or "An"
*/
var splitCategories = textWithCategories.split("\n");
splitCategories.sort(function (a, b) {
if (
a.substr(0, categoryEponymous.length) ===
categoryEponymous
) {
return -1e8;
}
if (
b.substr(0, categoryEponymous.length) ===
categoryEponymous
) {
return 1e8;
}
if (
a.substr(0, categoryThe.length) ===
categoryThe
) {
a = a.replace(categoryThe, category);
}
if (
b.substr(0, categoryThe.length) ===
categoryThe
) {
b = b.replace(categoryThe, category);
}
if (
a.substr(0, categoryA.length) ===
categoryA
) {
a = a.replace(categoryA, category);
}
if (
b.substr(0, categoryA.length) ===
categoryA
) {
b = b.replace(categoryA, category);
}
if (
a.substr(0, categoryAn.length) ===
categoryAn
) {
a = a.replace(categoryAn, category);
}
if (
b.substr(0, categoryAn.length) ===
categoryAn
) {
b = b.replace(categoryAn, category);
}
return a.localeCompare(b);
});
textWithCategories = splitCategories.join("\n");
// If a stub template occurs before the first category,
// ensure exactly one newline separates it from the category.
var lastStubIndex = trimmedPreText.lastIndexOf(stubTag);
if (lastStubIndex >= 0) {
var textThroughLastStub =
trimmedPreText.substr(
0,
lastStubIndex + stubTag.length
);
var textAfterLastStub =
trimmedPreText.substr(
lastStubIndex + stubTag.length
);
if (/^\s*$/.test(textAfterLastStub)) {
trimmedPreText = textThroughLastStub;
separator = "\n";
}
}
// Ensure any text after the final category is split
// onto its own line.
if (textAfterCategories !== "") {
textAfterCategories =
"\n" + textAfterCategories;
}
// Merge pre-category text back with the sorted category text.
var newContent =
trimmedPreText +
separator +
textWithCategories +
textAfterCategories;
// Write the result back.
if (inCodeMirror) {
$wpTextbox1.textSelection(
"setContents",
newContent
);
} else {
wpTextbox1.value = newContent;
}
setoptions(minor = "true");
setreason(
"sorted categories alphabetically via [[User:Epicgenius/sortcategories|script]]",
"append"
);
doaction("diff");
});
});
});
});
// </nowiki>