Greasy Fork is available in English.

Go[Lang/Doc] Syntax Highlighter

Syntax highlights any <pre> element on the Go or GoDoc site.

  1. // ==UserScript==
  2. // @name Go[Lang/Doc] Syntax Highlighter
  3. // @namespace http://github.com/kdar
  4. // @version 0.1
  5. // @description Syntax highlights any <pre> element on the Go or GoDoc site.
  6. // @author Kevin Darlington
  7. // @match http://godoc.org/*
  8. // @match http://golang.org/pkg/*
  9. // @match https://godoc.org/*
  10. // @match https://golang.org/pkg/*
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. // Base64 encoder/decoder. Modified symbols to not use Go operators.
  15. // utf8 aware.
  16. var Base64 = {
  17. // private property
  18. _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789?$=",
  19.  
  20. // public method for encoding
  21. encode : function (input) {
  22. var output = "";
  23. var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  24. var i = 0;
  25.  
  26. input = Base64._utf8_encode(input);
  27.  
  28. while (i < input.length) {
  29.  
  30. chr1 = input.charCodeAt(i++);
  31. chr2 = input.charCodeAt(i++);
  32. chr3 = input.charCodeAt(i++);
  33.  
  34. enc1 = chr1 >> 2;
  35. enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  36. enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  37. enc4 = chr3 & 63;
  38.  
  39. if (isNaN(chr2)) {
  40. enc3 = enc4 = 64;
  41. } else if (isNaN(chr3)) {
  42. enc4 = 64;
  43. }
  44.  
  45. output = output +
  46. Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
  47. Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);
  48. }
  49.  
  50. return output;
  51. },
  52.  
  53. // public method for decoding
  54. decode : function (input) {
  55. var output = "";
  56. var chr1, chr2, chr3;
  57. var enc1, enc2, enc3, enc4;
  58. var i = 0;
  59.  
  60. input = input.replace(/[^A-Za-z0-9\?\$\=]/g, "");
  61.  
  62. while (i < input.length) {
  63. enc1 = Base64._keyStr.indexOf(input.charAt(i++));
  64. enc2 = Base64._keyStr.indexOf(input.charAt(i++));
  65. enc3 = Base64._keyStr.indexOf(input.charAt(i++));
  66. enc4 = Base64._keyStr.indexOf(input.charAt(i++));
  67.  
  68. chr1 = (enc1 << 2) | (enc2 >> 4);
  69. chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  70. chr3 = ((enc3 & 3) << 6) | enc4;
  71.  
  72. output = output + String.fromCharCode(chr1);
  73.  
  74. if (enc3 != 64) {
  75. output = output + String.fromCharCode(chr2);
  76. }
  77. if (enc4 != 64) {
  78. output = output + String.fromCharCode(chr3);
  79. }
  80. }
  81.  
  82. output = Base64._utf8_decode(output);
  83.  
  84. return output;
  85. },
  86.  
  87. // private method for UTF-8 encoding
  88. _utf8_encode : function (string) {
  89. string = string.replace(/\r\n/g,"\n");
  90. var utftext = "";
  91.  
  92. for (var n = 0; n < string.length; n++) {
  93.  
  94. var c = string.charCodeAt(n);
  95.  
  96. if (c < 128) {
  97. utftext += String.fromCharCode(c);
  98. }
  99. else if((c > 127) && (c < 2048)) {
  100. utftext += String.fromCharCode((c >> 6) | 192);
  101. utftext += String.fromCharCode((c & 63) | 128);
  102. }
  103. else {
  104. utftext += String.fromCharCode((c >> 12) | 224);
  105. utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  106. utftext += String.fromCharCode((c & 63) | 128);
  107. }
  108.  
  109. }
  110.  
  111. return utftext;
  112. },
  113.  
  114. // private method for UTF-8 decoding
  115. _utf8_decode : function (utftext) {
  116. var string = "";
  117. var i = 0;
  118. var c = c1 = c2 = 0;
  119.  
  120. while ( i < utftext.length ) {
  121.  
  122. c = utftext.charCodeAt(i);
  123.  
  124. if (c < 128) {
  125. string += String.fromCharCode(c);
  126. i++;
  127. }
  128. else if((c > 191) && (c < 224)) {
  129. c2 = utftext.charCodeAt(i+1);
  130. string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
  131. i += 2;
  132. }
  133. else {
  134. c2 = utftext.charCodeAt(i+1);
  135. c3 = utftext.charCodeAt(i+2);
  136. string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  137. i += 3;
  138. }
  139.  
  140. }
  141. return string;
  142. }
  143. };
  144.  
  145. // repeats pattern count times
  146. function repeat(pattern, count) {
  147. if (count < 1) return '';
  148. var result = '';
  149. while (count > 1) {
  150. if (count & 1) result += pattern;
  151. count >>= 1, pattern += pattern;
  152. }
  153. return result + pattern;
  154. }
  155.  
  156. // simply just adds a global css style
  157. function addGlobalStyle(css) {
  158. var head, style;
  159. head = document.getElementsByTagName('head')[0];
  160. if (!head) { return; }
  161. style = document.createElement('style');
  162. style.type = 'text/css';
  163. style.innerHTML = css;
  164. head.appendChild(style);
  165. }
  166.  
  167. // since & and ; are operators in Go, if Prism encounters an HTML escaped value, it converts it to
  168. // <span class="token operator">&amp;</span>VALUE<span class="token operator">;</span>
  169. // So, we convert it back.
  170. function htmlDecode(str) {
  171. var entityMap = {
  172. "&": 'amp',
  173. "<": "lt",
  174. ">": "gt",
  175. '"': 'quot',
  176. "'": '#39',
  177. "/": '#x2F'
  178. };
  179. var start = '<span class="token operator">&amp;</span>';
  180. var end = '<span class="token operator">;</span>';
  181. for (var x in entityMap) {
  182. str = str.replace(new RegExp(start+entityMap[x]+end, "gm"), "&" + entityMap[x] + ";");
  183. }
  184. return str;
  185. }
  186.  
  187. (function(d) {
  188. var document = d;
  189. /* http://prismjs.com/download.html?themes=prism-okaidia&languages=clike+go&plugins=line-numbers */
  190. self=typeof window!="undefined"?window:typeof WorkerGlobalScope!="undefined"&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):t.util.type(e)==="Array"?e.map(t.util.encode):e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},clone:function(e){var n=t.util.type(e);switch(n){case"Object":var r={};for(var i in e)e.hasOwnProperty(i)&&(r[i]=t.util.clone(e[i]));return r;case"Array":return e.slice()}return e}},languages:{extend:function(e,n){var r=t.util.clone(t.languages[e]);for(var i in n)r[i]=n[i];return r},insertBefore:function(e,n,r,i){i=i||t.languages;var s=i[e];if(arguments.length==2){r=arguments[1];for(var o in r)r.hasOwnProperty(o)&&(s[o]=r[o]);return s}var u={};for(var a in s)if(s.hasOwnProperty(a)){if(a==n)for(var o in r)r.hasOwnProperty(o)&&(u[o]=r[o]);u[a]=s[a]}t.languages.DFS(t.languages,function(t,n){n===i[e]&&t!=e&&(this[t]=u)});return i[e]=u},DFS:function(e,n,r){for(var i in e)if(e.hasOwnProperty(i)){n.call(e,i,e[i],r||i);t.util.type(e[i])==="Object"?t.languages.DFS(e[i],n):t.util.type(e[i])==="Array"&&t.languages.DFS(e[i],n,i)}}},highlightAll:function(e,n){var r=document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');for(var i=0,s;s=r[i++];)t.highlightElement(s,e===!0,n)},highlightElement:function(r,i,s){var o,u,a=r;while(a&&!e.test(a.className))a=a.parentNode;if(a){o=(a.className.match(e)||[,""])[1];u=t.languages[o]}if(!u)return;r.className=r.className.replace(e,"").replace(/\s+/g," ")+" language-"+o;a=r.parentNode;/pre/i.test(a.nodeName)&&(a.className=a.className.replace(e,"").replace(/\s+/g," ")+" language-"+o);var f=r.textContent;if(!f)return;var l={element:r,language:o,grammar:u,code:f};t.hooks.run("before-highlight",l);if(i&&self.Worker){var c=new Worker(t.filename);c.onmessage=function(e){l.highlightedCode=n.stringify(JSON.parse(e.data),o);t.hooks.run("before-insert",l);l.element.innerHTML=l.highlightedCode;s&&s.call(l.element);t.hooks.run("after-highlight",l)};c.postMessage(JSON.stringify({language:l.language,code:l.code}))}else{l.highlightedCode=t.highlight(l.code,l.grammar,l.language);t.hooks.run("before-insert",l);l.element.innerHTML=l.highlightedCode;s&&s.call(r);t.hooks.run("after-highlight",l)}},highlight:function(e,r,i){var s=t.tokenize(e,r);return n.stringify(t.util.encode(s),i)},tokenize:function(e,n,r){var i=t.Token,s=[e],o=n.rest;if(o){for(var u in o)n[u]=o[u];delete n.rest}e:for(var u in n){if(!n.hasOwnProperty(u)||!n[u])continue;var a=n[u];a=t.util.type(a)==="Array"?a:[a];for(var f=0;f<a.length;++f){var l=a[f],c=l.inside,h=!!l.lookbehind,p=0,d=l.alias;l=l.pattern||l;for(var v=0;v<s.length;v++){var m=s[v];if(s.length>e.length)break e;if(m instanceof i)continue;l.lastIndex=0;var g=l.exec(m);if(g){h&&(p=g[1].length);var y=g.index-1+p,g=g[0].slice(p),b=g.length,w=y+b,E=m.slice(0,y+1),S=m.slice(w+1),x=[v,1];E&&x.push(E);var T=new i(u,c?t.tokenize(g,c):g,d);x.push(T);S&&x.push(S);Array.prototype.splice.apply(s,x)}}}}return s},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[];r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(!r||!r.length)return;for(var i=0,s;s=r[i++];)s(n)}}},n=t.Token=function(e,t,n){this.type=e;this.content=t;this.alias=n};n.stringify=function(e,r,i){if(typeof e=="string")return e;if(Object.prototype.toString.call(e)=="[object Array]")return e.map(function(t){return n.stringify(t,r,e)}).join("");var s={type:e.type,content:n.stringify(e.content,r,i),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:i};s.type=="comment"&&(s.attributes.spellcheck="true");if(e.alias){var o=t.util.type(e.alias)==="Array"?e.alias:[e.alias];Array.prototype.push.apply(s.classes,o)}t.hooks.run("wrap",s);var u="";for(var a in s.attributes)u+=a+'="'+(s.attributes[a]||"")+'"';return"<"+s.tag+' class="'+s.classes.join(" ")+'" '+u+">"+s.content+"</"+s.tag+">"};if(!self.document){if(!self.addEventListener)return self.Prism;self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,i=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(i,t.languages[r]))));self.close()},!1);return self.Prism}var r=document.getElementsByTagName("script");r=r[r.length-1];if(r){t.filename=r.src;document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)}return self.Prism}();typeof module!="undefined"&&module.exports&&(module.exports=Prism);;
  191. Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//g,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*?(\r?\n|$)/g,lookbehind:!0}],string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/gi,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/gi,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};;
  192. Prism.languages.go=Prism.languages.extend("clike",{keyword:/\b(break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/g,builtin:/\b(bool|byte|complex(64|128)|error|float(32|64)|rune|string|u?int(8|16|32|64|)|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(ln)?|real|recover)\b/g,"boolean":/\b(_|iota|nil|true|false)\b/g,operator:/([(){}\[\]]|[*\/%^!]=?|\+[=+]?|-[>=-]?|\|[=|]?|>[=>]?|<(<|[=-])?|==?|&(&|=|^=?)?|\.(\.\.)?|[,;]|:=?)/g,number:/\b(-?(0x[a-f\d]+|(\d+\.?\d*|\.\d+)(e[-+]?\d+)?)i?)\b/gi,string:/("|'|`)(\\?.|\r|\n)*?\1/g}),delete Prism.languages.go["class-name"];;
  193. Prism.hooks.add("after-highlight",function(e){var n=e.element.parentNode;if(n&&/pre/i.test(n.nodeName)&&-1!==n.className.indexOf("line-numbers")){var t,a=1+e.code.split("\n").length;lines=new Array(a),lines=lines.join("<span></span>"),t=document.createElement("span"),t.className="line-numbers-rows",t.innerHTML=lines,n.hasAttribute("data-start")&&(n.style.counterReset="linenumber "+(parseInt(n.getAttribute("data-start"),10)-1)),e.element.appendChild(t)}});;
  194.  
  195. //addGlobalStyle('@import url("//prismjs.com/themes/prism-coy.css")');
  196. //addGlobalStyle('@import url("//prismjs.com/themes/prism-okaidia.css")');
  197. addGlobalStyle("code[class*=language-],pre[class*=language-]{color:#f8f8f2;background:0 0;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#272822}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#f8f8f2}.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}");
  198. addGlobalStyle('.language-go a {color: #F3A44E;}');
  199. // find every <pre>, wrap the innerHTML in <code>, and add the Prism class(es).
  200. var pres = d.getElementsByTagName("pre");
  201. for (var i = 0; i < pres.length; i++) {
  202. var c = d.createElement('code');
  203. c.innerHTML = pres[i].innerHTML;
  204. c.className = pres[i].className + " language-go";
  205. pres[i].innerHTML = "";
  206. pres[i].appendChild(c);
  207. }
  208. // Before we insert, take the element's innerHTML and replace all the html with
  209. // base64 encoding. We do this so we don't lose hyperlinks.
  210. Prism.hooks.add('before-insert', function(env) {
  211. var code = env.element.innerHTML.replace(/<.*?>/g, function(x) {
  212. var encoded = Base64.encode(x);
  213. return " ___" + encoded.replace(/=/g, "") + "___ ";
  214. });
  215. env.highlightedCode = Prism.highlight(code, env.grammar, env.language);
  216. });
  217. // Convert the base64 encoded stuff back to text.
  218. Prism.hooks.add('after-highlight', function(env) {
  219. var tmp = env.element.innerHTML.replace(/ ___(.*?)___ /g, function(_, x) {
  220. var padding = x.length % 4;
  221. if (x > 0) {
  222. x = x + repeat("=", padding);
  223. }
  224. return Base64.decode(x);
  225. });
  226. env.element.innerHTML = htmlDecode(tmp);
  227. });
  228. Prism.highlightAll();
  229. })(document);
  230.