User:Guywan/Scripts/BulletSort.js

// Category:Wikipedia scripts

//

$(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>/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]);

}

});

//