Stories
Slash Boxes
Comments

SoylentNews is people

Log In

Log In

Create Account  |  Retrieve Password


Relationship Hacking: Part 13 - A new beginning?

Posted by Snow on Thursday March 24 2016, @08:55PM (#1814)
0 Comments
/dev/random

Last week I had another first date. I met this girl on OkCupid. We met in the afternoon at a local pub and shared a meat and cheese platter. She was visibly nervous when she arrived. I found her nervousness charming, and it put me at ease. Once the nerves calmed down, we had some great conversation as we picked at the cheese and meat tray.

She is recently out of a multi-year relationship, and isn't looking to get right back into one, so she thought that dating a married person would be a good way to avoid being locked down again. We chatted about stuff and things, and wrapped it up after a couple hours. As we parted ways, we hugged and I went in for the kiss. Her lips were soft and I ended up floating back to my car.

We arranged for a second date a couple days later. We went for drinks and appetizers at a somewhat trendy restaurant downtown. She is new to non-monogamy, so I brought her a present -- a book called "The Ethical Slut". This book is considered by some as the bible for non-monogamous relationships, and as she is new to the scene, I thought it would help. We chatted, ate, drank, and eventually made it back to her place for some fooling around.

This girl has really done a number on me. I can't stop thinking about her. I can't wait to see her again.

War on Drugs Meant to Disrupt Blacks and Hippies

Posted by takyon on Wednesday March 23 2016, @12:34AM (#1810)
6 Comments
News

A Former Nixon Aide Admitted the 'War on Drugs' Was Designed to Screw Over Blacks and Hippies

According to Watergate mastermind and former Richard Nixon aide John Ehrlichman, the then-president launched the notorious (and ongoing) war on drugs in 1971 to disrupt that administration's two greatest perceived threats: black people and antiwar leftists.

The brazen quote surfaced in the April cover story of Harper's magazine that was written by Dan Baum and went online Tuesday. The reporter recalls an interview back in 1994 in which Ehrlichman bluntly explained the whole thing.

"The Nixon campaign in 1968, and the Nixon White House after that, had two enemies: the antiwar left and black people. You understand what I'm saying?" Ehrlichman told Baum. "We knew we couldn't make it illegal to be either against the war or black, but by getting the public to associate the hippies with marijuana and blacks with heroin, and then criminalizing both heavily, we could disrupt those communities. We could arrest their leaders, raid their homes, break up their meetings, and vilify them night after night on the evening news. Did we know we were lying about the drugs? Of course we did."

Obvious? Sure. But it's important to get this kind of history explicitly out in the open so that mistakes can be corrected.

Here's the article at Harper's Magazine.

Dice in Hot Water

Posted by takyon on Monday March 21 2016, @12:06PM (#1808)
6 Comments
/dev/random

Too spicy for SoylentNews... not spicy enough for your job:

'Hot Tech Talent' IT job board ads caught up in sexism allegations

Dice, formerly the IT Job Boards, said it intended the images, which feature both men and women, to be light-hearted. Part of the drive behind the campaign was to counter the notion that people working in technology were "nerds".

SlashdotMedia - Fair processing notice

Posted by GungnirSniper on Thursday March 17 2016, @09:51PM (#1806)
1 Comment
/dev/random

I received this email this afternoon:

From: notices[at]slashdotmedia.com
2016-03-16

Dear Site User,

Fair processing notice - Data Protection Act 1998

We are writing to let you know that with effect from 27 January 2016, the Slashdot Media business, which provides online services through various web sites including Slashdot.org and SourceForge.net (the "Slashdot Media Services") has been purchased by SourceForge Media LLC of 1660 Logan Avenue, San Diego, California, 92113, USA ("we" or "us").

As a result your personal data have been transferred to us and will be used in connection with the continued provision of the Slashdot Media Services to you. Your personal data will continue to be processed fairly and lawfully in accordance with the Data Protection Act 1998 for the same purposes as those it was originally collected by Dice Career Solutions Inc and/or eFinancialCareers Limited including to:

* continue to provide you with information (by electronic means or otherwise) about other services we offer that are similar to those that you have already received or enquired about;
* carry out our obligations arising from any contracts entered into between you and us;
* provide you with the information and services you request from us;
* tell you about changes to the Slashdot Media Services; and
* ensure that the content made available through the Slashdot Media Services is presented in the most effective manner for you and your device.

Further information on how your personal data may be processed, who it may be disclosed to and how it will be stored can be found in the Slashdot Media Services privacy policy available at: http://www.slashdotmedia.com/privacy-statement/

You can ask us to remove all your account data, stop processing your personal data and to stop contacting you for marketing purposes at any time.
* For SourceForge.net, please contact us at sfnet_ops[at]slashdotmedia.com
* For Slashdot, please contact us at privacy[at]slashdot.org
* For FreeCode, please contact us at freecode-privacy[at]slashdotmedia.com
* For SlashdotMedia.com, please contact us at sfnet_ops[at]slashdotmedia.com

Please let us know if you have any queries.
Yours sincerely,
Logan Abbott
The team at SourceForge Media LLC

Their privacy policy does allow them to share your info with advertisers:

In order to effectively tailor our services, these Sites may sell your personal information third party consultants and business partners, including, but not limited to other lead generation companies (collectively “Third Party Contractors”) to collect, compile, organize, and market to you related services.

When you submit any personal identifiable information on a Site, we will obtain your consent authorizing the Sites to sell to Third Party Contractors, any and all personally identifiable information that is necessary to enable additional service offerings.

Hopefully this doesn't mean a spam bombardment.

Applicant Tracking Systems Suck

Posted by GungnirSniper on Thursday March 17 2016, @08:51PM (#1805)
2 Comments
Career & Education

I've been looking for a new job for a bit now, and Applicant Tracking Systems are the bane of my search. A long series of forms can take up to 20 minutes to fill out, and for what? So a human being can never even look at it?

iCIMS
Why do I need to enter a time zone setting for my account?
Why are there over 100 options, including "Antarctica/Casey (Australian Western Standard Time)" and "Pacific/Efate (Vanuatu Time)" when I've already given you my bloody postal code?
Why, when using my LinkedIn info to fill out your forms, do you need access to everything in my LinkedIn profile, including messages ya creeps?

LinkedIn
Why can't I limit what I share with other sites? Why is sending messages as me even an option?
Also, politics do not belong on LinkedIn. Don't kill your platform with offtopic noise, like memes.
Search options like my location and search radius should be remembered.

ClearCompany.com
Why can't I upload my resume from my PC instead of using Dropbox or Google Drive?

Glassdoor.com
Why am I automagically logged out when I close my browser?

Elsewhere, etc.
No, I'm not sharing my salary history with you. Not even if we are close to an offer. I'm not telling you what I made at the last 5 jobs in your tracking database, so don't make it a required field.
Recruiters, if you ask for an email in the posting, can you at least acknowledge you got it?
Why do I need an account and password and multiple forgot-password questions that are common?
No, I'm not giving you my mother's maiden name.
If you have a tracking system, why doesn't it email me when I'm rejected, or even list it as "not selected" when I check? It's like a black hole where I give info and get nothing in return.
The turnaround time frame on even hearing on submission can be in weeks or longer. Why not list when you're going to process the stack of resumes?

On a related note, I'd like to see employment law change so employers can give a reason why they reject a candidate without being sued. The only way I get any useful interview feedback is via agencies.

China Uses Trump as a Warning Against Democracy

Posted by takyon on Thursday March 17 2016, @07:18AM (#1804)
15 Comments
News

Democracy is a joke, says China – just look at Donald Trump

“The rise of a racist in the US political area worries the whole world,” the party-controlled Global Times crowed this week ahead of of Trump’s victory in the latest round of primaries. “He has even been called another Benito Mussolini or Adolf Hitler by some western media.” It added, darkly: “Mussolini and Hitler came to power through elections, a heavy lesson for western democracy.”

Trump, or “Chuanpu” as they call him in China, has been a gift to Communist party spin doctors paid to convince the country’s 1.4 billion citizens that rule of the people is a sure path to chaos and destruction.

“They are relishing this moment,” says Zhou Fengsuo, a US-based democracy activist who fled his native China following the deadly 1989 Tiananmen crackdown. “They are very happy. They are laughing over this. To them [Trump] is a good character to show the deficiencies of the democratic system, that such a person could become president. It is just unbelievable. Beijing is definitely gloating over this.”

[...] Chinese newspapers, which have previously pounced on the Arab Spring and Ukraine’s Maidan revolution as evidence of the dangers of democracy, have wasted no time in hyping the potential turmoil that Trump’s rise could bring.

An editorial in the Chinese-language edition of the Global Times noted with glee that fighting had broken out at Trump rallies in what was supposedly one of the world’s “most developed and mature democratic election systems”.

[...] An editorial on another government-run website claimed Trump had “humiliated” the US political system. “He has turned the election into a prank,” it said.

Florida Deputy Illegally Arrests Protesting PINAC Reporter

Posted by takyon on Monday March 14 2016, @09:11PM (#1802)
4 Comments
Digital Liberty

WATCH: Florida Deputy Illegally Arrests PINAC Reporter Protesting At High School
Broadcast by honoryouroath + YouTube

Florida Sheriff’s deputies illegally enforced the “school safety zones” trespassing law against PINAC reporter Jeff Gray, outside of a St. Augustine high school earlier today. Gray complied with law enforcement orders, and is currently being held in the northeastern Florida St. Johns County jail, but oddly no charges are listed with his mugshot, unlike all of the other suspects as you can see below.

The St. Johns Sheriff’s Office has wanted to detain Gray for many months now, after the local schools Superintendent declared him persona non grata, even though Gray has a son currently attending St. Augustine High School and two other children in the system.

Jeff Gray was arrested while protesting with a sign in hand, the SLAPP lawsuit filed against him by St. Johns Schools last December. The legal action was filed along with 38 SLAPP letters sent to his home address by certified mail, one of which invoked Florida Statute 810.0975 and its “school safety zones.”

“How are you doing, Mr. Gray?” asked the Florida deputy as he got out of his patrol car, wearing street clothing, to which Jeff responded, “Pretty good. How are you?” “May I ask you why are you here?” asked the St. Johns sheriff’s deputy. “I am peacefully assembling and peacefully protesting,” replied Gray. “Ok. Do you realize [that] this is a violation of your no trespass order that was issued. Correct?” asked the deputy.

“No, it’s not actually. There’s a provision that that says “shall not infringe on the right to peacefully assemble and protest If you look in the statute, it’s right there,” said Gray, whose HonorYourOath YouTube page is famously filled with instances like these where the reporter very carefully expresses to the officers his statutory or constitutional rights, and he re-iterated for emphasis, “In the statute. That’s why I’m here.”

“This is within the 500 foot safety rule, so i’m putting you under arrest for violation of that trespass order,” replied the Florida deputy who seemed to suddenly remember that Gray is a reporter and would in all likelihood be recording the scene, “If you would, put your sign down, turn your phone off, put your hands behind your back, turn around please. Put your hands together like you’re praying, please.”

Gray surrendered to detainment. “If you look at the statute, there’s a provision…” said Gray as the sheriff’s deputy cuffed him. But Jeff Gray is right. The last sentence of the “School Safety Zones” statute reads: “Nothing in this section shall be construed to abridge or infringe upon the right of any person to peaceably assemble and protest.”

Hillary Clinton Lie of the Day

Posted by takyon on Friday March 11 2016, @09:45PM (#1800)
0 Comments

16 GB DDR4 Modules Becoming More Common

Posted by takyon on Wednesday March 09 2016, @07:41PM (#1796)
0 Comments
Hardware

HyperX Introduces 16 GB DDR4 Impact SODIMM Modules, Kits Up To 64 GB At 2400 MHz

There are a couple 16 GB DDR4 SODIMM memory modules out there, but not very many. However, Kingston is filling the gap with new HyperX modules, which it uses in six new memory kits in its DDR4 Impact line.

The 16 GB DDR4 SODIMM modules will exist in two variants, one with a 2133 MHz frequency and the other at 2400 MHz. The latencies depend on the kit they're in, although the lower-frequency model has slightly quicker timings, as is usually the case.

16 GB modules for consumers are becoming more common, and DDR4 prices are dropping due to the usual industry oversupply. You probably remember a time when 8 GB or 4 GB modules were in this position. What amount of RAM do you want or need for gaming or VM/work computers? Is the requirement of a DDR4-capable motherboard holding you back?

Edit: I didn't realize the story is for SODIMM laptop memory. I don't see a lot of DDR4 laptops because I mainly look at deals which are for older laptops. A typical laptop with removable/replaceable RAM will have 2 slots, so that's 32 GB of memory with this kit.

Older stories:

Price Check: DDR4 Memory Down Nearly 40% in 6 Months, Expected To Continue
G.Skill Introduces 64GB DDR4-3200 Memory Kits
G.Skill Announces 128 GB DDR4 3000 MHz Kit For Content Creation Professionals
Price Check: Price Gap Between DDR3 and DDR4 Memory Almost Gone

Soylent Upgrade Greasemonkey/Tampermonkey extension v12

Posted by takyon on Thursday March 03 2016, @04:54AM (#1788)
4 Comments
Code

SKIP TO THE COMMENTS

// ==UserScript==
// @name Soylent Upgrade
// @version 12.0
// @grant none
// @match http://soylentnews.org/*article.pl*
// @match http://*.soylentnews.org/*article.pl*
// @match https://soylentnews.org/*article.pl*
// @match https://*.soylentnews.org/*article.pl*

// @match http://soylentnews.org/*submit.pl*
// @match http://*.soylentnews.org/*submit.pl*
// @match https://soylentnews.org/*submit.pl*
// @match https://*.soylentnews.org/*submit.pl*

// @match http://soylentnews.org/*admin.pl*
// @match http://*.soylentnews.org/*admin.pl*
// @match https://soylentnews.org/*admin.pl*
// @match https://*.soylentnews.org/*admin.pl*

// @match http://soylentnews.org/*comments.pl*
// @match http://*.soylentnews.org/*comments.pl*
// @match https://soylentnews.org/*comments.pl*
// @match https://*.soylentnews.org/*comments.pl*

// @match http://soylentnews.org/*journal.pl*
// @match http://*.soylentnews.org/*journal.pl*
// @match https://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
var doiChecker = true; // Add Crossref search to DOIs in the summary

// 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
    }
}

// DOI checker in the summary
if (doiChecker && window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/article\.pl/)!=-1)
{
    var summary = document.getElementById("articles").getElementsByClassName("intro")[0];
    summary.innerHTML = summary.innerHTML.replace(/(\(|\[)DOI: (10[^\s]*)(\)|\])/gi,"$1DOI: <a href='http://search.crossref.org/?q=$2' target='_blank'>$2</a>$3");
    summary.innerHTML = summary.innerHTML.replace(/(\(|\[)open, DOI: (10[^\s]*)(\)|\])/gi,"$1open, DOI: <a href='http://search.crossref.org/?q=$2' target='_blank'>$2</a>$3");
    var summary2 = document.getElementById("articles").getElementsByClassName("full")[0];
    summary2.innerHTML = summary2.innerHTML.replace(/(\(|\[)DOI: (10[^\s]*)(\)|\])/gi,"$1DOI: <a href='http://search.crossref.org/?q=$2' target='_blank'>$2</a>$3");
    summary2.innerHTML = summary2.innerHTML.replace(/(\(|\[)open, DOI: (10[^\s]*)(\)|\])/gi,"$1open, DOI: <a href='http://search.crossref.org/?q=$2' target='_blank'>$2</a>$3");
}

// Empty email input area, but only on submission page
if (stripEmail && window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/submit\.pl/)!=-1)
{
    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(/https?\:\/\/.*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(/^\\s/gi,'').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(/([a-z])['\u2019]([a-z])/gi,function(m, p1, p2){return p1+'\\''+p2.toLowerCase();}).replace(/\\bx(86|64)\\b/gi,'x$1').replace(/\\s$/gi,'');");
            boxes[x].parentNode.insertBefore(button, boxes[x].nextSibling);
            if (window.location.href.search(/https?\:\/\/.*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);
            }
        }
    }
}

// Add warning for creating a story in the past
if (window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/admin\.pl/)!=-1)
{
    var boxes = document.getElementsByTagName("input");
    for (var x=0; x<boxes.length; x++)
    {
        if (boxes[x].name == "op" && (boxes[x].value == "save"))
        {
            // New onclick extracts the post date, compares to the current date, and only submits if the post date is in the future or the user overrides the warning:
            boxes[x].setAttribute("onclick","var d = new Date(document.getElementById('slashstoryform').elements['time'].value.replace(/\\s/,'T')); var a = true; if (d < Date.now()){a = confirm('Are you sure you want to post a story '+(Math.round((Date.now()-d)/60000))+' minutes in the past?');} if (a) {st_submit(this);}");
        }
    }
}

// Add draft capabilties to story submission form
if (window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/submit\.pl/)!=-1)
{
    var boxes = document.getElementsByTagName("textarea");
    for (var x=0; x<boxes.length; x++)
    {
        if (boxes[x].name == "story")
        {
            var p = document.createElement("p");

            // Save Draft button
            var button = document.createElement("input");
            button.setAttribute("type","button");
            button.setAttribute("value","Save Draft");
            button.setAttribute("onclick","saveSoydraft();");
            p.appendChild(button);

            p.appendChild(document.createTextNode(" "));

            // Discard Draft button
            var button = document.createElement("input");
            button.setAttribute("type","button");
            button.setAttribute("id","discardDraft");
            button.setAttribute("value","Discard");
            // Disable the Discard Draft button onload if no draft is available
            if(!localStorage.getItem("soydraft"))
            {
                button.setAttribute("disabled","disabled");
            }
            else
            {
                button.setAttribute("onclick","discardSoydraft();");
            }
            p.appendChild(button);

            p.appendChild(document.createTextNode(" "));

            // Autosave checkbox
            var span = document.createElement("span");
            span.setAttribute("id","autosaveBar");
            // Hide autosave checkbox onload if no draft is available
            if (document.getElementById("storyTitle").value == "" && boxes[x].value == "")
            {
                if(localStorage.getItem("soydraft"))
                {
                    span.setAttribute("style","visibility:visible;");
                }
                else
                {
                    span.setAttribute("style","visibility:hidden;");
                }
            }
            span.appendChild(document.createTextNode("Autosave?"));
            var checkbox = document.createElement("input");
            checkbox.setAttribute("type","checkbox");
            checkbox.setAttribute("id","autosave");
            checkbox.setAttribute("value","");
            checkbox.setAttribute("onclick","if (this.checked==false){autosaveOff();} else {autosaveOn();}");
            checkbox.setAttribute("style","vertical-align:middle;");
            span.appendChild(checkbox);
            span.appendChild(document.createTextNode(" "));
            p.appendChild(span);

            // "Saved." text will appear and fade out whenever a draft is saved
            var span2 = document.createElement("span");
            span2.setAttribute("id","autosaveState");
            span2.setAttribute("style","opacity:0;");
            span2.appendChild(document.createTextNode("Saved."));
            p.appendChild(span2);

            boxes[x].parentNode.insertBefore(p, boxes[x]);

            // Load draft if it exists, but only if workspace is clear
            if (document.getElementById("storyTitle").value == "" && boxes[x].value == "")
            {
                if(localStorage.getItem("soydraft"))
                {
                    document.getElementById("storyTitle").value = decodeURI(JSON.parse(localStorage.getItem("soydraft"))[0]);
                    document.getElementById("primaryskid").value = JSON.parse(localStorage.getItem("soydraft"))[1];
                    document.getElementById("tid").value = JSON.parse(localStorage.getItem("soydraft"))[2];
                    boxes[x].value = decodeURI(JSON.parse(localStorage.getItem("soydraft"))[3]);
                }
            }
        }
    }
}

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,128565],[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",":-)",":^)","(^_^;)","(\u00A0\u0361\u00B0\u00A0\u035C\u0296\u00A0\u0361\u00B0)","(\u00A0\u0361\u007E\u00A0\u035C\u0296\u00A0\u0361\u00B0)\uFEFF","\u00AF\u005C\u005F(\u30C4)\u005F\u002F\u00AF","(\u256F\u00B0\u25A1\u00B0\uFF09\u256F\uFE35\u00A0\u253B\u2501\u253B","(\u30CE\u0CA0\u76CA\u0CA0)\u30CE\u5F61\u253B\u2501\u253B","(\u0060\uFF65\u03C9\uFF65\u00B4)","\u0CA0_\u0CA0","\u0295\u2022\u1D25\u2022\u0294","(\u3065\uFFE3\u00A0\u00B3\uFFE3)\u3065","\u0669(\u204E\u275B\u1D17\u275B\u204E)\u06F6","\u30FD\u0F3C\u0E88\u0644\u035C\u0E88\u0F3D\uFF89","(\uB208\u2038\uB208)","\u006F(\u3003\uFF3E\u25BD\uFF3E\u3003)\u006F","\u0028\u0028\u30FE\u0028\u2267\u76BF\u2266\uFF1B\u0029\u30CE\uFF3F\u0029\u0029","\u30FD\u0028\u002A\u2312\u2207\u2312\u002A\u0029\uFF89","\u0028\u2267\u2207\u2266\u0029\u002F"]); // 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) } }"));

