您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Save format, images and links when pasting from clipboard into commentbox in derpibooru. (script by VcSaJen, icon by TryHardBrony)
// ==UserScript== // @name ClipFormat! (Derpibooru - comment autoformatter from clipboard) // @namespace https://derpiboo.ru/pasteformatizer // @description Save format, images and links when pasting from clipboard into commentbox in derpibooru. (script by VcSaJen, icon by TryHardBrony) // @include /https?://(www\.)?derpiboo.ru/.*/ // @include /https?://(www\.)?trixiebooru.org/.*/ // @include /https?://(www\.)?derpibooru.org/.*/ // @icon https://dl.dropboxusercontent.com/u/7410519/ScreenS/i_came_to_write_fanfics_by_tryhardbrony-64px-256col.png // @license LGPL 3 or later // @version 0.8 // @grant GM_addStyle // @require http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/jquery.selection/1.0.1/jquery.selection.min.js // @require https://greasyfork.org/scripts/4535-htmlparser/code/htmlparser.js?version=15389 // ==/UserScript== (function($) //< custom $ compatibility { $(function() //ready { var textasrea_selector = 'textarea#comment_body,textarea#topic_posts_attributes_0_body,textarea#post_body,textarea#image_description'; var simple_format_tags = /^(em|i|strong|b|ins|u|del|strike|s|pre|sup|sub|cite)$/i; var basic_fomat_chars = {"strong":"*", "b":"**", "em":"_", "i":"__", "del":"-", "ins":"+", "sup":"^", "sub":"~", "pre":"@", "cite":"??" }; //$(textasrea_selector).after('<textarea id="mymymy"></textarea>'); $(textasrea_selector).parent().before($('<div/>',{'class': 'field'}).append($('<label/>',{'for': 'clipformat_check', text: 'Clipformat', 'title': 'Format text from clipboard'}), $('<input/>',{id: 'clipformat_check', 'type': 'checkbox'}), $('<span/>',{id: 'clipformat_error', 'style': 'display:none;', 'class': 'comment_deleted', text: ' Error!'}))); var mycbChecked; $('#clipformat_check').change(function (e) { mycbChecked = $('#clipformat_check').prop('checked'); if (mycbChecked) { $(textasrea_selector).css('outline-color', '#5E95BC'); $(textasrea_selector).css('outline-width', '1px'); $(textasrea_selector).css('outline-style', 'solid'); } else { $(textasrea_selector).css('outline-style', 'none'); } }).dblclick(function (e) { $('#clipformat_check').prop("checked", true); $('#clipformat_check').prop("indeterminate", true); $('#clipformat_check').trigger("change"); }); $(textasrea_selector).on('paste', function (e) { if (!mycbChecked) return; if (e.originalEvent.clipboardData || e.clipboardData) { //alert('ok!'); $('#clipformat_error').hide(); var s = ""; var clipdata = (e.originalEvent.clipboardData || e.clipboardData); /*s+="html:"+clipdata.getData('text/html')+"\n"; s+="plain:"+clipdata.getData('text/plain')+"\n"; var types = clipdata.types; var count = types.length; s+="types:\n"; for (var i = 0; i < count; i++) { s+="type"+i+": "+types[i]+"\n"; } //$("#output").text(s); alert(s);*/ try { s=""; var myhtml = clipdata.getData('text/html'); if (!myhtml) { //alert("NO HTML!"); //flashElement($(textasrea_selector)); return; } if (/^<html xmlns:v="urn:schemas-microsoft-com:vml"/.test(myhtml)) myhtml=cleanHTML(myhtml); myhtml=myhtml.replace(/<!?\[[^>]*?\](?!--)?>/g, ""); myhtml=myhtml.replace(/<title>([\s\S].*?)<\/title>/gi, " "); myhtml=myhtml.replace(/<style[\s\S]*?<\/style>/gi, " "); if (!$('#clipformat_check').prop('indeterminate')) { $('#clipformat_check').prop("checked", false); $('#clipformat_check').trigger("change"); } //alert(myhtml); function writableTag(tag) { var result = tag; if (result==="strike"||result==="s") result="del"; if (result==="u") result="ins"; /*em|i|strong|b|ins|u|del|strike|pre|sup|sub*/ return result; } function htmlCharize(s) { var i, result=""; for (i=0;i<s.length;i++) { result+='&#'+s.charCodeAt(i)+';'; } //alert("result="+result); return result; } function escapeFull(s) { var i, result=""; for (i=0;i<s.length;i++) { var tmp=""; tmp=Number(s.charCodeAt(i)).toString(16); if (tmp.length<2) tmp='0'+tmp; result+='%'+tmp; } //alert("result="+result); return result; } function escapeRegexStr(s) { var i, result=""; for (i=0;i<s.length;i++) { var ch = s.charAt(i); if (ch==="*"||ch==="+"||ch==="?"||ch==="\\"||ch==="^"||ch==="$"||ch==="."||ch==="|"||ch==="("||ch===")"||ch==="["||ch==="]"|| ch==="{"||ch==="}") result+="\\"+ch; else result+=ch; } return result; } var nomoreparseing = false; var currentLinkTitle; var currentLinkURL; var currentLinkContent=""; var currently_a = false; var spoilerLevel = 0; var state = {"strong":false, "b":false, "em":false, "i":false, "del":false, "ins":false, "sup":false, "sub":false, "pre":false, "cite":false}; HTMLParser(myhtml, { start: function( tag, attrs, unary ) { tag=tag.toLowerCase(); if (tag.match(simple_format_tags)) { s += "<" + writableTag(tag) + ">"; state[writableTag(tag)]=true; return; } var atlist = {"href": "", "src": "http://"}; /*s += "[" + tag; for ( var i = 0; i < attrs.length; i++ ) s += " " + attrs[i].name + '="' + attrs[i].escaped + '"'; s += (unary ? "/" : "") + "]";*/ for ( var i = 0; i < attrs.length; i++ ) atlist[attrs[i].name.toLowerCase()]=attrs[i].value; if (unary && tag==="br") s += "\n"; if (tag==="img") { var imgstr = "", imgdescr=""; imgstr += "!"+'<link>'+escapeFull(atlist["src"])+'</link>'; if (!(currently_a&¤tLinkTitle)) { if (atlist["title"]!==undefined) imgdescr = atlist["title"]; else if (atlist["alt"]!==undefined) imgdescr = atlist["alt"]; if (/\)|!/.test(imgdescr)) imgdescr = "[=="+imgdescr+"==]"; } if (imgdescr) imgstr += "<bracket>"+imgdescr+"</bracket>"; imgstr += "!"; s += imgstr; if (currently_a) currentLinkContent+="[img]"; } if (tag==="a") { if (atlist["href"]==="") { currently_a = false; return; } s += '"'; currentLinkTitle = decodeSimpleHTMLEntities(atlist["title"]===undefined ? "" : atlist["title"]); if (/\)/.test(currentLinkTitle)) currentLinkTitle = "[=="+currentLinkTitle+"==]"; currentLinkURL=atlist["href"]; currentLinkURL=currentLinkURL.replace(/^.+deviantart\.com\/users\/outgoing\?(.+)$/ig, "$1"); if (!currentLinkURL.match(/^(?:https?:)/)) currentLinkURL="#nope"; currentLinkContent=""; currently_a = true; } if (tag==="blockquote") { var bqtext = ""; bqtext+="[bq"; if (atlist["title"]!==undefined) { bqtext+='="'+atlist["title"]+'"'; } bqtext+="]"; s+=bqtext; } if (tag==="span") { //s+="[span]"; if (spoilerLevel>0) spoilerLevel++; if (atlist["class"]==="spoiler" || atlist["class"]==="spoiler-revealed") { s+="[spoiler]"; spoilerLevel++; } } if (tag==="acronym"||tag==="abbr") { s+="<acronym"; if (atlist["title"]!==undefined) { s+='='+atlist["title"]; } s+=">"; } if (tag==="hr") { s+="\n-----------\n"; return; } }, end: function( tag ) { tag=tag.toLowerCase(); if (tag.match(simple_format_tags)) { s += "</" + writableTag(tag) + ">"; state[writableTag(tag)]=false; return; } if (tag.match(/^(blockquote|dd|dl|fieldset|form|h[1-6]|hr|ol|p|pre|section|table|tfoot|ul|div|li)$/i)) { s += "\n"; } if (tag==="a") { if (!currently_a) return; currently_a = false; if (currentLinkContent==="") s+=" "; var linkstr = ""; if (currentLinkTitle!=="") linkstr+="<bracket>"+currentLinkTitle+"</bracket>"; currentLinkURL=currentLinkURL.replace(/#$/g,""); linkstr+='":<link>'+escapeFull(currentLinkURL)+'</link>'; //I'm a master of kludge! s+=linkstr+' '; return; } if (tag==="blockquote") { s+="[/bq]"; } if (tag==="span") { //s+="[/span]"; if (spoilerLevel===1) { s+="[/spoiler]"; spoilerLevel=0; } if (spoilerLevel>0) spoilerLevel--; } if (tag==="acronym"||tag==="abbr") { s+="</acronym>"; } if (tag==="html") nomoreparseing = true; }, chars: function( text ) { if (nomoreparseing) return; var trimed = text.replace(/\s+/g, " "); if (s.length>0 && s.charAt(s.length-1)===" " && (/^\s/.test(trimed))) trimed = trimed.replace(/^\s+/g, ""); for(var key in basic_fomat_chars) { if (state[key]) { var fmtchr = basic_fomat_chars[key].charAt(0); fmtchr=escapeRegexStr(fmtchr); var myregex = new RegExp("(?:(\\W)"+fmtchr+")|(?:"+fmtchr+"(?=\\W))", 'gm'); trimed = trimed.replace(myregex, "$1"+htmlCharize(fmtchr.charAt(fmtchr.length-1))); } } if (currently_a) { trimed = trimed.replace(/"/g, """); if (currentLinkTitle==="") { trimed = trimed.replace(/\(/g, "("); trimed = trimed.replace(/\)/g, ")"); } if (currentLinkContent=="") { trimed = trimed.replace(/^\s/g, " "); } currentLinkContent+=trimed; } //if (state.strong||state.b) text.replace(/(?:(\s)\*)|(?:\*(?=\s))/gm, "*"); //if (state.em||state.i) text.replace(/(?:(\s)\*)|(?:\*(?=\s))/gm, "_"); s += trimed; }, comment: function( text ) { //s += "/*" + text + "*/"; } }); //var myAntiFormatRegex = /(\W|^)(\*|\*\*|_|__|\?\?|\+|-|\^|~|@)((?:\S)|(?:(?!\2\s)\S.*?\S))\2(?!\2)(?:(?=\W)|$)/g; for(var tag in basic_fomat_chars) { var myAntiFormatRegex = new RegExp("(\\W|^)("+escapeRegexStr(basic_fomat_chars[tag])+")((?:\\S)|(?:(?!\\2\\s)\\S[\\s\\S]*?\\S))\\2(?!\\2)(?:(?=\\W)|$)", 'g'); s=s.replace(myAntiFormatRegex, function(str, p1, p2, p3, offset, fullstr) { //alert("replacing!"+p1+","+p2+","+p3); if (/^-+$/.test(p3)) return str; return p1+htmlCharize(p2)+p3+htmlCharize(p2); }); } s=s.replace(/\(c\)|\(tm\)|\(r\)|-{5,}|[A-Z]{2,}\([^)]+\)/g, "[==$&==]"); s=s.replace(/([^-])(-{2,4}(?!-))/gi, function(str, p1, p2, offset, fullstr) {return p1+htmlCharize(p2);}); s=s.replace(/\[(<.+?>)\]/g, "[$1]"); //----------- //Escape: end, Format: begin //----------- s=s.replace(/<acronym=([^>)]+)>([A-Z]{2,})<\/acronym>/g, "$2($1)"); s=s.replace(/<acronym[^>]*>(.+?)<\/acronym>/g, "$1"); //var myReplSimpleFormatRegex = new RegExp(, 'g'); for(var tag in basic_fomat_chars) { var myTagRegEx = new RegExp("(\\w?)<"+tag+">(\\s*)([\\s\\S]*?)(\\s?)</"+tag+">(\\w?)", 'g'); s=s.replace(myTagRegEx, function(str, p1, p2, p3, p4, p5, offset, fullstr) { if (p3==="") return p1+p2+p4+p5; var b = p1!=="" || p5!=="" || p4!==""; if ((tag==="sup"||tag==="sub")&&!b) { if (offset>0&&!fullstr.charAt(offset-1).match(/[\s\^~]/)) { b=true; } } //alert(p1+','+p2+','+p3+','+p4+','+p5); return p1+(b?"[":"")+basic_fomat_chars[tag]+htmlCharize(p2)+p3+p4+basic_fomat_chars[tag]+(b?"]":"")+p5; //DONE: Escape brackets in titles and quotes in links! }); } s=s.replace(/<bracket>/g, "\("); s=s.replace(/<\/bracket>/g, "\)"); s=s.replace(/<link>([0-9A-Z%].*?)<\/link>/gi, function(str, p1, offset, fullstr) { return unescape(p1); }); //alert(s); //$('#mymymy').val(s); //clipdata.setData("Text", s) e.preventDefault(); //this.value = s; $(this).selection('replace', { text: s, caret: 'end' }); } catch(ex) { //DONE: add user-friendly error-handling!<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $('#clipformat_error').show(); $('#clipformat_error').attr("title", ex + "\nname: " + ex.name + "\nmessage: " + ex.message + "\nstack: " + ex.stack); //alert(s); //alert(err); } /*finally { }*/ } else /*alert("Nope.jpg")*/; }); }); // removes MS Office generated guff by Anthony (http://forums.squizsuite.net/index.php?showtopic=11304) function cleanHTML(input) { // 1. remove line breaks / Mso classes var stringStripper = /(\n|\r| class=(")?Mso[a-zA-Z]+(")?)/g; var output = input.replace(stringStripper, ' '); // 2. strip Word generated HTML comments var commentSripper = new RegExp('<!--(.*?)-->','g'); var output = output.replace(commentSripper, ''); var tagStripper = new RegExp('<(/)*(meta|link|span|\\?xml:|st1:|o:|font)(.*?)>','gi'); // 3. remove tags leave content if any output = output.replace(tagStripper, ''); // 4. Remove everything in between and including tags '<style(.)style(.)>' var badTags = ['style', 'script','applet','embed','noframes','noscript']; for (var i=0; i< badTags.length; i++) { tagStripper = new RegExp('<'+badTags[i]+'.*?'+badTags[i]+'(.*?)>', 'gi'); output = output.replace(tagStripper, ''); } // 5. remove attributes ' style="..."' var badAttributes = ['style', 'start']; for (var i=0; i< badAttributes.length; i++) { var attributeStripper = new RegExp(' ' + badAttributes[i] + '="(.*?)"','gi'); output = output.replace(attributeStripper, ''); } return output; } function flashElement($el) { $el.css({outline:'1px solid yellow'}); setTimeout(function() { $('#clipformat_check').trigger("change"); }, 500); } function decodeSimpleHTMLEntities(text) { //by William Lahti var entities = [ ['apos', '\''], ['amp', '&'], ['lt', '<'], ['gt', '>'] ]; for (var i = 0, max = entities.length; i < max; ++i) text = text.replace(new RegExp('&'+entities[i][0]+';', 'g'), entities[i][1]); return text; } })( jQuery ); /* Notes: regulars: <b>(?=\S)([^<]*?\S)<\/b> -nope (\w?)<b>(\s*)(.*?)(\s*)<\/b>(\w?) -yup */