User:Guywan/Scripts/BulletSort.js
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.
// [[Category:Wikipedia scripts]]
// <nowiki>
$(function()
{
if(mw.config.get("wgAction") !== "edit") return;
const debug = true;
// Add key handler.
window.addEventListener("keyup", e =>
{
if(e.ctrlKey && e.altKey && e.which == 83) run();
});
function run()
{
mw.notify("Sorting...");
// Purely to allow 'Sorting...' to display before we start sorting.
// That's a 100 miliseconds you'll never get back.
setTimeout(() =>
{
try
{
const txtarea = document.getElementById("wpTextbox1");
const start = txtarea.selectionStart;
const end = txtarea.selectionEnd;
var lines = txtarea.value.substring(start, end).split("\n");
var level = "*";
if(debug) console.log(lines);
// (1) Create the tree.
var t = tree(level, lines)[0];
if(debug) console.log(t);
// (2) Sort the tree.
new mw.Api().parse(txtarea.value.substring(start, end).replace(/<ref.*?>.*?<\/ref>/g, ""))
.done((parsed) =>
{
parsed = parsed.replace(/(<\/?[^>]*>)|(<!--.*?-->)/g, "").split("\n");
if(debug) console.log(parsed);
var n = [];
for(var i = 0; i < lines.length; i++)
{
if(lines[i].startsWith("*"))
{
n.push(lines[i]);
}
}
map = {};
for(i = 0; i < n.length; i++)
{
map[n[i]] = parsed[i].trim();
}
if(debug) console.log(map);
sort(t.sort(compare));
// (3) Convert the tree back into a string and reset txtarea.
txtarea.value = txtarea.value.substring(0, start) + join(t) + txtarea.value.substr(end + 1);
mw.notify("Done!");
});
}
catch(e)
{
console.log(e);
mw.notify("Failed! See your console for more info.", {type: "error"});
}
}, 100);
}
function tree(level, list)
{
var branch = [];
for(var i = 0; i < list.length; i++)
{
var line = list[i];
const match = line.match(/^\*+/);
if(!match) // No level.
{
branch[branch.length - 1].append += line + "\n";
}
else if(match[0] == level) // Same level.
{
branch.push({"text": line, "append": "", "children": null});
}
else if(match[0] == level + "*") // Lower level.
{
var result = tree(level + "*", list.slice(i));
branch[branch.length - 1].children = result[0];
i += result[1] - 1;
}
else // Upper level.
{
return [branch, i];
}
}
return [branch, i];
}
function sort(list)
{
for(var i = 0; i < list.length; i++)
{
if(list[i].children !== null && list[i].children !== undefined)
{
list[i].children.sort(compare);
sort(list[i].children);
}
}
}
function join(list)
{
var joined = "";
for(var i = 0; i < list.length; i++)
{
joined += list[i].text + "\n" + list[i].append;
if(list[i].children !== null)
{
joined += join(list[i].children);
}
}
return joined;
}
function compare(a, b)
{
return map[a.text].localeCompare(map[b.text]);
}
});
// </nowiki>