// Add save submission function
temp.appendChild(document.createTextNode("function saveSoydraft() { try {window.clearTimeout(timer);} catch(e){} var boxes = document.getElementsByTagName('textarea'); for (var x=0; x<boxes.length; x++) { if (boxes[x].name == 'story') { if (document.getElementById('storyTitle').value!=''||boxes[x].value!='') { document.getElementById('autosaveBar').style.visibility='visible'; document.getElementById('autosaveState').style.transition='opacity 0s'; document.getElementById('autosaveState').style.opacity='1'; document.getElementById('autosaveState').offsetWidth = document.getElementById('autosaveState').offsetWidth; document.getElementById('autosaveState').style.transition='opacity 1s'; document.getElementById('autosaveState').style.opacity='0'; localStorage.setItem('soydraft',JSON.stringify([encodeURI(document.getElementById('storyTitle').value),document.getElementById('primaryskid').value,document.getElementById('tid').value,encodeURI(boxes[x].value)])); document.getElementById('discardDraft').removeAttribute('disabled'); document.getElementById('discardDraft').setAttribute('onclick','discardSoydraft();'); } else { alert('There is no title or story to save.'); } break; } } }"));

// Add discard submission function
temp.appendChild(document.createTextNode("function discardSoydraft() { autosaveOff(); document.getElementById('autosave').checked=false; document.getElementById('autosaveBar').style.visibility='hidden'; localStorage.removeItem('soydraft'); document.getElementById('discardDraft').setAttribute('disabled','disabled'); document.getElementById('discardDraft').removeAttribute('onclick'); }"));

// Add autosave functions
temp.appendChild(document.createTextNode("function autosaveOn() { var boxes = document.getElementsByTagName('textarea'); for (var x=0; x<boxes.length; x++) { if (boxes[x].name == 'story') { boxes[x].onkeydown = function() {try {window.clearTimeout(timer);} catch(e){} timer = window.setTimeout(function() { if(document.getElementById(\"autosaveBar\").style.visibility==\"visible\") {saveSoydraft();} }, 3000);}; } } document.getElementById('storyTitle').onkeydown = function() {try {window.clearTimeout(timer);} catch(e){} timer = window.setTimeout(function() { if(document.getElementById(\"autosaveBar\").style.visibility==\"visible\") {saveSoydraft();} }, 3000);}; }"));
temp.appendChild(document.createTextNode("function autosaveOff() { var boxes = document.getElementsByTagName('textarea'); for (var x=0; x<boxes.length; x++) { if (boxes[x].name == 'story') { try {window.clearTimeout(timer);} catch(e){} boxes[x].onkeydown = null; } } document.getElementById('storyTitle').onkeydown = null; }"));

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