Stories
Slash Boxes
Comments

SoylentNews is people

Log In

Log In

Create Account  |  Retrieve Password


What's Got Voat's Goat?

Posted by GungnirSniper on Monday July 06 2015, @02:14AM (#1325)
3 Comments
Techonomics

With the upheaval at Reddit, it seems Voat.co should be thriving as the heir apparent. Yet it seems like every time I try to visit them, they are overloaded. I'm not sure what's going on, but it's clear they have a huge opportunity here and are apparently squandering it.

Syriza continues to impress

Posted by Yog-Yogguth on Saturday June 27 2015, @05:22PM (#1310)
6 Comments
News

N.b. since this is filled to the brim with my own opinion and reactions it doesn't suit being submitted as a story, great for a journal entry though :)

Syriza (a Greek acronym of what would be something like “The Coalition of the Radical Left” in English) is the main and largest party in the current coalition government in Greece. With a name like that (and lots and lots of ideology that I'm rather allergic to XD) I wasn't enthusiastic when they won the Greek election, I thought they would be like so many others who describe themselves in the same manner (there are always exceptions though, I know that).

But my misgivings have been put to shame! Time and time again they've obviously done their best to protect and champion the interests of Greece against the so-called “austerity” dictated by the EU and other scum like the IMF. “Austerity” which only ever seems to target those who are already living sparse and austere lives. “Austerity” which shrinks the economy as those most likely to spend any money they have on essential goods get even less money to spend. “Austerity” which continues to regress any remnants of national sovereignty into iron clad bureaucracy at the beck and call of the constantly manipulating and transnational “free actors” of “global commerce” (warning shadows of the steadfastly approaching horrors of TTIP and TPP).

It also helped put me at ease when I discovered that the tiny party I would be most likely to vote for if I was Greek was part of the government coalition. That party would be the “new/alternative right” ANEL or “Independent Greeks”.

Now RT reports that the Greek government has taken it even further towards actual democracy and announced a referendum to be held for people to vote in favor or against the debt deal that is being offered to Greece. The Greek people will instruct the Greek government as is appropriate in any democracy.

Thank you Greece, thank you Syriza, and thank you ANEL, your sensibility is shining one of the few lights and perhaps one of the brightest in a rather dismally dark and depressing world, may you continue down this path ♥

Banning history is as fascist as burning books

Posted by Yog-Yogguth on Saturday June 27 2015, @08:03AM (#1309)
2 Comments
News

That's all I really wanted to say.

TS;RM! (Too Short; Rant More!)

Yeah I need to get this off my chest.

  • First:

    Although certainly a central topic those who think the US civil war /as a war/ was about the emancipation of slaves rather than a war over secession and declaration of independence are as ignorant or malicious as those who think the second world war was fought on account of rescuing jews and other holocaust victims rather than a war fought to liberate invaded countries and territory.

    The victims of both are the ones that ought to be the most offended over such examples of blatant rewriting of history aimed solely at falsely glorifying the victors and endowing them with attributes they never had. The history and even more so the history of the victims (slaves, jews, slavic people, homosexuals, the seriously ill, the debilitated, anyone who stuck their neck out etc.) is being reduced to a lie.

  • Second:

    The US attempts at removal of the use of the confederate flag (which belongs to everyone living in the states that tried to break free from the US) is an example of cultural theft equal to that of the (continued) nazi appropriation and gross abuse of pan-germanic and pagan symbols like sun-wheels (like swastikas) and runes (which belongs to everyone in non-roman Europe in particular but also humanity in general).

  • Third:

    Unfortunate and wasteful as it is the US and NATO is now clearly first and foremost fascist just as the Soviet Union and Warsaw pact was fascist and as the Third Reich and Axis powers were fascist and that's true no matter how offensive it might feel feels to Germans (few of them complain, denial is rare), Russians (some of them complain, denial is still somewhat common), or Usians (almost everyone will complain, denial is “truth”).

To me it is as if during the last 16 years the world has lost between 200 and 300 years of progress paid for in blood and suffering by billions of humans. But of course that's not the case: it probably wasn't widespread in the first place and “everyone” just rode on the coattails of a few of the less idiotic humans having a somewhat brief period of actual influence and power. Well that era is done and gone that's for sure :C

Epoch Init System 1.3.0 "Fluoxetine" released.

Posted by Subsentient on Friday June 26 2015, @07:33AM (#1305)
2 Comments
Code

So I released one of the biggest updates ever for Epoch a couple days ago. As of writing I have yet to update the site documentation, but I thought I'd recap some of the new stuff.

* Basic dependency support. ObjectStartPriority=sshd+1 for example. This is the most requested feature for Epoch of all time.
* 'epoch merge' and 'epoch unmerge' commands to automatically add or delete a config Import= line from epoch.conf, which will help distro maintainers.
* Ability to change logfile location via the LogFile= config attribute.
* Ability to skip or start objects from the kernel command line via skipobj= and startobj=
* New "interactive" mode for boot which mimics old Red Hat releases' "press I for interactive startup" thing with sysvinit. All objects intended to be interactive must have ObjectOptions=INTERACTIVE set.
* Ability to ignore all kernel options passed to Epoch, useful for initramfs. Depends on existence of /.epochnokargs file.
* Added option to ignore when a MountVirtual (e.g. /proc, /sys, /dev. /dev/pts, or /dev/shm) fails to mount.
* Ability to specify the amount of time that should be considered too soon for a service to be auto-restarted.
* Fixed problems with colors and 'less' command. 'epoch help' now returns without color, and 'epoch statusnc' can be used to view status without color. I prefer color because it's easier for me to see at a glance, but now you have the choice.
* Added makefile support, which just calls ./buildepoch.sh. There is also a make clean and you can specify options to buildepoch.sh with 'make BUILDOPTS="--myoption"'.
* Epoch now compiles as C99. I was getting too happy with my nice C99 // comments.

This is probably the biggest update I've released since 1.0.0 "Sage".

Get it while it's hot.

http://universe2.us/epoch.html

200,000 Comments

Posted by GungnirSniper on Tuesday June 23 2015, @03:57PM (#1300)
6 Comments
Soylent

Looks like we're about to hit 200,000 posts today.

The burden of male minds

Posted by Subsentient on Tuesday June 23 2015, @06:56AM (#1298)
2 Comments
/dev/random

Sometimes I envy women for one thing: the freedom to be kind, to enjoy sweet, cute things, to be amusingly deranged, and to like whatever they want. I'll clear things up, I'm not gay, nor trans, or anything like that.

My complaint is that many of my peers think there's something wrong with giving a fuck about others, about being vegetarian, or about liking cute little videos made by some random youtuber nobody else ever heard of.

Let's see. I am:

* Kind, and try extremely hard at it.
* Vegetarian with a side of vegan. I avoid dairy and eggs but will eat it if provided to me. I will never eat meat.
* Goofy as hell, to the point of people questioning my sanity.
* A lover of adorable things. My favorite animal is the rat. The best possible pet. I also love cats, ironically.
* Mildly autistic, which I mostly outgrew.
* A lover of music from Enya to Creed to Glitch Mob to Bassnectar, with a deep love of post-dubstep.
* A socialist, a political choice motivated by compassion for others.
* Slow to anger, but tend to explode when my threshold is reached.
* Easygoing, with a sedate, laid back lifestyle and world view.
* Usually not wearing a shirt with any insignia whatsoever. I go plain.
* A brutal god-tier player in Warzone 2100, a game which I deeply love.
* A deist, but with a deep, deep respect for Jesus, willing to defend his name. The old testament is manure to me.
* The kind of philosophical mind who can find the meaning of life on a shampoo bottle.
* A Linux using programmer who built and uses his own XFCE distro from source code, and no, not LFS or Gentoo.
* A bit overweight, but not obese. I have a gut. I don't tend to mind fat jokes unless they are intended to insult.
* Not prone to judge a person by anything other than their ethics, which is one thing I will judge the shit out of them for.
* Slightly lazy.

I am not:

* A pussy. I've frequently made threats of grinding my enemies into cat food and feeding them to their grandmother.
* A faggot. I like the ladies, unfortunately they don't like me.
* A left-wing nutcase. I don't even like abortion.
* An atheist. I believe in a greater concept of God.
* A hardcore gamer. There are few games I play, and my most recent console is a PSP fat. I mostly do Warzone 2100 and Nintendo 64 emulation.
* A tech god. There's much I want to learn and I'll feel inadequate until I do.
* A hipster. Don't fucking say it. I have a beard, but you won't see me wearing slogan T-shirts, and I suck at identifying music. I don't have strong opinions on arts.

I just wanted to vent. I am what I am. I am Subsentient.

Night Mode Default

Posted by GungnirSniper on Wednesday June 17 2015, @04:55AM (#1288)
5 Comments
Rehash

On the old green site I've seen a few complaints about the default theme here. Maybe it would be worthwhile to switch to Night Mode as the default?

Soylent Upgrade Greasemonkey/Tampermonkey extension v9.1

Posted by takyon on Monday June 15 2015, @10:39PM (#1286)
1 Comment
Code

// ==UserScript==
// @name Soylent Upgrade
// @match http://soylentnews.org/*article.pl*
// @match https://soylentnews.org/*article.pl*
// @match http://soylentnews.org/submit.pl*
// @match https://soylentnews.org/submit.pl*
// @match http://soylentnews.org/admin.pl*
// @match https://soylentnews.org/admin.pl*
// @match http://soylentnews.org/*comments.pl*
// @match https://soylentnews.org/*comments.pl*
// @match http://soylentnews.org/journal.pl*
// @match https://soylentnews.org/journal.pl*
// ==/UserScript==

// User Options:

var simplifyChars = true; // Change to false if you don't want stylized quotation marks, ellipses, etc. to be replaced
var stripEmail = false; // Remove auto-filled email from submission

// End User Options

/* ! http://mths.be/fromcodepoint v0.1.0 by @mathias */
if (!String.fromCodePoint) { (function() { var defineProperty = (function() { try { var object = {}; var $defineProperty = Object.defineProperty; var result = $defineProperty(object, object, object) && $defineProperty; } catch(error) {} return result; }()); var stringFromCharCode = String.fromCharCode; var floor = Math.floor; var fromCodePoint = function() { var MAX_SIZE = 0x4000; var codeUnits = []; var highSurrogate; var lowSurrogate; var index = -1; var length = arguments.length; if (!length) { return ''; } var result = ''; while (++index < length) { var codePoint = Number(arguments[index]); if ( !isFinite(codePoint) || codePoint < 0 || codePoint > 0x10FFFF || floor(codePoint) != codePoint ) { throw RangeError('Invalid code point: ' + codePoint); } if (codePoint <= 0xFFFF) { codeUnits.push(codePoint); } else { codePoint -= 0x10000; highSurrogate = (codePoint >> 10) + 0xD800; lowSurrogate = (codePoint % 0x400) + 0xDC00; codeUnits.push(highSurrogate, lowSurrogate); } if (index + 1 == length || codeUnits.length > MAX_SIZE) { result += stringFromCharCode.apply(null, codeUnits); codeUnits.length = 0; } } return result; }; if (defineProperty) { defineProperty(String, 'fromCodePoint', { 'value': fromCodePoint, 'configurable': true, 'writable': true }); } else { String.fromCodePoint = fromCodePoint; } }()); }

// Add "Quote This" buttons to all initially visible comments

var spans = document.getElementsByTagName("span");
for (var x=0; x<spans.length; x++)
{
    if (spans[x].id.indexOf("reply_link_")==0)
    {
        var button = document.createElement("span");
        button.setAttribute("class","nbutton");
        var p = document.createElement("p");
        var b = document.createElement("b");
        var a = document.createElement("a");
        // Set the href of the "Quote This" button to the href of the "Reply to This" button, with the escaped contents of the post added to URL and any [domain.names] following links in the post cut out:
        a.setAttribute("href",spans[x].getElementsByTagName("a")[0].href.replace("#post_comment","&postercomment="+escape("<blockquote>"+document.getElementById("comment_body_"+spans[x].id.replace("reply_link_","")).innerHTML.replace(/<\/a>\s\[.*?\..*?\]/g,"<\/a>")+"<\/blockquote>\n\n")+"#post_comment"));
        // To Do: Shorten URLs longer than 2000 characters
        a.appendChild(document.createTextNode("Quote This"));
        b.appendChild(a);
        p.appendChild(b);
        button.appendChild(p);
        spans[x].parentNode.insertBefore(button, spans[x].nextSibling);
        spans[x].parentNode.insertBefore(document.createTextNode(" "), spans[x].nextSibling); // Divider
    }
}

if (stripEmail && window.location.href.search(/http(s)?\:\/\/soylentnews\.org\/submit\.pl/)!=-1) // Empty email input area, but only on submission page
{
    var boxes = document.getElementsByTagName("input");
    for (var x=0; x<boxes.length; x++)
    {
        if (boxes[x].name == "email")
        {
            boxes[x].value = "";
        }
    }
}

// Add title case button next to title/subj field on Story Submissions, Submission Preview, and Story Preview
if (window.location.href.search(/http(s)?\:\/\/soylentnews\.org\/(submit|admin)\.pl/)!=-1)
{
    var boxes = document.getElementsByTagName("input");
    for (var x=0; x<boxes.length; x++)
    {
        if (boxes[x].name == "title" || boxes[x].name == "subj")
        {
            boxes[x].id = "storyTitle";
            var button = document.createElement("input");
            button.setAttribute("type","button");
            button.setAttribute("value","Title Case");
            button.setAttribute("title","Convert title to title case.");
            button.setAttribute("onclick","document.getElementById('storyTitle').value=document.getElementById('storyTitle').value.replace(/\\b([a-z])/gi,function(m, p1){return p1.toUpperCase();}).replace(/\\b(at|of|is|and|to|in|by|as|its|be|the|on|a|an|but|or|for)\\b/gi,function(m, p1){return p1.toLowerCase();}).replace(/^([a-z])/gi,function(m, p1){return p1.toUpperCase();}).replace(/:\\s([a-z])/gi,function(m, p1){return ': '+p1.toUpperCase();}).replace(/\\bx(86|64)\\b/gi,'x$1');");
            boxes[x].parentNode.insertBefore(button, boxes[x].nextSibling);
            if (window.location.href.search(/http(s)?\:\/\/soylentnews\.org\/admin\.pl/)!=-1 || boxes[x].name == "subj")
            {
                boxes[x].parentNode.insertBefore(document.createElement("br"), boxes[x].nextSibling);
            }
            else
            {
                boxes[x].parentNode.insertBefore(document.createTextNode(" "), boxes[x].nextSibling);
            }
        }
    }
}

var boxes = document.getElementsByTagName("textarea");
for (var x=0; x<boxes.length; x++)
{
    if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
    {
        var temp = boxes[x].value; // Retrieve textarea contents
        temp = temp.replace(/<\/p><p>/g,"<\/p>\n\n<p>"); // Add newlines between paragraphs
        temp = temp.replace(/<br>\s?<br>/g,"<\/p>\n\n<p>"); // Convert double break tags to paragraph tags
        temp = temp.replace(/<\/blockquote><p>/g,"<\/blockquote>\n\n<p>"); // Add newlines after blockquotes
        temp = temp.replace(/<\/p><blockquote>/g,"<\/p>\n\n<blockquote>"); // Add newlines before blockquotes
        temp = temp.replace(/<blockquote><div><p>/g,"<blockquote><div>\n\n<p>"); // Add newlines within start of blockquotes
        temp = temp.replace(/<\/p><\/div><\/blockquote>/g,"<\/p>\n\n<\/div><\/blockquote>"); // Add newlines within end of blockquotes
        temp = temp.replace(/<\/blockquote><blockquote>/g,"<\/blockquote>\n\n<blockquote>"); // Add newlines between two blockquotes
        temp = temp.replace(/<p class="byline">\s/i,"<p class=\"byline\">"); // Remove extra space from byline
        temp = temp.replace(/<p>\s/g,"<p>"); // Remove extra space from start of paragraph
        temp = temp.replace(/\s<\/p>/g,"<\/p>"); // Remove extra space from end of paragraph
        temp = temp.replace(/<\/li><li>/g,"<\/li>\n<li>"); // Add newlines between list items
        temp = temp.replace(/(<\/li>)(<\/[u|o]l>)/g,'$1\n$2'); // Add newline after last list item
        temp = temp.replace(/(<\/p>)(<[u|o]l>)/g,'$1\n$2'); // Add newlines before lists
        temp = temp.replace(/<p>\[...\]/g,"<p>[...] "); // Add space within beginning of foreshortened paragraph
        while (temp.indexOf("  ")!=-1)
        {
            temp = temp.replace(/  /g," "); // Replace double spaces with single spaces
        }
        if (simplifyChars)
        {
            temp = temp.replace(/\u2018/g,"'"); // 'LEFT SINGLE QUOTATION MARK' (U+2018) to (U+0027)
            temp = temp.replace(/\u2019/g,"'"); // 'RIGHT SINGLE QUOTATION MARK' (U+2019) to (U+0027)
            temp = temp.replace(/\u201C/g,"\""); // 'LEFT DOUBLE QUOTATION MARK' (U+201C) to (U+0022)
            temp = temp.replace(/\u201D/g,"\""); // 'RIGHT DOUBLE QUOTATION MARK' (U+201D) to (U+0022)
            temp = temp.replace(/\u2026/g,"..."); // 'HORIZONTAL ELLIPSIS' (U+2026) to (U+002E) x3
        }
        boxes[x].value = temp;
        boxes[x].rows = 32; // Expand textarea height to 32 rows
    }
    var toolbar = document.createElement("div");

    // Blockquote button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Blockquote");
    tempbutton.setAttribute("title","Wrap \u003Cblockquote\u003E tags around the selected text.");
    tempbutton.setAttribute("onclick","addBlockquote(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Paragraph and Line break buttons
    var tempspan = document.createElement("span");
    tempspan.setAttribute("id","htmlFormatButtons");
    if (document.getElementById("posttype") && document.getElementById("posttype").selectedIndex == 0)
    {
        tempspan.setAttribute("style","display:none;"); // Hide if initial post type option is "Plain Old Text"
    }
    if (document.getElementById("posttype"))
    {
        document.getElementById("posttype").addEventListener("change", function() {if (document.getElementById('posttype').selectedIndex == 0) {document.getElementById('htmlFormatButtons').style.display = 'none'} else {document.getElementById('htmlFormatButtons').style.display = 'inline'}}); // Change visibility of these buttons based on value of post type
    }
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","P");
    tempbutton.setAttribute("title","Wrap \u003Cp\u003E tags around the selected text.");
    tempbutton.setAttribute("onclick","addPara(document.getElementsByTagName('textarea')["+x+"]);");
    tempspan.appendChild(tempbutton);
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","BR");
    tempbutton.setAttribute("title","Insert a line break.");
    tempbutton.setAttribute("onclick","addBreak(document.getElementsByTagName('textarea')["+x+"]);");
    tempspan.appendChild(tempbutton);
    toolbar.appendChild(tempspan);

    // HR button, if editing a story
    if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
    {
        var tempbutton = document.createElement("input");
        tempbutton.setAttribute("type","button");
        tempbutton.setAttribute("value","HR");
        tempbutton.setAttribute("title","Insert a horizontal rule.");
        tempbutton.setAttribute("style","text-decoration:underline overline;");
        tempbutton.setAttribute("onclick","addHRule(document.getElementsByTagName('textarea')["+x+"]);");
        tempspan.appendChild(tempbutton);
        toolbar.appendChild(tempspan);
    }

    // URL button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","URL");
    tempbutton.setAttribute("title","Create a hyperlink around the selected text.");
    tempbutton.setAttribute("style","text-decoration:underline;");
    tempbutton.setAttribute("onclick","addHyperlink(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);
    toolbar.appendChild(document.createTextNode(" "));

    // Bold button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","B");
    tempbutton.setAttribute("title","Bold");
    tempbutton.setAttribute("style","font-weight:bold;");
    tempbutton.setAttribute("onclick","addBold(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Italic button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","I");
    tempbutton.setAttribute("title","Italic");
    tempbutton.setAttribute("style","font-style:italic;");
    tempbutton.setAttribute("onclick","addItalic(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Strike button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","S");
    tempbutton.setAttribute("title","Strikethrough");
    tempbutton.setAttribute("style","text-decoration:line-through;");
    tempbutton.setAttribute("onclick","addStrike(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createTextNode(" ")); // Divider

    // Code button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Code");
    tempbutton.setAttribute("title","Wrap \u003Cecode\u003E tags around the selected text.");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addEcode(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Teletype button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","TT");
    tempbutton.setAttribute("title","Wrap \u003Ctt\u003E (teletype, i.e. monospace) tags around the selected text.");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addTT(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Small button, if editing a story
    if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
    {
        var tempbutton = document.createElement("input");
        tempbutton.setAttribute("type","button");
        tempbutton.setAttribute("value","\u0073\u1D0D\u1D00\u029F\u029F");
        tempbutton.setAttribute("title","Wrap \u003Csmall\u003E tags around the selected text.");
        // tempbutton.setAttribute("style","font-size:75%;");
        tempbutton.setAttribute("onclick","addSmall(document.getElementsByTagName('textarea')["+x+"]);");
        toolbar.appendChild(tempbutton);
    }

    toolbar.appendChild(document.createTextNode(" ")); // Divider

    // Superscript button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","x\u00B2");
    tempbutton.setAttribute("title","Superscript");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addSuper(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Subscript button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","x\u2082");
    tempbutton.setAttribute("title","Subscript");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addSubsc(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createTextNode(" ")); // Divider

    // Ordered list button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","1. List");
    tempbutton.setAttribute("title","Insert an ordered list or convert newline-separated text into an ordered list.");
    tempbutton.setAttribute("onclick","addOrdlist(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Unordered list button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","\u2022 List");
    tempbutton.setAttribute("title","Insert an unordered list or convert newline-separated text into an unordered list.");
    tempbutton.setAttribute("onclick","addUnordlist(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createElement("br")); // Divider

    // Create 7 macro buttons
    for (var i=1; i<=7; i++)
    {
        // Create macros if they don't exist
        if(!localStorage.getItem("soymacro"+i))
        {
            localStorage.setItem("soymacro"+i,JSON.stringify(["M"+i,"string","Sample Text"]));
            //localStorage.setItem("soymacro"+i,JSON.stringify(["M"+i,"regexp","/a/gi","b"]));
        }
        var tempbutton = document.createElement("input");
        tempbutton.setAttribute("type","button");
        tempbutton.setAttribute("id","soymacros"+x+"button"+i);
        tempbutton.setAttribute("value",JSON.parse(localStorage.getItem("soymacro"+i))[0]);
        if (JSON.parse(localStorage.getItem("soymacro"+i))[1]=="string")
        {
            if (JSON.parse(localStorage.getItem("soymacro"+i))[2].length < 40)
            {
                tempbutton.setAttribute("title","Insert or replace selected text with: " + JSON.parse(localStorage.getItem("soymacro"+i))[2]);
            }
            else
            {
                tempbutton.setAttribute("title","Insert or replace selected text with: " + JSON.parse(localStorage.getItem("soymacro"+i))[2].substring(0,40)+"...");
            }
            tempbutton.setAttribute("onclick","macroChoose(document.getElementsByTagName('textarea')["+x+"],"+i+");");
        }
        else
        {
            tempbutton.setAttribute("title","Replace text matched by the regular expression: " + JSON.parse(localStorage.getItem("soymacro"+i))[2] + " with: " + JSON.parse(localStorage.getItem("soymacro"+i))[3]);
            tempbutton.setAttribute("onclick","macroChoose(document.getElementsByTagName('textarea')["+x+"],"+i+");");
        }
        toolbar.appendChild(tempbutton);
    }
    // Create macros edit button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Edit");
    tempbutton.setAttribute("title","Configure user macros or discard changes.");
    tempbutton.setAttribute("onclick","if (document.getElementById('macrobar"+x+"').style.display == 'none') {document.getElementById('macrobar"+x+"').style.display = 'block'; macrobarInit("+x+");} else {document.getElementById('macrobar"+x+"').style.display = 'none'; if (p = document.getElementById('postercomment')) { var x = p.offsetTop; while (p = p.offsetParent) {x += p.offsetLeft;} window.scrollTo(0,x-75);}}");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createElement("br")); // Divider

    // Despace button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Despace");
    tempbutton.setAttribute("title","Delete newlines within the selection.");
    tempbutton.setAttribute("onclick","despace(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Symbol button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value",":-)");
    tempbutton.setAttribute("title","Insert a symbol.");
    tempbutton.setAttribute("onclick","if (document.getElementById('smilebar"+x+"').style.display == 'none') {document.getElementById('smilebar"+x+"').style.display = 'block'} else {document.getElementById('smilebar"+x+"').style.display = 'none'; if (p = document.getElementById('postercomment')) { var x = p.offsetTop; while (p = p.offsetParent) {x += p.offsetLeft;} window.scrollTo(0,x-75); } }");
    toolbar.appendChild(tempbutton);
    boxes[x].parentNode.insertBefore(toolbar, boxes[x].nextSibling);

    // Symbol list
    var smilebar = document.createElement("div");
    smilebar.setAttribute("style","-moz-user-select:none; -webkit-user-select:none; display:none; font-size:16pt; max-height:240px; overflow:auto; padding:0.5em;");
    smilebar.setAttribute("id","smilebar"+x);
    var smiles = ["\u0026amp;","\u0026lt;","\u0026gt;"];

    var codes = [[161,169],[171,172],[174],[176,177],[180,183],[187,191],[215],[224,255],[402],[629],[632],[916],[920],[931],[934],[937],[945,946],[956],[960],[963],[8216,8221],[8226],[8230],[8251],[8364],[8478],[8482],[8528,8542],[8585],[8592,8652],[8712,8716],[8721],[8730],[8733,8734],[8736],[8743,8749],[8756,8757],[8773],[8776],[8800,8805],[8834,8837],[8984],[9760],[9762,9765],[9770],[9773,9775],[9784,9794],[9812,9831],[9833,9842],[9850],[9855,9861],[9874,9877],[9882,9885],[9888,9893],[9913],[9940],[9962],[9971],[9981],[9992,10087],[65533],[127744,127756],[127759],[127775,127776],[127797],[127801],[127804,127812],[127817],[127820,127822],[127828,127831],[127838,127839],[127843],[127849],[127855],[127860,127867],[127891],[127904,127911],[127918],[127939],[127942],[127977],[128025],[128074,128078],[128123,128131],[128137,128142],[128148,128150],[128152],[128158],[128161,128164],[128168,128170],[128172],[128176,128177],[128187],[128189,128190],[128193,128194],[128197],[128203,128204],[128206],[128214],[128225,128227],[128231,128233],[128241],[128244],[128246],[128250,128252],[128259],[128266,128270],[128273,128276],[128278,128280],[128286],[128293,128299],[128302,128303],[128509,128510],[128659],[128684,128685]];

    for (var i=0; i<codes.length; i++) { if (codes[i].length > 1) { for (var j=codes[i][0]; j<=codes[i][1]; j++) { smiles[smiles.length] = String.fromCodePoint(j); } } else { smiles[smiles.length] = String.fromCodePoint(codes[i][0]); } } // Populate smiles array with code ranges converted to individual characters

    smiles = smiles.concat(["xD",":-)",":^)","(^_^;)","\u0028\u00A0\u0361\u00B0\u00A0\u035C\u0296\u00A0\u0361\u00B0\u0029","\u0028\u00A0\u0361\u007E\u00A0\u035C\u0296\u00A0\u0361\u00B0\u0029\uFEFF","\u00AF\u005C\u005F\u0028\u30C4\u0029\u005F\u002F\u00AF","\u0028\u256F\u00B0\u25A1\u00B0\uFF09\u256F\uFE35\u00A0\u253B\u2501\u253B","\u0028\u30CE\u0CA0\u76CA\u0CA0\u0029\u30CE\u5F61\u253B\u2501\u253B","\u0028\u0060\uFF65\u03C9\uFF65\u00B4\u0029","\u0CA0_\u0CA0","\u0295\u2022\u1D25\u2022\u0294","\u0028\u3065\uFFE3\u00A0\u00B3\uFFE3\u0029\u3065","\u0669\u0028\u204E\u275B\u1D17\u275B\u204E\u0029\u06F6","\u30FD\u0F3C\u0E88\u0644\u035C\u0E88\u0F3D\uFF89"]); // Add in arbitrary emoticons

    for (var i=0; i<smiles.length; i++)
    {
        var smile = document.createElement("span");
        smile.setAttribute("style","cursor:pointer; padding:2px; white-space:nowrap;");
        smile.setAttribute("onclick","addSmile(document.getElementsByTagName('textarea')["+x+"],'"+smiles[i].replace("\u005C","\u005C\u005C")+"');");
        smile.appendChild(document.createTextNode(smiles[i]));
        smilebar.appendChild(smile);
        if (i+1<smiles.length)
        {
            smilebar.appendChild(document.createTextNode(" "));
        }
    }
    toolbar.parentNode.insertBefore(smilebar, toolbar.nextSibling);

    // Create macro configuration interface
    var macrobar = document.createElement("div");
    macrobar.setAttribute("style","display:none; padding:0.5em;");
    macrobar.setAttribute("id","macrobar"+x);
    var table = document.createElement("table");
    var tr = document.createElement("tr");
    var th = document.createElement("th");
    th.appendChild(document.createTextNode("Name"));
    tr.appendChild(th);
    var th = document.createElement("th");
    th.appendChild(document.createTextNode("Type"));
    tr.appendChild(th);
    var th = document.createElement("th");
    th.appendChild(document.createTextNode("String | Expression"));
    tr.appendChild(th);
    var th = document.createElement("th");
    th.setAttribute("title","Only used with expressions. Parenthesized substring matches (e.g. '$1') can be used.");
    th.setAttribute("style","cursor:help;");
    th.appendChild(document.createTextNode("Expression Replace"));
    tr.appendChild(th);
    table.appendChild(tr);
    for (var i=1; i<=7; i++)
    {
        var tr = document.createElement("tr");

        // Macro name
        var td = document.createElement("td");
        var name = document.createElement("input");
        name.setAttribute("type","text");
        name.setAttribute("id","soymacros"+x+"name"+i);
        td.appendChild(name);
        tr.appendChild(td);

        // Macro type
        var td = document.createElement("td");
        var rad = document.createElement("input");
        rad.setAttribute("type","radio");
        rad.setAttribute("name","soymacros"+x+"type"+i);
        rad.setAttribute("id","soymacros"+x+"type"+i+"S");
        td.appendChild(rad);
        td.appendChild(document.createTextNode(" String "));
        var rad = document.createElement("input");
        rad.setAttribute("type","radio");
        rad.setAttribute("name","soymacros"+x+"type"+i);
        rad.setAttribute("id","soymacros"+x+"type"+i+"E");
        td.appendChild(rad);
        td.appendChild(document.createTextNode(" Expression "));
        tr.appendChild(td);

        // Field A
        var td = document.createElement("td");
        var f1 = document.createElement("input");
        f1.setAttribute("type","text");
        f1.setAttribute("id","soymacros"+x+"fieldA"+i);
        td.appendChild(f1);
        tr.appendChild(td);

        // Field B
        var td = document.createElement("td");
        var f1 = document.createElement("input");
        f1.setAttribute("type","text");
        f1.setAttribute("id","soymacros"+x+"fieldB"+i);
        td.appendChild(f1);
        tr.appendChild(td);

        table.appendChild(tr);
    }
    macrobar.appendChild(table);

    var p = document.createElement("p");
    var save = document.createElement("input");
    save.setAttribute("type","button");
    save.setAttribute("value","Save");
    save.setAttribute("title","Save any edits to the macro configuration.");
    save.setAttribute("onclick","macrobarSave("+x+");");
    p.appendChild(save);
    p.appendChild(document.createTextNode(" "));
    var guide = document.createElement("a");
    guide.setAttribute("href","https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions");
    guide.setAttribute("target","_blank");
    guide.appendChild(document.createTextNode("Regexp Guide"));
    p.appendChild(guide);
    macrobar.appendChild(p);

    toolbar.parentNode.insertBefore(macrobar, toolbar.nextSibling);
}

var temp = document.createElement("script");

// Add selection handling function
temp.appendChild(document.createTextNode("function getSelection(textarea) { if ('selectionStart' in textarea) { if (textarea.selectionStart != textarea.selectionEnd) { return [textarea.selectionStart,textarea.selectionEnd]; } } } "));

// Add comment formatting buttons
temp.appendChild(document.createTextNode("function addBlockquote(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<blockquote>'+area.value.substring(sel[0],sel[1])+'<\/blockquote>' + area.value.substring(sel[1]); } } function addPara(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<p>'+area.value.substring(sel[0],sel[1])+'<\/p>' + area.value.substring(sel[1]); } } function addBreak(area) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + '<br>' + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+4,pos+4) } } function addHRule(area) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + '<hr>' + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+4,pos+4) } } function addHyperlink(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { url = prompt('URL:', 'https://'); area.value = area.value.substring(0,sel[0]) + '<a href=\"'+url+'\">'+area.value.substring(sel[0],sel[1])+'<\/a>' + area.value.substring(sel[1]); } } function addBold(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<b>'+area.value.substring(sel[0],sel[1])+'<\/b>' + area.value.substring(sel[1]); } } function addItalic(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<em>'+area.value.substring(sel[0],sel[1])+'<\/em>' + area.value.substring(sel[1]); } } function addStrike(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<strike>'+area.value.substring(sel[0],sel[1])+'<\/strike>' + area.value.substring(sel[1]); } } function addEcode(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<ecode>'+area.value.substring(sel[0],sel[1])+'<\/ecode>' + area.value.substring(sel[1]); } } function addTT(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<tt>'+area.value.substring(sel[0],sel[1])+'<\/tt>' + area.value.substring(sel[1]); } } function addSmall(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<small>'+area.value.substring(sel[0],sel[1])+'<\/small>' + area.value.substring(sel[1]); } } function addSuper(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<sup>'+area.value.substring(sel[0],sel[1])+'<\/sup>' + area.value.substring(sel[1]); } } function addSubsc(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<sub>'+area.value.substring(sel[0],sel[1])+'<\/sub>' + area.value.substring(sel[1]); } } "));

// Add list creation functions
temp.appendChild(document.createTextNode("function addOrdlist(area) { if ('selectionStart' in area) { if (area.selectionStart != area.selectionEnd) { area.value = area.value.substring(0,area.selectionStart) + '<ol><li>' + area.value.substring(area.selectionStart,area.selectionEnd).replace(/\\n/g,'<\/li>\\n<li>').replace(/\\n<li><\\/li>/g,'') + '<\/li><\/ol>' + area.value.substring(area.selectionEnd); } else { temp = '<ol>'; while(listitem = prompt('Enter a list item. Leave the box empty or press Cancel to complete the list:', '')) { temp += '<li>' + listitem + '<\/li>\\n'; } area.value = area.value.substring(0,area.selectionStart) + temp.substring(0,temp.length-1) + '<\/ol>' + area.value.substring(area.selectionStart); } } } function addUnordlist(area) { if ('selectionStart' in area) { if (area.selectionStart != area.selectionEnd) { area.value = area.value.substring(0,area.selectionStart) + '<ul><li>' + area.value.substring(area.selectionStart,area.selectionEnd).replace(/\\n/g,'<\/li>\\n<li>').replace(/\\n<li><\\/li>/g,'') + '<\/li><\/ul>' + area.value.substring(area.selectionEnd); } else { temp = '<ul>'; while(listitem = prompt('Enter a list item. Leave the box empty or press Cancel to complete the list:', '')) { temp += '<li>' + listitem + '<\/li>\\n'; } area.value = area.value.substring(0,area.selectionStart) + temp.substring(0,temp.length-1) + '<\/ul>' + area.value.substring(area.selectionStart); } } }"));

// Add macro functions
temp.appendChild(document.createTextNode("function macroChoose(area,x) { if (JSON.parse(localStorage.getItem('soymacro'+x))[1]=='string') { macroString(area,x); } else { macroRegexp(area,x); } }"));
temp.appendChild(document.createTextNode("function macroString(area,x) { var sel = getSelection(area); if (sel && sel[0] != sel[1]) { area.value = area.value.substring(0,sel[0]) + JSON.parse(localStorage.getItem('soymacro'+x))[2] + area.value.substring(sel[1]); } else if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + JSON.parse(localStorage.getItem('soymacro'+x))[2] + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+JSON.parse(localStorage.getItem('soymacro'+x))[2].length,pos+JSON.parse(localStorage.getItem('soymacro'+x))[2].length); } }"));
temp.appendChild(document.createTextNode("function macroRegexp(area,x) { var sel = getSelection(area); if (sel && sel[0] != sel[1]) { var reg = JSON.parse(localStorage.getItem('soymacro'+x))[2]; area.value = area.value.substring(0,sel[0]) + area.value.substring(sel[0],sel[1]).replace(new RegExp(reg.substring(reg.indexOf('/')+1,reg.lastIndexOf('/')), reg.substring(reg.lastIndexOf('/')+1)),JSON.parse(localStorage.getItem('soymacro'+x))[3]) + area.value.substring(sel[1]); } }"));
temp.appendChild(document.createTextNode("function macrobarInit(x) { for (var y=1; y<=7; y++) { document.getElementById('soymacros'+x+'name'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[0]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]=='string') { document.getElementById('soymacros'+x+'type'+y+'S').checked = true; } else { document.getElementById('soymacros'+x+'type'+y+'E').checked = true; } document.getElementById('soymacros'+x+'fieldA'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[2]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]!='string') { document.getElementById('soymacros'+x+'fieldB'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[3]; } else { document.getElementById('soymacros'+x+'fieldB'+y).value = ''; } } }"));
temp.appendChild(document.createTextNode("function macrobarSave(x) { for (var y=1; y<=7; y++) { if (document.getElementById('soymacros'+x+'type'+y+'S').checked == true) { localStorage.setItem('soymacro'+y,JSON.stringify([document.getElementById('soymacros'+x+'name'+y).value,'string',document.getElementById('soymacros'+x+'fieldA'+y).value])); } else { localStorage.setItem('soymacro'+y,JSON.stringify([document.getElementById('soymacros'+x+'name'+y).value,'regexp',document.getElementById('soymacros'+x+'fieldA'+y).value,document.getElementById('soymacros'+x+'fieldB'+y).value])); } } document.getElementById('macrobar'+x).style.display = 'none'; var boxes = document.getElementsByTagName('textarea'); for (var z=0; z<boxes.length; z++) { for (var y=1; y<=7; y++) { document.getElementById('soymacros'+z+'button'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[0]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]=='string') { if (JSON.parse(localStorage.getItem('soymacro'+y))[2].length < 40) { document.getElementById('soymacros'+z+'button'+y).title = 'Insert or replace selected text with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2]; } else { document.getElementById('soymacros'+z+'button'+y).title = 'Insert or replace selected text with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2].substring(0,40)+'...'; } } else { document.getElementById('soymacros'+z+'button'+y).title = 'Replace text matched by the regular expression: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2] + ' with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[3]; } } } }"));

// Add despace function
temp.appendChild(document.createTextNode("function despace(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + area.value.substring(sel[0],sel[1]).replace(/\\r/g,' ').replace(/\\n/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ') + area.value.substring(sel[1]); } }"));

// Add unicode insertion function
temp.appendChild(document.createTextNode("function addSmile(area, smile) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,pos) + smile + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+smile.length,pos+smile.length) } }"));

document.getElementsByTagName('head')[0].appendChild(temp); // Add script to page

Soylent Upgrade Greasemonkey/Tampermonkey extension v9

Posted by takyon on Tuesday June 02 2015, @05:43PM (#1266)
8 Comments
Code

// ==UserScript==
// @name Soylent Upgrade
// @match http://soylentnews.org/*article.pl*
// @match https://soylentnews.org/*article.pl*
// @match http://soylentnews.org/submit.pl*
// @match https://soylentnews.org/submit.pl*
// @match http://soylentnews.org/admin.pl*
// @match https://soylentnews.org/admin.pl*
// @match http://soylentnews.org/*comments.pl*
// @match https://soylentnews.org/*comments.pl*
// @match http://soylentnews.org/journal.pl*
// @match https://soylentnews.org/journal.pl*
// ==/UserScript==

// User Options:

var simplifyChars = true; // Change to false if you don't want stylized quotation marks, ellipses, etc. to be replaced
var stripEmail = false; // Remove auto-filled email from submission

// End User Options

/* ! http://mths.be/fromcodepoint v0.1.0 by @mathias */
if (!String.fromCodePoint) { (function() { var defineProperty = (function() { try { var object = {}; var $defineProperty = Object.defineProperty; var result = $defineProperty(object, object, object) && $defineProperty; } catch(error) {} return result; }()); var stringFromCharCode = String.fromCharCode; var floor = Math.floor; var fromCodePoint = function() { var MAX_SIZE = 0x4000; var codeUnits = []; var highSurrogate; var lowSurrogate; var index = -1; var length = arguments.length; if (!length) { return ''; } var result = ''; while (++index < length) { var codePoint = Number(arguments[index]); if ( !isFinite(codePoint) || codePoint < 0 || codePoint > 0x10FFFF || floor(codePoint) != codePoint ) { throw RangeError('Invalid code point: ' + codePoint); } if (codePoint <= 0xFFFF) { codeUnits.push(codePoint); } else { codePoint -= 0x10000; highSurrogate = (codePoint >> 10) + 0xD800; lowSurrogate = (codePoint % 0x400) + 0xDC00; codeUnits.push(highSurrogate, lowSurrogate); } if (index + 1 == length || codeUnits.length > MAX_SIZE) { result += stringFromCharCode.apply(null, codeUnits); codeUnits.length = 0; } } return result; }; if (defineProperty) { defineProperty(String, 'fromCodePoint', { 'value': fromCodePoint, 'configurable': true, 'writable': true }); } else { String.fromCodePoint = fromCodePoint; } }()); }

// Add "Quote This" buttons to all initially visible comments

var spans = document.getElementsByTagName("span");
for (var x=0; x<spans.length; x++)
{
    if (spans[x].id.indexOf("reply_link_")==0)
    {
        var button = document.createElement("span");
        button.setAttribute("class","nbutton");
        var p = document.createElement("p");
        var b = document.createElement("b");
        var a = document.createElement("a");
        // Set the href of the "Quote This" button to the href of the "Reply to This" button, with the escaped contents of the post added to URL and any [domain.names] following links in the post cut out:
        a.setAttribute("href",spans[x].getElementsByTagName("a")[0].href.replace("#post_comment","&postercomment="+escape("<blockquote>"+document.getElementById("comment_body_"+spans[x].id.replace("reply_link_","")).innerHTML.replace(/<\/a>\s\[.*?\..*?\]/g,"<\/a>")+"<\/blockquote>\n\n")+"#post_comment"));
        // To Do: Shorten URLs longer than 2000 characters
        a.appendChild(document.createTextNode("Quote This"));
        b.appendChild(a);
        p.appendChild(b);
        button.appendChild(p);
        spans[x].parentNode.insertBefore(button, spans[x].nextSibling);
        spans[x].parentNode.insertBefore(document.createTextNode(" "), spans[x].nextSibling); // Divider
    }
}

if (stripEmail && window.location.href.search(/http(s)?\:\/\/soylentnews\.org\/submit\.pl/)!=-1) // Empty email input area, but only on submission page
{
    var boxes = document.getElementsByTagName("input");
    for (var x=0; x<boxes.length; x++)
    {
        if (boxes[x].name == "email")
        {
            boxes[x].value = "";
        }
    }
}

// Add title case button next to title/subj field on Story Submissions, Submission Preview, and Story Preview
if (window.location.href.search(/http(s)?\:\/\/soylentnews\.org\/(submit|admin)\.pl/)!=-1)
{
    var boxes = document.getElementsByTagName("input");
    for (var x=0; x<boxes.length; x++)
    {
        if (boxes[x].name == "title" || boxes[x].name == "subj")
        {
            boxes[x].id = "storyTitle";
            var button = document.createElement("input");
            button.setAttribute("type","button");
            button.setAttribute("value","Title Case");
            button.setAttribute("title","Convert title to title case.");
            button.setAttribute("onclick","document.getElementById('storyTitle').value=document.getElementById('storyTitle').value.replace(/\\b([a-z])/gi,function(m, p1){return p1.toUpperCase();}).replace(/\\b(at|of|is|and|to|in|by|as|its|be|the|on|a|an|but|or|for)\\b/gi,function(m, p1){return p1.toLowerCase();}).replace(/^([a-z])/gi,function(m, p1){return p1.toUpperCase();}).replace(/:\\s([a-z])/gi,function(m, p1){return ': '+p1.toUpperCase();}).replace(/\\bx(86|64)\\b/gi,'x$1');");
            boxes[x].parentNode.insertBefore(button, boxes[x].nextSibling);
            if (window.location.href.search(/http(s)?\:\/\/soylentnews\.org\/admin\.pl/)!=-1 || boxes[x].name == "subj")
            {
                boxes[x].parentNode.insertBefore(document.createElement("br"), boxes[x].nextSibling);
            }
            else
            {
                boxes[x].parentNode.insertBefore(document.createTextNode(" "), boxes[x].nextSibling);
            }
        }
    }
}

var boxes = document.getElementsByTagName("textarea");
for (var x=0; x<boxes.length; x++)
{
    if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
    {
        var temp = boxes[x].value; // Retrieve textarea contents
        temp = temp.replace(/<\/p><p>/g,"<\/p>\n\n<p>"); // Add newlines between paragraphs
        temp = temp.replace(/<br>\s?<br>/g,"<\/p>\n\n<p>"); // Convert double break tags to paragraph tags
        temp = temp.replace(/<\/blockquote><p>/g,"<\/blockquote>\n\n<p>"); // Add newlines after blockquotes
        temp = temp.replace(/<\/p><blockquote>/g,"<\/p>\n\n<blockquote>"); // Add newlines before blockquotes
        temp = temp.replace(/<blockquote><div><p>/g,"<blockquote><div>\n\n<p>"); // Add newlines within start of blockquotes
        temp = temp.replace(/<\/p><\/div><\/blockquote>/g,"<\/p>\n\n<\/div><\/blockquote>"); // Add newlines within end of blockquotes
        temp = temp.replace(/<\/blockquote><blockquote>/g,"<\/blockquote>\n\n<blockquote>"); // Add newlines between two blockquotes
        temp = temp.replace(/<p class="byline">\s/i,"<p class=\"byline\">"); // Remove extra space from byline
        temp = temp.replace(/<p>\s/g,"<p>"); // Remove extra space from start of paragraph
        temp = temp.replace(/\s<\/p>/g,"<\/p>"); // Remove extra space from end of paragraph
        temp = temp.replace(/<\/li><li>/g,"<\/li>\n<li>"); // Add newlines between list items
        temp = temp.replace(/<\/li><\/ul>/g,"<\/li>\n(<\/ul>|<\/ol>)"); // Add newline after last list item
        temp = temp.replace(/<\/p><ul>/g,"<\/p>\n\n(<ul>|<ol>)"); // Add newlines before lists
        temp = temp.replace(/<p>\[...\]/g,"<p>[...] "); // Add space within beginning of foreshortened paragraph
        while (temp.indexOf("  ")!=-1)
        {
            temp = temp.replace(/  /g," "); // Replace double spaces with single spaces
        }
        if (simplifyChars)
        {
            temp = temp.replace(/\u2018/g,"'"); // 'LEFT SINGLE QUOTATION MARK' (U+2018) to (U+0027)
            temp = temp.replace(/\u2019/g,"'"); // 'RIGHT SINGLE QUOTATION MARK' (U+2019) to (U+0027)
            temp = temp.replace(/\u201C/g,"\""); // 'LEFT DOUBLE QUOTATION MARK' (U+201C) to (U+0022)
            temp = temp.replace(/\u201D/g,"\""); // 'RIGHT DOUBLE QUOTATION MARK' (U+201D) to (U+0022)
            temp = temp.replace(/\u2026/g,"..."); // 'HORIZONTAL ELLIPSIS' (U+2026) to (U+002E) x3
        }
        boxes[x].value = temp;
        boxes[x].rows = 32; // Expand textarea height to 32 rows
    }
    var toolbar = document.createElement("div");

    // Blockquote button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Blockquote");
    tempbutton.setAttribute("title","Wrap \u003Cblockquote\u003E tags around the selected text.");
    tempbutton.setAttribute("onclick","addBlockquote(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Paragraph and Line break buttons
    var tempspan = document.createElement("span");
    tempspan.setAttribute("id","htmlFormatButtons");
    if (document.getElementById("posttype") && document.getElementById("posttype").selectedIndex == 0)
    {
        tempspan.setAttribute("style","display:none;"); // Hide if initial post type option is "Plain Old Text"
    }
    if (document.getElementById("posttype"))
    {
        document.getElementById("posttype").addEventListener("change", function() {if (document.getElementById('posttype').selectedIndex == 0) {document.getElementById('htmlFormatButtons').style.display = 'none'} else {document.getElementById('htmlFormatButtons').style.display = 'inline'}}); // Change visibility of these buttons based on value of post type
    }
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","P");
    tempbutton.setAttribute("title","Wrap \u003Cp\u003E tags around the selected text.");
    tempbutton.setAttribute("onclick","addPara(document.getElementsByTagName('textarea')["+x+"]);");
    tempspan.appendChild(tempbutton);
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","BR");
    tempbutton.setAttribute("title","Insert a line break.");
    tempbutton.setAttribute("onclick","addBreak(document.getElementsByTagName('textarea')["+x+"]);");
    tempspan.appendChild(tempbutton);
    toolbar.appendChild(tempspan);

    // HR button, if editing a story
    if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
    {
        var tempbutton = document.createElement("input");
        tempbutton.setAttribute("type","button");
        tempbutton.setAttribute("value","HR");
        tempbutton.setAttribute("title","Insert a horizontal rule.");
        tempbutton.setAttribute("style","text-decoration:underline overline;");
        tempbutton.setAttribute("onclick","addHRule(document.getElementsByTagName('textarea')["+x+"]);");
        tempspan.appendChild(tempbutton);
        toolbar.appendChild(tempspan);
    }

    // URL button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","URL");
    tempbutton.setAttribute("title","Create a hyperlink around the selected text.");
    tempbutton.setAttribute("style","text-decoration:underline;");
    tempbutton.setAttribute("onclick","addHyperlink(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);
    toolbar.appendChild(document.createTextNode(" "));

    // Bold button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","B");
    tempbutton.setAttribute("title","Bold");
    tempbutton.setAttribute("style","font-weight:bold;");
    tempbutton.setAttribute("onclick","addBold(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Italic button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","I");
    tempbutton.setAttribute("title","Italic");
    tempbutton.setAttribute("style","font-style:italic;");
    tempbutton.setAttribute("onclick","addItalic(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Strike button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","S");
    tempbutton.setAttribute("title","Strikethrough");
    tempbutton.setAttribute("style","text-decoration:line-through;");
    tempbutton.setAttribute("onclick","addStrike(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createTextNode(" ")); // Divider

    // Code button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Code");
    tempbutton.setAttribute("title","Wrap \u003Cecode\u003E tags around the selected text.");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addEcode(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Teletype button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","TT");
    tempbutton.setAttribute("title","Wrap \u003Ctt\u003E (teletype, i.e. monospace) tags around the selected text.");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addTT(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Small button, if editing a story
    if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
    {
        var tempbutton = document.createElement("input");
        tempbutton.setAttribute("type","button");
        tempbutton.setAttribute("value","\u0073\u1D0D\u1D00\u029F\u029F");
        tempbutton.setAttribute("title","Wrap \u003Csmall\u003E tags around the selected text.");
        // tempbutton.setAttribute("style","font-size:75%;");
        tempbutton.setAttribute("onclick","addSmall(document.getElementsByTagName('textarea')["+x+"]);");
        toolbar.appendChild(tempbutton);
    }

    toolbar.appendChild(document.createTextNode(" ")); // Divider

    // Superscript button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","x\u00B2");
    tempbutton.setAttribute("title","Superscript");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addSuper(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Subscript button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","x\u2082");
    tempbutton.setAttribute("title","Subscript");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addSubsc(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createTextNode(" ")); // Divider

    // Ordered list button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","1. List");
    tempbutton.setAttribute("title","Insert an ordered list or convert newline-separated text into an ordered list.");
    tempbutton.setAttribute("onclick","addOrdlist(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Unordered list button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","\u2022 List");
    tempbutton.setAttribute("title","Insert an unordered list or convert newline-separated text into an unordered list.");
    tempbutton.setAttribute("onclick","addUnordlist(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createElement("br")); // Divider

    // Create 7 macro buttons
    for (var i=1; i<=7; i++)
    {
        // Create macros if they don't exist
        if(!localStorage.getItem("soymacro"+i))
        {
            localStorage.setItem("soymacro"+i,JSON.stringify(["M"+i,"string","Sample Text"]));
            //localStorage.setItem("soymacro"+i,JSON.stringify(["M"+i,"regexp","/a/gi","b"]));
        }
        var tempbutton = document.createElement("input");
        tempbutton.setAttribute("type","button");
        tempbutton.setAttribute("id","soymacros"+x+"button"+i);
        tempbutton.setAttribute("value",JSON.parse(localStorage.getItem("soymacro"+i))[0]);
        if (JSON.parse(localStorage.getItem("soymacro"+i))[1]=="string")
        {
            if (JSON.parse(localStorage.getItem("soymacro"+i))[2].length < 40)
            {
                tempbutton.setAttribute("title","Insert or replace selected text with: " + JSON.parse(localStorage.getItem("soymacro"+i))[2]);
            }
            else
            {
                tempbutton.setAttribute("title","Insert or replace selected text with: " + JSON.parse(localStorage.getItem("soymacro"+i))[2].substring(0,40)+"...");
            }
            tempbutton.setAttribute("onclick","macroChoose(document.getElementsByTagName('textarea')["+x+"],"+i+");");
        }
        else
        {
            tempbutton.setAttribute("title","Replace text matched by the regular expression: " + JSON.parse(localStorage.getItem("soymacro"+i))[2] + " with: " + JSON.parse(localStorage.getItem("soymacro"+i))[3]);
            tempbutton.setAttribute("onclick","macroChoose(document.getElementsByTagName('textarea')["+x+"],"+i+");");
        }
        toolbar.appendChild(tempbutton);
    }
    // Create macros edit button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Edit");
    tempbutton.setAttribute("title","Configure user macros or discard changes.");
    tempbutton.setAttribute("onclick","if (document.getElementById('macrobar"+x+"').style.display == 'none') {document.getElementById('macrobar"+x+"').style.display = 'block'; macrobarInit("+x+");} else {document.getElementById('macrobar"+x+"').style.display = 'none'; if (p = document.getElementById('postercomment')) { var x = p.offsetTop; while (p = p.offsetParent) {x += p.offsetLeft;} window.scrollTo(0,x-75);}}");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createElement("br")); // Divider

    // Despace button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Despace");
    tempbutton.setAttribute("title","Delete newlines within the selection.");
    tempbutton.setAttribute("onclick","despace(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Symbol button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value",":-)");
    tempbutton.setAttribute("title","Insert a symbol.");
    tempbutton.setAttribute("onclick","if (document.getElementById('smilebar"+x+"').style.display == 'none') {document.getElementById('smilebar"+x+"').style.display = 'block'} else {document.getElementById('smilebar"+x+"').style.display = 'none'; if (p = document.getElementById('postercomment')) { var x = p.offsetTop; while (p = p.offsetParent) {x += p.offsetLeft;} window.scrollTo(0,x-75); } }");
    toolbar.appendChild(tempbutton);
    boxes[x].parentNode.insertBefore(toolbar, boxes[x].nextSibling);

    // Symbol list
    var smilebar = document.createElement("div");
    smilebar.setAttribute("style","-moz-user-select:none; -webkit-user-select:none; display:none; font-size:16pt; max-height:240px; overflow:auto; padding:0.5em;");
    smilebar.setAttribute("id","smilebar"+x);
    var smiles = ["\u0026amp;","\u0026lt;","\u0026gt;"];

    var codes = [[161,169],[171,172],[174],[176,177],[180,183],[187,191],[215],[224,255],[402],[629],[632],[916],[920],[931],[934],[937],[945,946],[956],[960],[963],[8216,8221],[8226],[8230],[8251],[8364],[8478],[8482],[8528,8542],[8585],[8592,8652],[8712,8716],[8721],[8730],[8733,8734],[8736],[8743,8749],[8756,8757],[8773],[8776],[8800,8805],[8834,8837],[8984],[9760],[9762,9765],[9770],[9773,9775],[9784,9794],[9812,9831],[9833,9842],[9850],[9855,9861],[9874,9877],[9882,9885],[9888,9893],[9913],[9940],[9962],[9971],[9981],[9992,10087],[65533],[127744,127756],[127759],[127775,127776],[127797],[127801],[127804,127812],[127817],[127820,127822],[127828,127831],[127838,127839],[127843],[127849],[127855],[127860,127867],[127891],[127904,127911],[127918],[127939],[127942],[127977],[128025],[128074,128078],[128123,128131],[128137,128142],[128148,128150],[128152],[128158],[128161,128164],[128168,128170],[128172],[128176,128177],[128187],[128189,128190],[128193,128194],[128197],[128203,128204],[128206],[128214],[128225,128227],[128231,128233],[128241],[128244],[128246],[128250,128252],[128259],[128266,128270],[128273,128276],[128278,128280],[128286],[128293,128299],[128302,128303],[128509,128510],[128659],[128684,128685]];

    for (var i=0; i<codes.length; i++) { if (codes[i].length > 1) { for (var j=codes[i][0]; j<=codes[i][1]; j++) { smiles[smiles.length] = String.fromCodePoint(j); } } else { smiles[smiles.length] = String.fromCodePoint(codes[i][0]); } } // Populate smiles array with code ranges converted to individual characters

    smiles = smiles.concat(["xD",":-)",":^)","(^_^;)","\u0028\u00A0\u0361\u00B0\u00A0\u035C\u0296\u00A0\u0361\u00B0\u0029","\u0028\u00A0\u0361\u007E\u00A0\u035C\u0296\u00A0\u0361\u00B0\u0029\uFEFF","\u00AF\u005C\u005F\u0028\u30C4\u0029\u005F\u002F\u00AF","\u0028\u256F\u00B0\u25A1\u00B0\uFF09\u256F\uFE35\u00A0\u253B\u2501\u253B","\u0028\u30CE\u0CA0\u76CA\u0CA0\u0029\u30CE\u5F61\u253B\u2501\u253B","\u0028\u0060\uFF65\u03C9\uFF65\u00B4\u0029","\u0CA0_\u0CA0","\u0295\u2022\u1D25\u2022\u0294","\u0028\u3065\uFFE3\u00A0\u00B3\uFFE3\u0029\u3065","\u0669\u0028\u204E\u275B\u1D17\u275B\u204E\u0029\u06F6","\u30FD\u0F3C\u0E88\u0644\u035C\u0E88\u0F3D\uFF89"]); // Add in arbitrary emoticons

    for (var i=0; i<smiles.length; i++)
    {
        var smile = document.createElement("span");
        smile.setAttribute("style","cursor:pointer; padding:2px; white-space:nowrap;");
        smile.setAttribute("onclick","addSmile(document.getElementsByTagName('textarea')["+x+"],'"+smiles[i].replace("\u005C","\u005C\u005C")+"');");
        smile.appendChild(document.createTextNode(smiles[i]));
        smilebar.appendChild(smile);
        if (i+1<smiles.length)
        {
            smilebar.appendChild(document.createTextNode(" "));
        }
    }
    toolbar.parentNode.insertBefore(smilebar, toolbar.nextSibling);

    // Create macro configuration interface
    var macrobar = document.createElement("div");
    macrobar.setAttribute("style","display:none; padding:0.5em;");
    macrobar.setAttribute("id","macrobar"+x);
    var table = document.createElement("table");
    var tr = document.createElement("tr");
    var th = document.createElement("th");
    th.appendChild(document.createTextNode("Name"));
    tr.appendChild(th);
    var th = document.createElement("th");
    th.appendChild(document.createTextNode("Type"));
    tr.appendChild(th);
    var th = document.createElement("th");
    th.appendChild(document.createTextNode("String | Expression"));
    tr.appendChild(th);
    var th = document.createElement("th");
    th.setAttribute("title","Only used with expressions. Parenthesized substring matches (e.g. '$1') can be used.");
    th.setAttribute("style","cursor:help;");
    th.appendChild(document.createTextNode("Expression Replace"));
    tr.appendChild(th);
    table.appendChild(tr);
    for (var i=1; i<=7; i++)
    {
        var tr = document.createElement("tr");

        // Macro name
        var td = document.createElement("td");
        var name = document.createElement("input");
        name.setAttribute("type","text");
        name.setAttribute("id","soymacros"+x+"name"+i);
        td.appendChild(name);
        tr.appendChild(td);

        // Macro type
        var td = document.createElement("td");
        var rad = document.createElement("input");
        rad.setAttribute("type","radio");
        rad.setAttribute("name","soymacros"+x+"type"+i);
        rad.setAttribute("id","soymacros"+x+"type"+i+"S");
        td.appendChild(rad);
        td.appendChild(document.createTextNode(" String "));
        var rad = document.createElement("input");
        rad.setAttribute("type","radio");
        rad.setAttribute("name","soymacros"+x+"type"+i);
        rad.setAttribute("id","soymacros"+x+"type"+i+"E");
        td.appendChild(rad);
        td.appendChild(document.createTextNode(" Expression "));
        tr.appendChild(td);

        // Field A
        var td = document.createElement("td");
        var f1 = document.createElement("input");
        f1.setAttribute("type","text");
        f1.setAttribute("id","soymacros"+x+"fieldA"+i);
        td.appendChild(f1);
        tr.appendChild(td);

        // Field B
        var td = document.createElement("td");
        var f1 = document.createElement("input");
        f1.setAttribute("type","text");
        f1.setAttribute("id","soymacros"+x+"fieldB"+i);
        td.appendChild(f1);
        tr.appendChild(td);

        table.appendChild(tr);
    }
    macrobar.appendChild(table);

    var p = document.createElement("p");
    var save = document.createElement("input");
    save.setAttribute("type","button");
    save.setAttribute("value","Save");
    save.setAttribute("title","Save any edits to the macro configuration.");
    save.setAttribute("onclick","macrobarSave("+x+");");
    p.appendChild(save);
    p.appendChild(document.createTextNode(" "));
    var guide = document.createElement("a");
    guide.setAttribute("href","https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions");
    guide.setAttribute("target","_blank");
    guide.appendChild(document.createTextNode("Regexp Guide"));
    p.appendChild(guide);
    macrobar.appendChild(p);

    toolbar.parentNode.insertBefore(macrobar, toolbar.nextSibling);
}

var temp = document.createElement("script");

// Add selection handling function
temp.appendChild(document.createTextNode("function getSelection(textarea) { if ('selectionStart' in textarea) { if (textarea.selectionStart != textarea.selectionEnd) { return [textarea.selectionStart,textarea.selectionEnd]; } } } "));

// Add comment formatting buttons
temp.appendChild(document.createTextNode("function addBlockquote(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<blockquote>'+area.value.substring(sel[0],sel[1])+'<\/blockquote>' + area.value.substring(sel[1]); } } function addPara(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<p>'+area.value.substring(sel[0],sel[1])+'<\/p>' + area.value.substring(sel[1]); } } function addBreak(area) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + '<br>' + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+4,pos+4) } } function addHRule(area) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + '<hr>' + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+4,pos+4) } } function addHyperlink(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { url = prompt('URL:', 'https://'); area.value = area.value.substring(0,sel[0]) + '<a href=\"'+url+'\">'+area.value.substring(sel[0],sel[1])+'<\/a>' + area.value.substring(sel[1]); } } function addBold(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<b>'+area.value.substring(sel[0],sel[1])+'<\/b>' + area.value.substring(sel[1]); } } function addItalic(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<em>'+area.value.substring(sel[0],sel[1])+'<\/em>' + area.value.substring(sel[1]); } } function addStrike(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<strike>'+area.value.substring(sel[0],sel[1])+'<\/strike>' + area.value.substring(sel[1]); } } function addEcode(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<ecode>'+area.value.substring(sel[0],sel[1])+'<\/ecode>' + area.value.substring(sel[1]); } } function addTT(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<tt>'+area.value.substring(sel[0],sel[1])+'<\/tt>' + area.value.substring(sel[1]); } } function addSmall(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<small>'+area.value.substring(sel[0],sel[1])+'<\/small>' + area.value.substring(sel[1]); } } function addSuper(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<sup>'+area.value.substring(sel[0],sel[1])+'<\/sup>' + area.value.substring(sel[1]); } } function addSubsc(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<sub>'+area.value.substring(sel[0],sel[1])+'<\/sub>' + area.value.substring(sel[1]); } } "));

// Add list creation functions
temp.appendChild(document.createTextNode("function addOrdlist(area) { if ('selectionStart' in area) { if (area.selectionStart != area.selectionEnd) { area.value = area.value.substring(0,area.selectionStart) + '<ol><li>' + area.value.substring(area.selectionStart,area.selectionEnd).replace(/\\n/g,'<\/li>\\n<li>').replace(/\\n<li><\\/li>/g,'') + '<\/li><\/ol>' + area.value.substring(area.selectionEnd); } else { temp = '<ol>'; while(listitem = prompt('Enter a list item. Leave the box empty or press Cancel to complete the list:', '')) { temp += '<li>' + listitem + '<\/li>\\n'; } area.value = area.value.substring(0,area.selectionStart) + temp.substring(0,temp.length-1) + '<\/ol>' + area.value.substring(area.selectionStart); } } } function addUnordlist(area) { if ('selectionStart' in area) { if (area.selectionStart != area.selectionEnd) { area.value = area.value.substring(0,area.selectionStart) + '<ul><li>' + area.value.substring(area.selectionStart,area.selectionEnd).replace(/\\n/g,'<\/li>\\n<li>').replace(/\\n<li><\\/li>/g,'') + '<\/li><\/ul>' + area.value.substring(area.selectionEnd); } else { temp = '<ul>'; while(listitem = prompt('Enter a list item. Leave the box empty or press Cancel to complete the list:', '')) { temp += '<li>' + listitem + '<\/li>\\n'; } area.value = area.value.substring(0,area.selectionStart) + temp.substring(0,temp.length-1) + '<\/ul>' + area.value.substring(area.selectionStart); } } }"));

// Add macro functions
temp.appendChild(document.createTextNode("function macroChoose(area,x) { if (JSON.parse(localStorage.getItem('soymacro'+x))[1]=='string') { macroString(area,x); } else { macroRegexp(area,x); } }"));
temp.appendChild(document.createTextNode("function macroString(area,x) { var sel = getSelection(area); if (sel && sel[0] != sel[1]) { area.value = area.value.substring(0,sel[0]) + JSON.parse(localStorage.getItem('soymacro'+x))[2] + area.value.substring(sel[1]); } else if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + JSON.parse(localStorage.getItem('soymacro'+x))[2] + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+JSON.parse(localStorage.getItem('soymacro'+x))[2].length,pos+JSON.parse(localStorage.getItem('soymacro'+x))[2].length); } }"));
temp.appendChild(document.createTextNode("function macroRegexp(area,x) { var sel = getSelection(area); if (sel && sel[0] != sel[1]) { var reg = JSON.parse(localStorage.getItem('soymacro'+x))[2]; area.value = area.value.substring(0,sel[0]) + area.value.substring(sel[0],sel[1]).replace(new RegExp(reg.substring(reg.indexOf('/')+1,reg.lastIndexOf('/')), reg.substring(reg.lastIndexOf('/')+1)),JSON.parse(localStorage.getItem('soymacro'+x))[3]) + area.value.substring(sel[1]); } }"));
temp.appendChild(document.createTextNode("function macrobarInit(x) { for (var y=1; y<=7; y++) { document.getElementById('soymacros'+x+'name'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[0]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]=='string') { document.getElementById('soymacros'+x+'type'+y+'S').checked = true; } else { document.getElementById('soymacros'+x+'type'+y+'E').checked = true; } document.getElementById('soymacros'+x+'fieldA'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[2]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]!='string') { document.getElementById('soymacros'+x+'fieldB'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[3]; } else { document.getElementById('soymacros'+x+'fieldB'+y).value = ''; } } }"));
temp.appendChild(document.createTextNode("function macrobarSave(x) { for (var y=1; y<=7; y++) { if (document.getElementById('soymacros'+x+'type'+y+'S').checked == true) { localStorage.setItem('soymacro'+y,JSON.stringify([document.getElementById('soymacros'+x+'name'+y).value,'string',document.getElementById('soymacros'+x+'fieldA'+y).value])); } else { localStorage.setItem('soymacro'+y,JSON.stringify([document.getElementById('soymacros'+x+'name'+y).value,'regexp',document.getElementById('soymacros'+x+'fieldA'+y).value,document.getElementById('soymacros'+x+'fieldB'+y).value])); } } document.getElementById('macrobar'+x).style.display = 'none'; var boxes = document.getElementsByTagName('textarea'); for (var z=0; z<boxes.length; z++) { for (var y=1; y<=7; y++) { document.getElementById('soymacros'+z+'button'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[0]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]=='string') { if (JSON.parse(localStorage.getItem('soymacro'+y))[2].length < 40) { document.getElementById('soymacros'+z+'button'+y).title = 'Insert or replace selected text with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2]; } else { document.getElementById('soymacros'+z+'button'+y).title = 'Insert or replace selected text with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2].substring(0,40)+'...'; } } else { document.getElementById('soymacros'+z+'button'+y).title = 'Replace text matched by the regular expression: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2] + ' with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[3]; } } } }"));

// Add despace function
temp.appendChild(document.createTextNode("function despace(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + area.value.substring(sel[0],sel[1]).replace(/\\r/g,' ').replace(/\\n/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ') + area.value.substring(sel[1]); } }"));

// Add unicode insertion function
temp.appendChild(document.createTextNode("function addSmile(area, smile) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,pos) + smile + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+smile.length,pos+smile.length) } }"));

document.getElementsByTagName('head')[0].appendChild(temp); // Add script to page

Soylent Upgrade Greasemonkey/Tampermonkey extension v8

Posted by takyon on Monday June 01 2015, @08:34PM (#1264)
3 Comments
Code

// ==UserScript==
// @name Soylent Upgrade
// @match http://soylentnews.org/*article.pl*
// @match https://soylentnews.org/*article.pl*
// @match http://soylentnews.org/submit.pl*
// @match https://soylentnews.org/submit.pl*
// @match http://soylentnews.org/admin.pl*
// @match https://soylentnews.org/admin.pl*
// @match http://soylentnews.org/*comments.pl*
// @match https://soylentnews.org/*comments.pl*
// @match http://soylentnews.org/journal.pl*
// @match https://soylentnews.org/journal.pl*
// ==/UserScript==

/* ! http://mths.be/fromcodepoint v0.1.0 by @mathias */
if (!String.fromCodePoint) { (function() { var defineProperty = (function() { try { var object = {}; var $defineProperty = Object.defineProperty; var result = $defineProperty(object, object, object) && $defineProperty; } catch(error) {} return result; }()); var stringFromCharCode = String.fromCharCode; var floor = Math.floor; var fromCodePoint = function() { var MAX_SIZE = 0x4000; var codeUnits = []; var highSurrogate; var lowSurrogate; var index = -1; var length = arguments.length; if (!length) { return ''; } var result = ''; while (++index < length) { var codePoint = Number(arguments[index]); if ( !isFinite(codePoint) || codePoint < 0 || codePoint > 0x10FFFF || floor(codePoint) != codePoint ) { throw RangeError('Invalid code point: ' + codePoint); } if (codePoint <= 0xFFFF) { codeUnits.push(codePoint); } else { codePoint -= 0x10000; highSurrogate = (codePoint >> 10) + 0xD800; lowSurrogate = (codePoint % 0x400) + 0xDC00; codeUnits.push(highSurrogate, lowSurrogate); } if (index + 1 == length || codeUnits.length > MAX_SIZE) { result += stringFromCharCode.apply(null, codeUnits); codeUnits.length = 0; } } return result; }; if (defineProperty) { defineProperty(String, 'fromCodePoint', { 'value': fromCodePoint, 'configurable': true, 'writable': true }); } else { String.fromCodePoint = fromCodePoint; } }()); }

// Add "Quote This" buttons to all initially visible comments

var spans = document.getElementsByTagName("span");
for (var x=0; x<spans.length; x++)
{
    if (spans[x].id.indexOf("reply_link_")==0)
    {
        var button = document.createElement("span");
        button.setAttribute("class","nbutton");
        var p = document.createElement("p");
        var b = document.createElement("b");
        var a = document.createElement("a");
        // Set the href of the "Quote This" button to the href of the "Reply to This" button, with the escaped contents of the post added to URL and any [domain.names] following links in the post cut out:
        a.setAttribute("href",spans[x].getElementsByTagName("a")[0].href.replace("#post_comment","&postercomment="+escape("<blockquote>"+document.getElementById("comment_body_"+spans[x].id.replace("reply_link_","")).innerHTML.replace(/<\/a>\s\[.*?\..*?\]/g,"<\/a>")+"<\/blockquote>\n\n")+"#post_comment"));
        // To Do: Shorten URLs longer than 2000 characters
        a.appendChild(document.createTextNode("Quote This"));
        b.appendChild(a);
        p.appendChild(b);
        button.appendChild(p);
        spans[x].parentNode.insertBefore(button, spans[x].nextSibling);
        spans[x].parentNode.insertBefore(document.createTextNode(" "), spans[x].nextSibling); // Divider
    }
}

var simplifyChars = true; // Change to false if you don't want stylized quotation marks, ellipses, etc. to be replaced
var stripEmail = false; // Remove auto-filled email from submission

if (stripEmail && window.location.href.search(/http(s)?\:\/\/soylentnews\.org\/submit\.pl/)!=-1) // Empty email input area, but only on submission page
{
    var boxes = document.getElementsByTagName("input");
    for (var x=0; x<boxes.length; x++)
    {
        if (boxes[x].name == "email")
        {
            boxes[x].value = "";
        }
    }
}

var boxes = document.getElementsByTagName("textarea");
for (var x=0; x<boxes.length; x++)
{
    if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
    {
        var temp = boxes[x].value; // Retrieve textarea contents
        temp = temp.replace(/<\/p><p>/g,"<\/p>\n\n<p>"); // Add newlines between paragraphs
        temp = temp.replace(/<br>\s?<br>/g,"<\/p>\n\n<p>"); // Convert double break tags to paragraph tags
        temp = temp.replace(/<\/blockquote><p>/g,"<\/blockquote>\n\n<p>"); // Add newlines after blockquotes
        temp = temp.replace(/<\/p><blockquote>/g,"<\/p>\n\n<blockquote>"); // Add newlines before blockquotes
        temp = temp.replace(/<blockquote><div><p>/g,"<blockquote><div>\n\n<p>"); // Add newlines within start of blockquotes
        temp = temp.replace(/<\/p><\/div><\/blockquote>/g,"<\/p>\n\n<\/div><\/blockquote>"); // Add newlines within end of blockquotes
        temp = temp.replace(/<\/blockquote><blockquote>/g,"<\/blockquote>\n\n<blockquote>"); // Add newlines between two blockquotes
        temp = temp.replace(/<p class="byline">\s/i,"<p class=\"byline\">"); // Remove extra space from byline
        temp = temp.replace(/<p>\s/g,"<p>"); // Remove extra space from start of paragraph
        temp = temp.replace(/\s<\/p>/g,"<\/p>"); // Remove extra space from end of paragraph
        temp = temp.replace(/<\/li><li>/g,"<\/li>\n<li>"); // Add newlines between list items
        temp = temp.replace(/<\/li><\/ul>/g,"<\/li>\n(<\/ul>|<\/ol>)"); // Add newline after last list item
        temp = temp.replace(/<\/p><ul>/g,"<\/p>\n\n(<ul>|<ol>)"); // Add newlines before lists
        temp = temp.replace(/<p>\[...\]/g,"<p>[...] "); // Add space within beginning of foreshortened paragraph
        while (temp.indexOf("  ")!=-1)
        {
            temp = temp.replace(/  /g," "); // Replace double spaces with single spaces
        }
        if (simplifyChars)
        {
            temp = temp.replace(/\u2018/g,"'"); // 'LEFT SINGLE QUOTATION MARK' (U+2018) to (U+0027)
            temp = temp.replace(/\u2019/g,"'"); // 'RIGHT SINGLE QUOTATION MARK' (U+2019) to (U+0027)
            temp = temp.replace(/\u201C/g,"\""); // 'LEFT DOUBLE QUOTATION MARK' (U+201C) to (U+0022)
            temp = temp.replace(/\u201D/g,"\""); // 'RIGHT DOUBLE QUOTATION MARK' (U+201D) to (U+0022)
            temp = temp.replace(/\u2026/g,"..."); // 'HORIZONTAL ELLIPSIS' (U+2026) to (U+002E) x3
        }
        boxes[x].value = temp;
        boxes[x].rows = 32; // Expand textarea height to 32 rows
    }
    var toolbar = document.createElement("div");

    // Blockquote button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Blockquote");
    tempbutton.setAttribute("title","Wrap \u003Cblockquote\u003E tags around the selected text.");
    tempbutton.setAttribute("onclick","addBlockquote(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Paragraph and Line break buttons
    var tempspan = document.createElement("span");
    tempspan.setAttribute("id","htmlFormatButtons");
    if (document.getElementById("posttype") && document.getElementById("posttype").selectedIndex == 0)
    {
        tempspan.setAttribute("style","display:none;"); // Hide if initial post type option is "Plain Old Text"
    }
    if (document.getElementById("posttype"))
    {
        document.getElementById("posttype").addEventListener("change", function() {if (document.getElementById('posttype').selectedIndex == 0) {document.getElementById('htmlFormatButtons').style.display = 'none'} else {document.getElementById('htmlFormatButtons').style.display = 'inline'}}); // Change visibility of these buttons based on value of post type
    }
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","P");
    tempbutton.setAttribute("title","Wrap \u003Cp\u003E tags around the selected text.");
    tempbutton.setAttribute("onclick","addPara(document.getElementsByTagName('textarea')["+x+"]);");
    tempspan.appendChild(tempbutton);
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","BR");
    tempbutton.setAttribute("title","Insert a line break.");
    tempbutton.setAttribute("onclick","addBreak(document.getElementsByTagName('textarea')["+x+"]);");
    tempspan.appendChild(tempbutton);
    toolbar.appendChild(tempspan);

    // HR button, if editing a story
    if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
    {
        var tempbutton = document.createElement("input");
        tempbutton.setAttribute("type","button");
        tempbutton.setAttribute("value","HR");
        tempbutton.setAttribute("title","Insert a horizontal rule.");
        tempbutton.setAttribute("style","text-decoration:underline overline;");
        tempbutton.setAttribute("onclick","addHRule(document.getElementsByTagName('textarea')["+x+"]);");
        tempspan.appendChild(tempbutton);
        toolbar.appendChild(tempspan);
    }

    // URL button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","URL");
    tempbutton.setAttribute("title","Create a hyperlink around the selected text.");
    tempbutton.setAttribute("style","text-decoration:underline;");
    tempbutton.setAttribute("onclick","addHyperlink(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);
    toolbar.appendChild(document.createTextNode(" "));

    // Bold button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","B");
    tempbutton.setAttribute("title","Bold");
    tempbutton.setAttribute("style","font-weight:bold;");
    tempbutton.setAttribute("onclick","addBold(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Italic button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","I");
    tempbutton.setAttribute("title","Italic");
    tempbutton.setAttribute("style","font-style:italic;");
    tempbutton.setAttribute("onclick","addItalic(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Strike button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","S");
    tempbutton.setAttribute("title","Strikethrough");
    tempbutton.setAttribute("style","text-decoration:line-through;");
    tempbutton.setAttribute("onclick","addStrike(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createTextNode(" ")); // Divider

    // Code button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Code");
    tempbutton.setAttribute("title","Wrap \u003Cecode\u003E tags around the selected text.");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addEcode(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Teletype button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","TT");
    tempbutton.setAttribute("title","Wrap \u003Ctt\u003E (teletype, i.e. monospace) tags around the selected text.");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addTT(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Small button, if editing a story
    if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
    {
        var tempbutton = document.createElement("input");
        tempbutton.setAttribute("type","button");
        tempbutton.setAttribute("value","\u0073\u1D0D\u1D00\u029F\u029F");
        tempbutton.setAttribute("title","Wrap \u003Csmall\u003E tags around the selected text.");
        // tempbutton.setAttribute("style","font-size:75%;");
        tempbutton.setAttribute("onclick","addSmall(document.getElementsByTagName('textarea')["+x+"]);");
        toolbar.appendChild(tempbutton);
    }

    toolbar.appendChild(document.createTextNode(" ")); // Divider

    // Superscript button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","x\u00B2");
    tempbutton.setAttribute("title","Superscript");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addSuper(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Subscript button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","x\u2082");
    tempbutton.setAttribute("title","Subscript");
    tempbutton.setAttribute("style","font-family:monospace;");
    tempbutton.setAttribute("onclick","addSubsc(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createTextNode(" ")); // Divider

    // Ordered list button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","1. List");
    tempbutton.setAttribute("title","Insert an ordered list or convert newline-separated text into an ordered list.");
    tempbutton.setAttribute("onclick","addOrdlist(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Unordered list button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","\u2022 List");
    tempbutton.setAttribute("title","Insert an unordered list or convert newline-separated text into an unordered list.");
    tempbutton.setAttribute("onclick","addUnordlist(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createTextNode(" ")); // Divider

    // Create 5 macro buttons
    for (var i=1; i<=5; i++)
    {
        // Create macros if they don't exist
        if(!localStorage.getItem("soymacro"+i))
        {
            localStorage.setItem("soymacro"+i,JSON.stringify(["M"+i,"string","Sample Text"]));
            //localStorage.setItem("soymacro"+i,JSON.stringify(["M"+i,"regexp","/a/gi","b"]));
        }
        var tempbutton = document.createElement("input");
        tempbutton.setAttribute("type","button");
        tempbutton.setAttribute("id","soymacros"+x+"button"+i);
        tempbutton.setAttribute("value",JSON.parse(localStorage.getItem("soymacro"+i))[0]);
        if (JSON.parse(localStorage.getItem("soymacro"+i))[1]=="string")
        {
            if (JSON.parse(localStorage.getItem("soymacro"+i))[2].length < 40)
            {
                tempbutton.setAttribute("title","Insert or replace selected text with: " + JSON.parse(localStorage.getItem("soymacro"+i))[2]);
            }
            else
            {
                tempbutton.setAttribute("title","Insert or replace selected text with: " + JSON.parse(localStorage.getItem("soymacro"+i))[2].substring(0,40)+"...");
            }
            tempbutton.setAttribute("onclick","macroChoose(document.getElementsByTagName('textarea')["+x+"],"+i+");");
        }
        else
        {
            tempbutton.setAttribute("title","Replace text matched by the regular expression: " + JSON.parse(localStorage.getItem("soymacro"+i))[2] + " with: " + JSON.parse(localStorage.getItem("soymacro"+i))[3]);
            tempbutton.setAttribute("onclick","macroChoose(document.getElementsByTagName('textarea')["+x+"],"+i+");");
        }
        toolbar.appendChild(tempbutton);
    }
    // Create macros edit button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Edit");
    tempbutton.setAttribute("title","Configure user macros or discard changes.");
    tempbutton.setAttribute("onclick","if (document.getElementById('macrobar"+x+"').style.display == 'none') {document.getElementById('macrobar"+x+"').style.display = 'block'; macrobarInit("+x+");} else {document.getElementById('macrobar"+x+"').style.display = 'none'; if (p = document.getElementById('postercomment')) { var x = p.offsetTop; while (p = p.offsetParent) {x += p.offsetLeft;} window.scrollTo(0,x-75);}}");
    toolbar.appendChild(tempbutton);

    toolbar.appendChild(document.createElement("br")); // Divider

    // Despace button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value","Despace");
    tempbutton.setAttribute("title","Delete newlines within the selection.");
    tempbutton.setAttribute("onclick","despace(document.getElementsByTagName('textarea')["+x+"]);");
    toolbar.appendChild(tempbutton);

    // Symbol button
    var tempbutton = document.createElement("input");
    tempbutton.setAttribute("type","button");
    tempbutton.setAttribute("value",":-)");
    tempbutton.setAttribute("title","Insert a symbol.");
    tempbutton.setAttribute("onclick","if (document.getElementById('smilebar"+x+"').style.display == 'none') {document.getElementById('smilebar"+x+"').style.display = 'block'} else {document.getElementById('smilebar"+x+"').style.display = 'none'; if (p = document.getElementById('postercomment')) { var x = p.offsetTop; while (p = p.offsetParent) {x += p.offsetLeft;} window.scrollTo(0,x-75); } }");
    toolbar.appendChild(tempbutton);
    boxes[x].parentNode.insertBefore(toolbar, boxes[x].nextSibling);

    // Symbol list
    var smilebar = document.createElement("div");
    smilebar.setAttribute("style","-moz-user-select:none; -webkit-user-select:none; display:none; font-size:16pt; max-height:240px; overflow:auto; padding:0.5em;");
    smilebar.setAttribute("id","smilebar"+x);
    var smiles = ["<",">"];

    var codes = [[161,169],[171,172],[174],[176,177],[180,183],[187,191],[215],[224,255],[402],[629],[632],[916],[920],[931],[934],[937],[945,946],[956],[960],[963],[8216,8221],[8226],[8230],[8251],[8364],[8478],[8482],[8528,8542],[8585],[8712,8716],[8721],[8730],[8733,8734],[8736],[8743,8749],[8756,8757],[8773],[8776],[8800,8805],[8834,8837],[8984],[9760],[9762,9765],[9770],[9773,9775],[9784,9794],[9812,9831],[9833,9842],[9850],[9855,9861],[9874,9877],[9882,9885],[9888,9893],[9913],[9940],[9962],[9971],[9981],[9992,10087],[65533],[127744,127756],[127759],[127775,127776],[127797],[127801],[127804,127812],[127817],[127820,127822],[127828,127831],[127838,127839],[127843],[127849],[127855],[127860,127867],[127891],[127904,127911],[127918],[127939],[127942],[127977],[128025],[128074,128078],[128123,128131],[128137,128142],[128148,128150],[128152],[128158],[128161,128164],[128168,128170],[128172],[128176,128177],[128187],[128189,128190],[128193,128194],[128197],[128203,128204],[128206],[128214],[128225,128227],[128231,128233],[128241],[128244],[128246],[128250,128252],[128259],[128266,128270],[128273,128276],[128278,128280],[128286],[128293,128299],[128302,128303],[128509,128510],[128659],[128684,128685]];

    for (var i=0; i<codes.length; i++) { if (codes[i].length > 1) { for (var j=codes[i][0]; j<=codes[i][1]; j++) { smiles[smiles.length] = String.fromCodePoint(j); } } else { smiles[smiles.length] = String.fromCodePoint(codes[i][0]); } } // Populate smiles array with code ranges converted to individual characters

    smiles = smiles.concat(["xD",":-)",":^)","(^_^;)","\u0028\u00A0\u0361\u00B0\u00A0\u035C\u0296\u00A0\u0361\u00B0\u0029","\u0028\u00A0\u0361\u007E\u00A0\u035C\u0296\u00A0\u0361\u00B0\u0029\uFEFF","\u00AF\u005C\u005F\u0028\u30C4\u0029\u005F\u002F\u00AF","\u0028\u256F\u00B0\u25A1\u00B0\uFF09\u256F\uFE35\u00A0\u253B\u2501\u253B","\u0028\u30CE\u0CA0\u76CA\u0CA0\u0029\u30CE\u5F61\u253B\u2501\u253B","\u0028\u0060\uFF65\u03C9\uFF65\u00B4\u0029","\u0CA0_\u0CA0","\u0295\u2022\u1D25\u2022\u0294","\u0028\u3065\uFFE3\u00A0\u00B3\uFFE3\u0029\u3065","\u0669\u0028\u204E\u275B\u1D17\u275B\u204E\u0029\u06F6","\u30FD\u0F3C\u0E88\u0644\u035C\u0E88\u0F3D\uFF89"]); // Add in arbitrary emoticons

    for (var i=0; i<smiles.length; i++)
    {
        var smile = document.createElement("span");
        smile.setAttribute("style","cursor:pointer; padding:2px; white-space:nowrap;");
        smile.setAttribute("onclick","addSmile(document.getElementsByTagName('textarea')["+x+"],'"+smiles[i].replace("\u005C","\u005C\u005C")+"');");
        smile.appendChild(document.createTextNode(smiles[i]));
        smilebar.appendChild(smile);
        if (i+1<smiles.length)
        {
            smilebar.appendChild(document.createTextNode(" "));
        }
    }
    toolbar.parentNode.insertBefore(smilebar, toolbar.nextSibling);

    // Create macro configuration interface
    var macrobar = document.createElement("div");
    macrobar.setAttribute("style","display:none; padding:0.5em;");
    macrobar.setAttribute("id","macrobar"+x);
    var table = document.createElement("table");
    var tr = document.createElement("tr");
    var th = document.createElement("th");
    th.appendChild(document.createTextNode("Name"));
    tr.appendChild(th);
    var th = document.createElement("th");
    th.appendChild(document.createTextNode("Type"));
    tr.appendChild(th);
    var th = document.createElement("th");
    th.appendChild(document.createTextNode("String | Expression"));
    tr.appendChild(th);
    var th = document.createElement("th");
    th.setAttribute("title","Only used with expressions. Parenthesized substring matches (e.g. '$1') can be used.");
    th.setAttribute("style","cursor:help;");
    th.appendChild(document.createTextNode("Expression Replace"));
    tr.appendChild(th);
    table.appendChild(tr);
    for (var i=1; i<=5; i++)
    {
        var tr = document.createElement("tr");

        // Macro name
        var td = document.createElement("td");
        var name = document.createElement("input");
        name.setAttribute("type","text");
        name.setAttribute("id","soymacros"+x+"name"+i);
        td.appendChild(name);
        tr.appendChild(td);

        // Macro type
        var td = document.createElement("td");
        var rad = document.createElement("input");
        rad.setAttribute("type","radio");
        rad.setAttribute("name","soymacros"+x+"type"+i);
        rad.setAttribute("id","soymacros"+x+"type"+i+"S");
        td.appendChild(rad);
        td.appendChild(document.createTextNode(" String "));
        var rad = document.createElement("input");
        rad.setAttribute("type","radio");
        rad.setAttribute("name","soymacros"+x+"type"+i);
        rad.setAttribute("id","soymacros"+x+"type"+i+"E");
        td.appendChild(rad);
        td.appendChild(document.createTextNode(" Expression "));
        tr.appendChild(td);

        // Field A
        var td = document.createElement("td");
        var f1 = document.createElement("input");
        f1.setAttribute("type","text");
        f1.setAttribute("id","soymacros"+x+"fieldA"+i);
        td.appendChild(f1);
        tr.appendChild(td);

        // Field B
        var td = document.createElement("td");
        var f1 = document.createElement("input");
        f1.setAttribute("type","text");
        f1.setAttribute("id","soymacros"+x+"fieldB"+i);
        td.appendChild(f1);
        tr.appendChild(td);

        table.appendChild(tr);
    }
    macrobar.appendChild(table);

    var p = document.createElement("p");
    var save = document.createElement("input");
    save.setAttribute("type","button");
    save.setAttribute("value","Save");
    save.setAttribute("title","Save any edits to the macro configuration.");
    save.setAttribute("onclick","macrobarSave("+x+");");
    p.appendChild(save);
    p.appendChild(document.createTextNode(" "));
    var guide = document.createElement("a");
    guide.setAttribute("href","https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions");
    guide.setAttribute("target","_blank");
    guide.appendChild(document.createTextNode("Regexp Guide"));
    p.appendChild(guide);
    macrobar.appendChild(p);

    toolbar.parentNode.insertBefore(macrobar, toolbar.nextSibling);
}

var temp = document.createElement("script");

// Add selection handling function
temp.appendChild(document.createTextNode("function getSelection(textarea) { if ('selectionStart' in textarea) { if (textarea.selectionStart != textarea.selectionEnd) { return [textarea.selectionStart,textarea.selectionEnd]; } } } "));

// Add comment formatting buttons
temp.appendChild(document.createTextNode("function addBlockquote(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<blockquote>'+area.value.substring(sel[0],sel[1])+'<\/blockquote>' + area.value.substring(sel[1]); } } function addPara(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<p>'+area.value.substring(sel[0],sel[1])+'<\/p>' + area.value.substring(sel[1]); } } function addBreak(area) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + '<br>' + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+4,pos+4) } } function addHRule(area) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + '<hr>' + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+4,pos+4) } } function addHyperlink(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { url = prompt('URL:', 'https://'); area.value = area.value.substring(0,sel[0]) + '<a href=\"'+url+'\">'+area.value.substring(sel[0],sel[1])+'<\/a>' + area.value.substring(sel[1]); } } function addBold(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<b>'+area.value.substring(sel[0],sel[1])+'<\/b>' + area.value.substring(sel[1]); } } function addItalic(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<em>'+area.value.substring(sel[0],sel[1])+'<\/em>' + area.value.substring(sel[1]); } } function addStrike(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<strike>'+area.value.substring(sel[0],sel[1])+'<\/strike>' + area.value.substring(sel[1]); } } function addEcode(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<ecode>'+area.value.substring(sel[0],sel[1])+'<\/ecode>' + area.value.substring(sel[1]); } } function addTT(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<tt>'+area.value.substring(sel[0],sel[1])+'<\/tt>' + area.value.substring(sel[1]); } } function addSmall(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<small>'+area.value.substring(sel[0],sel[1])+'<\/small>' + area.value.substring(sel[1]); } } function addSuper(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<sup>'+area.value.substring(sel[0],sel[1])+'<\/sup>' + area.value.substring(sel[1]); } } function addSubsc(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<sub>'+area.value.substring(sel[0],sel[1])+'<\/sub>' + area.value.substring(sel[1]); } } "));

// Add list creation functions
temp.appendChild(document.createTextNode("function addOrdlist(area) { if ('selectionStart' in area) { if (area.selectionStart != area.selectionEnd) { area.value = area.value.substring(0,area.selectionStart) + '<ol><li>' + area.value.substring(area.selectionStart,area.selectionEnd).replace(/\\n/g,'<\/li>\\n<li>').replace(/\\n<li><\\/li>/g,'') + '<\/li><\/ol>' + area.value.substring(area.selectionEnd); } else { temp = '<ol>'; while(listitem = prompt('Enter a list item. Leave the box empty or press Cancel to complete the list:', '')) { temp += '<li>' + listitem + '<\/li>\\n'; } area.value = area.value.substring(0,area.selectionStart) + temp.substring(0,temp.length-1) + '<\/ol>' + area.value.substring(area.selectionStart); } } } function addUnordlist(area) { if ('selectionStart' in area) { if (area.selectionStart != area.selectionEnd) { area.value = area.value.substring(0,area.selectionStart) + '<ul><li>' + area.value.substring(area.selectionStart,area.selectionEnd).replace(/\\n/g,'<\/li>\\n<li>').replace(/\\n<li><\\/li>/g,'') + '<\/li><\/ul>' + area.value.substring(area.selectionEnd); } else { temp = '<ul>'; while(listitem = prompt('Enter a list item. Leave the box empty or press Cancel to complete the list:', '')) { temp += '<li>' + listitem + '<\/li>\\n'; } area.value = area.value.substring(0,area.selectionStart) + temp.substring(0,temp.length-1) + '<\/ul>' + area.value.substring(area.selectionStart); } } }"));

// Add macro functions
temp.appendChild(document.createTextNode("function macroChoose(area,x) { if (JSON.parse(localStorage.getItem('soymacro'+x))[1]=='string') { macroString(area,x); } else { macroRegexp(area,x); } }"));
temp.appendChild(document.createTextNode("function macroString(area,x) { var sel = getSelection(area); if (sel && sel[0] != sel[1]) { area.value = area.value.substring(0,sel[0]) + JSON.parse(localStorage.getItem('soymacro'+x))[2] + area.value.substring(sel[1]); } else if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + JSON.parse(localStorage.getItem('soymacro'+x))[2] + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+JSON.parse(localStorage.getItem('soymacro'+x))[2].length,pos+JSON.parse(localStorage.getItem('soymacro'+x))[2].length); } }"));
temp.appendChild(document.createTextNode("function macroRegexp(area,x) { var sel = getSelection(area); if (sel && sel[0] != sel[1]) { var reg = JSON.parse(localStorage.getItem('soymacro'+x))[2]; area.value = area.value.substring(0,sel[0]) + area.value.substring(sel[0],sel[1]).replace(new RegExp(reg.substring(reg.indexOf('/')+1,reg.lastIndexOf('/')), reg.substring(reg.lastIndexOf('/')+1)),JSON.parse(localStorage.getItem('soymacro'+x))[3]) + area.value.substring(sel[1]); } }"));
temp.appendChild(document.createTextNode("function macrobarInit(x) { for (var y=1; y<=5; y++) { document.getElementById('soymacros'+x+'name'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[0]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]=='string') { document.getElementById('soymacros'+x+'type'+y+'S').checked = true; } else { document.getElementById('soymacros'+x+'type'+y+'E').checked = true; } document.getElementById('soymacros'+x+'fieldA'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[2]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]!='string') { document.getElementById('soymacros'+x+'fieldB'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[3]; } else { document.getElementById('soymacros'+x+'fieldB'+y).value = ''; } } }"));
temp.appendChild(document.createTextNode("function macrobarSave(x) { for (var y=1; y<=5; y++) { if (document.getElementById('soymacros'+x+'type'+y+'S').checked == true) { localStorage.setItem('soymacro'+y,JSON.stringify([document.getElementById('soymacros'+x+'name'+y).value,'string',document.getElementById('soymacros'+x+'fieldA'+y).value])); } else { localStorage.setItem('soymacro'+y,JSON.stringify([document.getElementById('soymacros'+x+'name'+y).value,'regexp',document.getElementById('soymacros'+x+'fieldA'+y).value,document.getElementById('soymacros'+x+'fieldB'+y).value])); } } document.getElementById('macrobar'+x).style.display = 'none'; var boxes = document.getElementsByTagName('textarea'); for (var z=0; z<boxes.length; z++) { for (var y=1; y<=5; y++) { document.getElementById('soymacros'+z+'button'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[0]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]=='string') { if (JSON.parse(localStorage.getItem('soymacro'+y))[2].length < 40) { document.getElementById('soymacros'+z+'button'+y).title = 'Insert or replace selected text with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2]; } else { document.getElementById('soymacros'+z+'button'+y).title = 'Insert or replace selected text with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2].substring(0,40)+'...'; } } else { document.getElementById('soymacros'+z+'button'+y).title = 'Replace text matched by the regular expression: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2] + ' with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[3]; } } } }"));

// Add despace function
temp.appendChild(document.createTextNode("function despace(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + area.value.substring(sel[0],sel[1]).replace(/\\r/g,' ').replace(/\\n/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ') + area.value.substring(sel[1]); } }"));

// Add unicode insertion function
temp.appendChild(document.createTextNode("function addSmile(area, smile) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,pos) + smile + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+smile.length,pos+smile.length) } }"));

document.getElementsByTagName('head')[0].appendChild(temp); // Add script to page