User:Alien333/poemise.js

From Wikisource
Jump to navigation Jump to search
Note: After saving, changes may not occur immediately. Click here to learn how to bypass your browser's cache.
  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Cmd-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (Cmd-Shift-R on a Mac)
  • Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Clear the cache in Tools → Preferences

For details and instructions about other browsers, see Wikipedia:Bypass your cache.

/* global mw,$ */
"use strict";
mw.loader.using(['mediawiki.util'], () => { $(() => {
    if (mw.config.get('wgCanonicalNamespace') == 'Page' && mw.config.get('wgPageContentModel') == 'proofread-page' && ['edit', 'submit'].includes(mw.config.get('wgAction'))) {
    	var poemisebtn = mw.util.addPortletLink('p-tb', '#', 'Poemise', 'poemise-btn', 'Poemise.'); 
	    $(poemisebtn).click(event => { event.preventDefault(); poemise() });
	    if (mw.config.get("wgAction")=="submit") {
	    	diem();
	    }
    }
})});
var concat = (ll) => [].concat.apply([], ll); // merge array array
var multiplyArray = (arr, length) => Array.from({ length }, () => arr).flat();
var ins = (s, c) =>  (new RegExp("(?<=(\\]|^)[^\\[]*)\\"+c)).test(s);
var ind = (n) => ":".repeat(n);
var pr = (s) => // Process Rhyme pattern
	(s=="")?[]:
    (ins(s, "-"))?concat(s.split("-").map(pr)):
	(ins(s, "*"))?multiplyArray(pr(s.split("*").slice(1).join("*")), Number(s.split("*")[0])):
	(ins(s, ","))?concat(s.split(",").map(pr)):
	(s[0]=="!")?[ind(Number(s.slice(1)))]: // multiple-digit indent
	(s[0]=="'")?pr(s.slice(1)+"*0-."):
	(s[0]==":")?pr(s.slice(1)+"*01-."):
	(s[0]==".")?["."].concat(pr(s.slice(1))):
	(s[0]=="[")?[s.match(/.*?\]/)[0].slice(1, -1)].concat(pr(s.match(/\].*/)[0].slice(1))):
	(/^[0-9]/.test(s))?[ind(Number(s[0]))].concat(pr(s.slice(1))):["!"];
