User:JPxG/TrackSum.js

//

// TrackSum v1.0

// If you are editing a page, this script gives you a button to click and automatically sum up all the track lengths in Template:Tracklist to provide a total length.

// Keep in mind that officially-released runtimes should be used if available. Some albums are longer or shorter than the sum of all track lengths.

// NOTE: This won't work if you have hh:mm:ss track lengths. I don't know if this ever happens, but if it does, they need to be in minutes.

// Of course, since 60 is 60, this will work on mm:ss as well as hh:mm track lengths, if they're all used consistently.

// Skeleton of this code forked from Wikipedia:WikiProject User scripts/Scripts/Quick wikify

// - JPxG, 2021 September 3

function getIndices(strang, substrang) {

var indices = [], i = -1;

while ((i = strang.indexOf(substrang, i+1)) != -1){

indices.push(i);

} // Close loop to increment over the strang.

return indices;

} // Function to get indices of a substring in a string.

function asMinSecs(input) {

strangMins = Math.floor(input / 60);

strangSecs = input - (strangMins * 60);

if (strangSecs < 10) {

return strangMins.toString() + ":0" + strangSecs.toString();

}

else {

return strangMins.toString() + ":" + strangSecs.toString();

}

} // Function to put out a string of minutes and seconds, given seconds as input.

function doTracksum() {

tbox = document.editform.wpTextbox1.value;

// Get the text from the edit box and store it as "tbox".

obox = "";

// Initialize blank output string.

var cursor = 0;

var allTotal = 0;

// Set cursor to zero.

var indax = getIndices(tbox, "{{tracklist");

indax = indax.concat(getIndices(tbox, "{{Tracklist"));

indax = indax.concat(getIndices(tbox, "{{Track listing"));

indax = indax.concat(getIndices(tbox, "{{Track Listing"));

indax = indax.concat(getIndices(tbox, "{{track listing"));

indax = indax.concat(getIndices(tbox, "{{Tracklisting"));

indax = indax.concat(getIndices(tbox, "{{tracklisting"));

indax = indax.concat(getIndices(tbox, "{{Soundtrack"));

indax = indax.concat(getIndices(tbox, "{{soundtrack"));

indax = indax.sort();

// We now have an array, "indax", of every index where a tracklist template appears.

obox = tbox.substring(0, indax[0]);

// Store everything before the first tracklist template into obox.

for (let i = 0; i < indax.length; i++){

if (i == indax.length){

j = indax.length;

} else {

j = indax[i+1];

}

slice = tbox.substring(indax[i], j);

openbraces = getIndices(slice, "{{");

closebraces = getIndices(slice, "}}");

allbraces = openbraces.concat(closebraces).sort();

lastbrace = allbraces[allbraces.length];

// Get the last of all braces in the slice.

braceStatus = 0;

lastInSlice = 0;

for(var incre = 0; incre < slice.length; incre++) {

if(openbraces.includes(incre)) {braceStatus++}

if(closebraces.includes(incre)) {braceStatus--}

if(braceStatus == 0) {lastInSlice = incre;break}

} // Try to find the closing brace of the whole darn slice. This is where we add the "total_length" param.

total = 0;

lengths = getIndices(slice, "|length");

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

lengths = lengths.concat(getIndices(slice, "| length"));

// 12345678901234567890

lengths = lengths.sort();

console.log(lengths);

// Now we have every index of "| length" in the template.

for(var len = 0; len < lengths.length; len++) {

time = 0;

lenstr = slice.substring(lengths[len], slice.indexOf("\n", lengths[len]));

// The string we're looking at is between that instance of "length" and the next line return.

lenstr = lenstr.substring(lenstr.indexOf("=")+1);

// Everything in that string after the "=".

lenstr = lenstr.trim();

// Remove spaces. Now it will just be "32:04" or "9:45" or whatever.

mins = lenstr.substring(0, lenstr.indexOf(":"));

secs = lenstr.substring(lenstr.indexOf(":")+1);

time = (parseInt(mins) * 60) + parseInt(secs);

total = total + time;

} // Read time out of the "length" parameter for every one we find.

allTotal = allTotal + total;

obox = obox + slice.substring(0,lastInSlice) + "| total_length = " + asMinSecs(total) + " \n" + slice.substring(lastInSlice);

// Reconstitute the tbox.

} // Everything in the darn obox.

//obox = obox + tbox.substring(indax[indax.length])

// Add the last bit of the tbox into obox.

document.editform.wpTextbox1.value = obox;

// document.editform.wpTextbox1.value = '{' + '{' + 'Wikify|date=' + '{' + '{' + 'subst:CURRENTMONTHNAME}} ' + '{' + '{' + 'subst:CURRENTYEAR}}}}\n\n' + document.editform.wpTextbox1.value;

document.editform.wpSummary.value = "Automatically summed track lengths (total length: " + asMinSecs(allTotal) + "), using script [JPxG's TrackSum V1.0]";

document.editform.wpMinoredit.checked = true;

//document.editform.submit();

} // function to replace the stuff with the other stuff

addOnloadHook(function() {

if (document.editform) {

mw.util.addPortletLink("p-cactions", "javascript:doTracksum()", "Tracksum", "ca-tracksum", "Sum up track lengths in tracklist template", "");

}

}); // onloadhook

//