var getcookie = (s) => document.cookie.split(";").map(x => x.split("=")).filter(x => x[0].trim() == s)[0][1];
function poemise() { // apply poem formatting
    var l = $('#wpTextbox1').val().split("\n"); // list of lines
    var rhyme = (document.cookie.includes("poemise-last-pattern="))
    	?(pr(decodeURIComponent(getcookie("poemise-last-pattern")))) // use the cookie value
    	:[""]; 
    var ri = (document.cookie.includes("poemise-last-index=") && getcookie("poemise-last-index").split("|")[1] != encodeURI(mw.config.get("wgPageName"))) // don't reuse it if it's from this page
    	?(Number(getcookie("poemise-last-index").split("|")[0]))
    	:0;
    var ei = l.findIndex((ll) => ll[0] == "-"); // end index
    ei = (ei != -1)?ei:l.length;
    var after = l.slice(ei).join("\n").slice(1);
    l = l.slice(0, ei);
    var si = l.findIndex((ll) => ll[0] == "+" && !/\d|>/.test(ll[1])); // start index
    si = (si != -1)?si:0;
    var before = l.slice(0, si).join("\n");
    var anend = !l.some((ll) => /^\+?\$/.test(ll));
    l = ("\n" + l.slice(si).join("\n") + "\n")
    	.replaceAll(/\n[\+\$]+([^\d>])/g, "\n$1")
    	.trim().split("\n");
    l.forEach((ll) => {
    	if (ll[0] == "*") {
    		if (ll == "*") {
    			document.cookie = "poemise-last-pattern=;max-age=-1"; // erase the cookie
    			rhyme = [""];
    		} else {
	    		rhyme = pr(ll.slice(1).trim());
    			document.cookie = "poemise-last-pattern="+encodeURIComponent(ll.slice(1).trim()); // set the cookie
    		}
    	} else if (ll[0] == "/") {
    		if (ll == "/") {
    			document.cookie = "poemise-last-index=;max-age=-1";
    			ri = 0;
    		} else {
	    		ri = Number(ll.slice(1));
    		}
    	}
    });
    l = l.filter((ll) => ll[0] != "/" && ll[0] != "*").join("\n").trim().split("\n");
	if (rhyme.includes("!")) {
    	alert("Poemise: Parsing error: unknown one-character pattern");
    	return;
	} else if (!rhyme.some((e) => e != ".")) { // would go into infinite loop else, which is a bit annoying
    	alert("Poemise: Parsing error: the result indent pattern is only composed of stanza breaks");
    	return;
    }
    before = before || ("{{ppoem|\nstart="+((rhyme[(ri < 1)?(rhyme.length+ri-1):(ri-1)] == ".")?"stanza|":"follow|"));
    var [poem, li] = ["", 0]; // Line Index
    ri %= rhyme.length; // rhyme index
    while (li < l.length) {
        while (rhyme[ri] == ".") {
            poem += "\n";
            ri = (ri+1)%rhyme.length;
        }
        if (l[li] == " " ) l[li] = "";
        poem += rhyme[ri]+l[li];
        li += 1;
        while (li < l.length && (/[a-z]/.test(l[li][0]) || (l[li].length < 3 && l[li] != " "))) {
        	if (/[a-z]/.test(l[li][0])) {
        		if (/(?<!\-)\-$/.test(poem)) {
        			poem = poem.slice(0, -1);
        		} else {
	        		poem += " ";
        		}
        	}
        	poem += l[li];
        	li ++;
        }
        poem += "\n";
        ri = (ri+1) % rhyme.length;
    }
    after = after || (((anend)?("|end="+((rhyme[ri] == ".")?"stanza\n":"follow\n")):"")+"}}");
    document.cookie = "poemise-last-index="+((ri+((rhyme[ri] == ".")?1:0))%rhyme.length)+"|"+encodeURI(mw.config.get("wgPageName"));
    let res = before + "\n" + poem + after;
    try { res = clean(res) } catch (e) {}
    $('#wpTextbox1').val(res);
}
var diem = () => {
	let l = $(".ws-poem-line");
	let go = false;
	for (let e of l) {
		if (e.clientHeight > 22) {
			go = true;
			break;
		}
	}
	go = go && /\{\{(ppoem|tpp)\|.*?\{\{di\|.*?/s.test($("#wpTextbox1").val()) && $(".ws-poem-hi").width() != $(".ws-poem-hi").parent().width();
	if (go) {
		let em = /\{\{em\|?(\d+)?\}\}/.exec($("#wpTextbox1").val());
		$("#wpTextbox1").val(
			$("#wpTextbox1").val()
			.replace(/(.*\{\{di\|.*?)(\{\{em.*?\}\})?\n(.*)/, 
			"$1{{em"+(em?("|"+(Number(em[1]||"1")+1)):"")+"}}\n$3")
		);
		$("#wpPreview").trigger("click");
	}
};
var endshift = () => {
	let m = /^(.*?)(\|end=(follow|stanza)\n)?\}\}$/s.exec($("#wpTextbox1").val().trim());
	$("#wpTextbox1").val(m[1]+(m[3] ? (m[3] == "stanza" ? "" : "|end=stanza\n") : "|end=follow\n")+"}}");
};
var startshift = () => {
	let m = /^\{\{(ppoem|tpp)\|(\nstart=(follow|stanza)\|)?(.*?)$/s.exec($("#wpTextbox1").val().trim());
	$("#wpTextbox1").val("{{"+m[1]+"|"+(m[3] ? (m[3] == "stanza" ? "" : "\nstart=stanza|") : "\nstart=follow|")+m[4]);
};