Tatoeba Markdown Editor (new)

Adds MarkEdit to Tatoeba and parses markdown comments as HTML

  1. // ==UserScript==
  2. // @name Tatoeba Markdown Editor (new)
  3. // @namespace Jakob V. <jakov@gmx.at>
  4. // @description Adds MarkEdit to Tatoeba and parses markdown comments as HTML
  5. // @include http*://tatoeba.org/*
  6. // @include http*://*.tatoeba.org/*
  7. // @version 1
  8. // @grant GM_addStyle
  9. // @grant GM_getValue
  10. // @grant GM_setValue
  11. // @require http://code.jquery.com/jquery-1.8.3.js
  12. // @require http://code.jquery.com/ui/1.8.24/jquery-ui.js
  13. // @require https://greasyfork.org/scripts/9431-tatoeba-jquery-ui-css-for-require/code/Tatoeba%20jQuery%20UI%20CSS%20for%20@require.js?version=48895
  14. // @require https://greasyfork.org/scripts/9546-js-pandoc-for-require/code/js-pandoc%20for%20@require.js?version=48894
  15. // @require https://greasyfork.org/scripts/9434-markdown-editor-rehost-for-userscript-integration/code/Markdown%20Editor%20rehost%20for%20userscript%20integration.user.js
  16. // @require https://greasyfork.org/scripts/9547-diff-match-patch-for-require/code/diff_match_patch-for-require.js?version=48896
  17. // @require https://greasyfork.org/scripts/9431-tatoeba-jquery-ui-css-for-require/code/Tatoeba%20jQuery%20UI%20CSS%20for%20@require.js?version=48895
  18. // ==/UserScript==
  19.  
  20. // The MIT License
  21. //
  22. // Original WMD and Showdwon code copyright (c) 2007 John Fraser
  23. // Toolbar images (c) 2009 Dana Robinson
  24. // MarkEdit jQuery rewrite and modified images (c) 2009 Titus Stone
  25. //
  26. // Permission is hereby granted, free of charge, to any person obtaining a copy
  27. // of this software and associated documentation files (the "Software"), to deal
  28. // in the Software without restriction, including without limitation the rights
  29. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  30. // copies of the Software, and to permit persons to whom the Software is
  31. // furnished to do so, subject to the following conditions:
  32. //
  33. // The above copyright notice and this permission notice shall be included in
  34. // all copies or substantial portions of the Software.
  35. //
  36. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  37. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  38. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  39. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  40. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  41. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  42. // THE SOFTWARE.
  43. //
  44.  
  45.  
  46.  
  47. console.log('asdf');
  48.  
  49. // load and save users using markdown
  50. if(true){
  51. // define default variables
  52. default_markdownusers = {
  53. 'jakov': true,
  54. 'Esperantostern': true,
  55. 'sacredceltic': true
  56. };
  57. default_markdownusers = JSON.stringify(default_markdownusers);
  58.  
  59. // get saved variables
  60. markdownusers = GM_getValue('markdownusers');
  61. markdownusers = markdownusers || default_markdownusers;
  62. markdownusers = JSON.parse(markdownusers);
  63. console.log('markdownusers: ' + JSON.stringify(markdownusers));
  64. }
  65.  
  66. // add CSS
  67. if(true){
  68. var css = resourcevar + "\
  69. .markedit { clear: both; display: inline-block; } \
  70. .markedit textarea { width: 100%; } \
  71. .markedit-toolbar { padding: 0.3em; margin: 0; clear: both; height: 22px; border-radius: 8px 8px 0px 0px; -moz-border-radius: 8px 8px 0px 0px;} \
  72. .markedit-toolbar .toolbar-group { margin-right: 0.5em; padding: 0 0 0 5px; float: left; } \
  73. .markedit-toolbar .toggle-group { } \
  74. .markedit-toolbar .toggle-group button { font-size: 0.85em; font-weight: bold; padding: 0.15em 0.5em; } \
  75. .markedit-toolbar .toggle-group button:first-child { -moz-border-radius: 11px 0 0 11px; border-radius: 11px 0 0 11px; } \
  76. .markedit-toolbar .toggle-group button:last-child { -moz-border-radius: 0 11px 11px 0; border-radius: 0 11px 11px 0; } \
  77. .markedit-toolbar button { height: 22px; outline: 0; cursor: pointer; } \
  78. .markedit-toolbar button.icon { width: 22px; background-repeat: no-repeat; margin: 0 5px 0 0; } \
  79. .markedit .light-bg button.icon { background-image: url(images/wmd-buttons.png); } \
  80. .markedit .dark-bg button.icon { background-image: url(images/wmd-buttons-dark.png); } \
  81. .markedit-toolbar button.bold { background-position: 0px 0px; } \
  82. .markedit-toolbar button.italic { background-position: -20px 0px; } \
  83. .markedit-toolbar button.link { background-position: -40px 1px; } \
  84. .markedit-toolbar button.quote { background-position: -60px 0px; } \
  85. .markedit-toolbar button.code { background-position: -80px 1px; } \
  86. .markedit-toolbar button.image { background-position: -100px 1px; } \
  87. .markedit-toolbar button.numberlist { background-position: -120px 0px; } \
  88. .markedit-toolbar button.bulletlist { background-position: -140px 0px; } \
  89. .markedit-toolbar button.heading { background-position: -160px 0px; } \
  90. .markedit-toolbar button.line { background-position: -180px 0px; } \
  91. .markedit-toolbar button.undo { background-position: -200px 0px; } \
  92. .markedit-toolbar button.redo { background-position: -220px 0px; } \
  93. .markedit-toolbar button.help { background-position: -240px 0px; } \
  94. .markedit-dialog { font-size: 0.75em; } \
  95. .markedit-dialog input { width: 100%; } \
  96. .markedit-preview { padding: 15px; } \
  97. \
  98. /* Selectmenu */ \
  99. .ui-selectmenu { display: block; display: inline-block; position: relative; height: 2.2em; vertical-align: middle; text-decoration: none; overflow: hidden; zoom: 1; } \
  100. .ui-selectmenu-icon { position:absolute; right:6px; margin-top:-8px; top: 50%; } \
  101. .ui-selectmenu-menu { padding:0; margin:0; position:absolute; top: 0; display: none; z-index: 1005;} /* z-index: 1005 to make selectmenu work with dialog */ \
  102. .ui-selectmenu-menu ul { padding:0; margin:0; list-style:none; position: relative; overflow: auto; overflow-y: auto ; overflow-x: hidden; -webkit-overflow-scrolling: touch;} \
  103. .ui-selectmenu-open { display: block; } \
  104. .ui-selectmenu-menu-popup { margin-top: -1px; } \
  105. .ui-selectmenu-menu li { padding:0; margin:0; display: block; border-top: 1px dotted transparent; border-bottom: 1px dotted transparent; border-right-width: 0 !important; border-left-width: 0 !important; font-weight: normal !important; } \
  106. .ui-selectmenu-menu li a,.ui-selectmenu-status { line-height: 1.4em; display: block; padding: .405em 2.1em .405em 1em; outline:none; text-decoration:none; } \
  107. .ui-selectmenu-menu li.ui-state-disabled a, .ui-state-disabled { cursor: default; } \
  108. .ui-selectmenu-menu li.ui-selectmenu-hasIcon a, \
  109. .ui-selectmenu-hasIcon .ui-selectmenu-status { padding-left: 20px; position: relative; margin-left: 5px; } \
  110. .ui-selectmenu-menu li .ui-icon, .ui-selectmenu-status .ui-icon { position: absolute; top: 1em; margin-top: -8px; left: 0; } \
  111. .ui-selectmenu-status { line-height: 1.4em; } \
  112. /*.ui-selectmenu-menu li span,.ui-selectmenu-status span { display:block; margin-bottom: .2em; } */\
  113. .ui-selectmenu-menu li .ui-selectmenu-item-header { font-weight: bold; } \
  114. .ui-selectmenu-menu li .ui-selectmenu-item-footer { opacity: .8; } \
  115. /* for optgroups */ \
  116. .ui-selectmenu-menu .ui-selectmenu-group { font-size: 1em; } \
  117. .ui-selectmenu-menu .ui-selectmenu-group .ui-selectmenu-group-label { line-height: 1.4em; display:block; padding: .6em .5em 0; font-weight: bold; } \
  118. .ui-selectmenu-menu .ui-selectmenu-group ul { margin: 0; padding: 0; } \
  119. /* IE6 workaround (dotted transparent borders) */ \
  120. * html .ui-selectmenu-menu li { border-color: pink; filter:chroma(color=pink); width:100%; } \
  121. * html .ui-selectmenu-menu li a { position: relative } \
  122. /* IE7 workaround (opacity disabled) */ \
  123. *+html .ui-state-disabled, *+html .ui-state-disabled a { color: silver; } \
  124. \
  125. /* selectmenu Tatoeba */ \
  126. .ui-selectmenu-status { line-height: 0.7em; } \
  127. .ui-selectmenu { height: 1.5em;} \
  128. .ui-selectmenu a { width: auto !important; } \
  129. .ui-button { padding: 0.1em 0.2em !important; } \
  130. .ui-button-text { padding: 0.1em 0.2em !important; } \
  131. .ui-selectmenu-status .languageFlag { float: none; margin: 0; vertical-align: text-bottom; } \
  132. .ui-selectmenu { height: auto !important; width: auto !important; } \
  133. .ui-selectmenu-menu li a, .ui-selectmenu-status { padding: 0.3em 1.6em 0.3em 0.8em; } \
  134. /*.search_bar a { color: #257D0C !important; } \
  135. .search_bar .select, .search_bar .input { width: auto !important; } \
  136. .search_bar fieldset { float: left; } */ \
  137. \
  138. .markedit .light-bg button.icon { background-image: url('data:image/png;base64,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'); } .markedit .dark-bg button.icon { background-image: url('data:image/png;base64,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'); } \
  139. \
  140. textarea, .unparsedmarkdown { font-family: monospace; } \
  141. \
  142. pre.unparsedmarkdown { white-space: pre-wrap; } \
  143. .unparsedmarkdown br { display: none; } \
  144. .profileDescription .unparsedmarkdown { font-size: 1.3em; } \
  145. .privateMessage div.body { font-size: 1.1em; } \
  146. .privateMessage pre.body { font-size: 1.2em; } \
  147. .sticky .unparsedmarkdown { border: 1px solid grey; } \
  148. .parsedmarkdown { padding: 15px; } \
  149. .parsedmarkdown blockquote, .markedit-preview blockquote { border-left: 0.3em solid #BBBBBB; margin:0.5em 0; padding: 0 1.1em; } \
  150. .parsedmarkdown > :first-child { margin-top: 0 !important; } \
  151. .parsedmarkdown > :last-child { margin-bottom: 0 !important; } \
  152. .parsedmarkdown li { margin: 0.2em 0 !important; } \
  153. .parsedmarkdown p { margin: 0.2em 0 !important; } \
  154. #WallContent { /* max-width: 508px;*/ } \
  155. .parsedmarkdown ul, .parsedmarkdown ol { padding-left: 3em; } \
  156. .parsedmarkdown ul { list-style: disc; } \
  157. \
  158. .parsedmarkdown ul, .parsedmarkdown ol { padding-left: 3em; } \
  159. .parsedmarkdown ul { list-style: disc; } \
  160. \
  161. #sendMessageForm .markedit textarea, .replyFormDiv .markedit textarea, .markedit textarea { min-width: 388px; margin: 3px 0; } \
  162. #SentenceCommentSaveForm textarea, #sendMessageForm textarea { width: 508px; } \
  163. .replyFormDiv textarea { width: 508px; width:100%; } \
  164. #WallSaveForm textarea { width: 508px; } \
  165. #PrivateMessageContent { width: 560px; } \
  166. #PrivateMessageSendForm .input.text { clear:both; display: inline-block; width: 100%; } \
  167. #PrivateMessageSendForm .input.text label { width:auto; } \
  168. #PrivateMessageSendForm .input.text input { float: right; width: 455px; } \
  169. #PrivateMessageSendForm { /* display: table; */ } \
  170. label:empty { display: none; } \
  171. #SentenceCommentSaveForm textarea { width: auto; } \
  172. .markedit-preview { margin-bottom: 3px; } \
  173. \
  174. a[href^='/tags/show_sentences_with_tag/'] { background: none repeat scroll 0 0 #FFE684; border-bottom: 1px solid #DDDDDD; border-radius: 5px 5px 5px 5px; border-right: 1px solid #DDDDDD; padding: 2px 8px; color: #333333 !important; font-size: 1.2em;} \
  175. \
  176. a[href^='/user/profile/'] { } \
  177. a[href^='/sentences/show/'] { } \
  178. \
  179. a[href^='/tags/show_sentences_with_tag/']:before { content:'#'; } \
  180. a[href^='/user/profile/']:before { content:'@'; } \
  181. a[href^='/sentences/show/']:before { content:'?'; } \
  182. \
  183. .comp { padding:2px 8px; line-height:25px; background-color: #FBFFC9; border-bottom: 1px solid #DDDDDD; border-right: 1px solid #DDDDDD; border-radius:3px; } \
  184. .comp del, .patch del {color:red; background-color: #FFE6E6;} \
  185. .comp ins, .patch ins {color:green; background-color: #E6FFE6;} \
  186. .comp .before ins, .patch .before ins {display:none;} \
  187. .comp .after del, .patch .after del {display:none;} \
  188. \
  189. .autocorrect .ui-selectmenu { display: block; } \
  190. .autocorrect { font-size: 0.8em; margin-bottom: 3px; } \
  191. .autocorrect .patch { width: auto; width: -moz-available; display: inline-table !important; font-family: monospace; white-space:pre-wrap; } \
  192. .autocorrect .patch > span { display: table-cell !important; text-align:left;} \
  193. .autocorrect .patch .gets { font-size: x-large !important; } \
  194. .dropdown { border: 1px solid red; height: 100%; margin-top: -1px; position: absolute; right: -1px; top: 0; width: 26px; } \
  195. \
  196. a { -moz-transition: text-shadow 0.5s ease 0s; text-shadow: none;} \
  197. a:hover { text-shadow: 0 0 2px #89C140; } \
  198. \
  199. .parsedmarkdown table, .markedit-preview table { width: auto; } \
  200. .parsedmarkdown th, .parsedmarkdown td, .markedit-preview th, .markedit-preview td { border: 1px solid black; } \
  201. a:hover .markdownmark.solid path { fill: #FB6B10 !important; } \
  202. a:hover .markdownmark.normal path { fill: #FB6B10 !important; } \
  203. a:hover .markdownmark.normal rect { stroke: #FB6B10 !important; } \
  204. ";
  205. GM_addStyle(css);
  206. }
  207.  
  208. if(true){
  209. // diff_match_patch
  210. // the function that outputs the pretty html for the diffs
  211. diff_match_patch.prototype.diff_prettyHtml = function (diffs) {
  212. var html = [];
  213. var i = 0;
  214. for (var x = 0; x < diffs.length; x++) {
  215. var op = diffs[x][0]; // Operation (insert, delete, equal)
  216. var data = diffs[x][1]; // Text of change.
  217. var text = data.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '&para;<BR>');
  218. switch (op) {
  219. case DIFF_INSERT:
  220. html[x] = '<ins>' + text + '</ins>';
  221. break;
  222. case DIFF_DELETE:
  223. html[x] = '<del>' + text + '</del>';
  224. break;
  225. case DIFF_EQUAL:
  226. html[x] = '<span>' + text + '</span>';
  227. break;
  228. }
  229. if (op !== DIFF_DELETE) {
  230. i += data.length;
  231. }
  232. }
  233. return html.join('');
  234. };
  235.  
  236. // http://stackoverflow.com/questions/8584098/how-to-change-an-element-type-using-jquery
  237. $.fn.changeElementType = function(newType) {
  238. var attrs = {};
  239.  
  240. $.each(this[0].attributes, function(idx, attr) {
  241. attrs[attr.nodeName] = attr.nodeValue;
  242. });
  243. var newelement = $("<" + newType + "/>", attrs).append($(this).contents());
  244. this.replaceWith(newelement);
  245. return newelement;
  246. };
  247.  
  248. //http://stackoverflow.com/questions/202605/repeat-string-javascript
  249. String.prototype.repeat = function(count) {
  250. if (count < 1) return '';
  251. var result = '', pattern = this.valueOf();
  252. while (count > 0) {
  253. if (count & 1) result += pattern;
  254. count >>= 1, pattern += pattern;
  255. }
  256. return result;
  257. };
  258.  
  259. function linum2int(input) { //jakob
  260. input = input.replace(/[^A-Za-z]/, '');
  261. output = 0;
  262. for (i = 0; i < input.length; i++) {
  263. output = output * 26 + parseInt(input.substr(i, 1), 26 + 10) - 9;
  264. }
  265. console.log('linum', output);
  266. return output;
  267. }
  268.  
  269. function int2linum(input) { //jakob
  270. // There's a quicker function that does the same on stackoverflow, but i wrote this one myself and im not sure about the license of the other one
  271. // http://stackoverflow.com/questions/8603480/how-to-create-a-function-that-converts-a-number-to-a-bijective-hexavigesimal/11506042#11506042
  272. var zeros = 0;
  273. var next = input;
  274. var generation = 0;
  275. while (next >= 27) {
  276. next = (next - 1) / 26 - (next - 1) % 26 / 26;
  277. zeros += next * Math.pow(27, generation);
  278. generation++;
  279. }
  280. output = (input + zeros).toString(27).replace(/./g, function ($0) {
  281. return '_abcdefghijklmnopqrstuvwxyz'.charAt(parseInt($0, 27));
  282. });
  283. return output;
  284. }
  285.  
  286. function roman2int(input) { //jakob
  287.  
  288. romans = {
  289. 'm': 1000,
  290. 'd': 500,
  291. 'c': 100,
  292. 'l': 50,
  293. 'x': 10,
  294. 'v': 5,
  295. 'i': 1
  296. };
  297. input = input.replace(/[^A-Za-z]/, '').toLowerCase();
  298. output = 0;
  299. highest = false;
  300. for (i = input.length - 1; i >= 0; i--) {
  301. num = romans[input.substr(i, 1)] || 0;
  302. highest = (num > highest ? num : highest);
  303. output = (num < highest ? (output - num) : (output + num));
  304. }
  305. return output;
  306. }
  307.  
  308. function int2roman(number) {
  309. // http://www.blackwasp.co.uk/NumberToRoman_2.aspx
  310. result = "";
  311. values = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
  312. numerals = ["m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i"];
  313.  
  314. for (i = 0; i < 13; i++) {
  315. while (number >= values[i]) {
  316. number -= values[i];
  317. result += numerals[i];
  318. }
  319. }
  320. return result;
  321. }
  322.  
  323. }
  324.  
  325. // Tatoeba specific Text-manipulation
  326. if(true){
  327. function tatoebaundo(text) {
  328. //console.log(text);
  329.  
  330. // undo the link shortening and fix its bugs
  331. // replace shortened link within inline markdown links or images
  332. // text = text.replace(/\(<a href="(.*?)">(.*?)<\/a>\)/gi, '\($1\)');
  333. // repair markdown forced links <http://example.com>
  334. text = text.replace(/&lt;<a href="(.*?)%3E">(.*?)&gt;<\/a>;/gim, function($0, $1, $2){ return '<'+unescape($1)+'>';});
  335. // repair link detection errors
  336. text = text.replace(/<a href="(.*?&amp;)">(.*?)<\/a>;/gim, function($0, $1, $2){ return '<'+unescape($1)+'>';});
  337.  
  338. // replace shortened link with its URL
  339. text = text.replace(/<a href="(.*?)">(.*?)<\/a>/gi, function($0, $1, $2){ return '<'+unescape($1)+'>';});
  340. // remove forced linebreaks (<br>)
  341. text = text.replace(/(<br\/*>)+/gim, "");
  342.  
  343. // replace shortened link within reference markdown links or images
  344. text = text.replace(/\[(.*)\]\: <a href="(.*)">(.*)<\/a>/gi, '[$1]: $2');
  345.  
  346. return text;
  347. }
  348.  
  349. function tatoedown(text) {
  350.  
  351. // mimik Tatoeba's HTML denial by displaying angle brackets as they are
  352. // this will be later reenabled further down, but in the end we maybe don't even want html to be parsed!!!
  353. text = text.replace(/</gim, "&lt;").replace(/>/gim, "&gt;");
  354.  
  355. // reenable html (Tatoeba doesn't allow HTML, so it displays the angle brackets as &lt; and &gt;)
  356. // however in the end we maybe don't even want html to be parsed!!!
  357. text = text.replace(/&lt;/gim, "<").replace(/&gt;/gim, ">");
  358.  
  359. // convert wiki-style headers "== header ==" with markdown style headers
  360. text = text.replace(/^\s*= (.*?) =\s*$/gim, '# $1 #').replace(/^\s*== (.*?) ==\s*$/gim, '## $1 ##').replace(/^\s*=== (.*) ===\s*$/gim, '### $1 ###').replace(/^\s*==== (.*?) ====\s*$/gim, '#### $1 ####').replace(/^\s*====== (.*?) ======\s*$/gim, '###### $1 ######').replace(/^\s*======= (.*?) =======\s*$/gim, '####### $1 #######');
  361.  
  362. return text;
  363. }
  364. }
  365.  
  366. // Markdown preview
  367. if(true){
  368. //
  369. // $.markeditGetHtml
  370. //
  371. $.fn.markeditGetHtml = function () {
  372.  
  373. /*
  374. // Load Showdown if it's not loaded
  375. if (typeof(MarkEditShowDown) === 'undefined') {
  376. if (typeof(Attacklab) === 'undefined') {
  377. throw 'Showdown.js (Attacklab.showdown) must be loaded before MarkEdit.';
  378. }
  379. MarkEditShowDown = new Attacklab.showdown.converter();
  380. }*/
  381.  
  382. // Render the preview
  383. var textarea = MarkEdit.getTextArea(this);
  384. var text = $(textarea).val();
  385. if (typeof (text) !== 'undefined') {
  386.  
  387. var text = $(this).val();
  388.  
  389. var html = Pandoc(tatoedown(tatoebaundo(text)));
  390. // html = html.replace(/\r/g, '');
  391. /* //this seems to be unneccessary for Tatoeba purposes
  392. // Convert newlines to <br/> inside a <p>
  393. var lineBreakInP = /(<p>(?:[\S\s](?!<\/p>))*)\n([\S\s]*?<\/p>)/g;
  394. var lineBreaksRemaining = lineBreakInP.exec(html);
  395.  
  396. while (lineBreaksRemaining !== null) {
  397. html = html.replace(lineBreakInP, '$1<br />$2');
  398. lineBreaksRemaining = lineBreakInP.exec(html);
  399. }
  400. */
  401.  
  402. return html;
  403. } else {
  404. return '';
  405. }
  406.  
  407. };
  408. }
  409.  
  410. // enable MarkEdit with live preview
  411. $('#SentenceCommentText, #WallContent, #UserDescription, #PrivateMessageContent').addClass('markedittextarea').markedit({
  412. 'preview': 'below',
  413. 'toolbar': {
  414. 'backgroundMode': 'light',
  415. 'layout': 'bold italic | link quote code image | numberlist bulletlist heading line | cite-sentence',
  416. 'buttons': [{
  417. // prepare the link toggle button
  418. // this should toggle between endnote and inline link
  419. // doesn'T work at all yet
  420. 'id': 'linktoggle',
  421. 'css': 'icon ui-state-default ui-corner-all',
  422. //ui-icon ui-icon-transferthick-e-w
  423. 'tip': 'click to toggle between endnote style and inline style',
  424. 'click': function () {
  425. //markedit = $(this).parentsUntil('.markedit').parent();
  426. //markedit.markeditSetLinkOrImage('http://example.com');
  427. },
  428. 'mouseover': function () {},
  429. 'mouseout': function () {}
  430. }, {
  431. 'id': 'cite-sentence',
  432. 'css': 'icon ui-state-default ui-corner-all',
  433. //ui-icon ui-icon-transferthick-e-w
  434. 'tip': 'cite the main sentence',
  435. 'click': function () {
  436. //find the textarea
  437. thetextarea = $('.markedittextarea');
  438. state = thetextarea.markeditGetState();
  439.  
  440. // insert sentence citation (the selection will be the proposed change;
  441. // if it's empty the whole sentence will be copied)
  442. state.beforeSelect = state.beforeSelect + '"' + $('.mainSentence .sentenceContent .text').text() + '" --> "';
  443. state.select = (state.select == "" ? $('.mainSentence .sentenceContent .text').text() : state.select);
  444. state.afterSelect = '"' + state.afterSelect;
  445.  
  446. thetextarea.markeditSetState(state);
  447. },
  448. 'mouseover': function () {},
  449. 'mouseout': function () {}
  450. }],
  451. }
  452. });
  453.  
  454. var profile = (window.location.href.split('/')[4] == 'user' && window.location.href.split('/')[5] == 'profile');
  455.  
  456. if (profile == true) {
  457. user = $('.profileSummary .username').text().trim();
  458. } else {
  459. user = '_';
  460. }
  461.  
  462. $('.comments .commentText, .wall .message .body, .profileDescription .content, .privateMessage .body').each(function ()
  463. {
  464. // determine the author of a comment or post
  465. if (profile == true) {
  466. author = user;
  467. } else {
  468. author = $(this).parentsUntil('li').parent().find('.meta .author:first').text().trim();
  469. }
  470. console.log(author);
  471. text = $(this).html();
  472.  
  473. // trim leading and trailing whitespace to avoid interpretation like code-blocks
  474. if($(this).is('.commentText')){
  475. text = text.substring(9, text.length-8);
  476. }
  477. else if($(this).parent().is('.root')){
  478. text = text.substring(16, text.length-14);
  479. }
  480. else if($(this).parent().is('.privateMessage')){
  481. text = text.substring(9, text.length-8);
  482. }
  483. else if($(this).parentsUntil('.replies').parent().is('.replies')){
  484. text = text.substring(17, text.length-12);
  485. }
  486.  
  487.  
  488. text = text.replace(/<br\/?>/g,'');
  489. $(this).html(text);
  490.  
  491. // prepare for parsing:
  492. text = Pandoc(tatoedown(tatoebaundo(text)));
  493.  
  494. // old parsing
  495. // MarkEditShowDown = new Attacklab.showdown.converter();
  496. // parsedmarkdown = $('<div class="parsedmarkdown"></div>').html(MarkEditShowDown.makeHtml(text));
  497.  
  498. // create the new element
  499. parsedmarkdown = $('<div class="parsedmarkdown"></div>').html(text);
  500. // copy the CSS classes to the new element
  501. parsedmarkdown.addClass($(this).attr("class")).hide();
  502. // hide the new element and put it below the original
  503. var pre = $(this);
  504. pre.after(parsedmarkdown);
  505. pre = pre.changeElementType("pre");
  506. pre.addClass('unparsedmarkdown');
  507. // add classes for later control of visibility
  508. //console.log(markdownusers[author]);
  509. if (markdownusers[author] == true) {
  510. pre.addClass('md_force');
  511. parsedmarkdown.addClass('md_force');
  512. } else if (markdownusers[author] == false) {
  513. pre.addClass('md_deny');
  514. parsedmarkdown.addClass('md_deny');
  515. } else {
  516. pre.addClass('md_normal');
  517. parsedmarkdown.addClass('md_normal');
  518. }
  519. });
  520.  
  521. if(true){
  522. // This mark was designed by Dustin Curtis, a villain. http://twitter.com/dcurtis
  523. markdownmark_normal = '<?xml version="1.0" encoding="utf-8"?> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="14" viewBox="0 0 208 128" style="vertical-align: text-bottom;" class="markdownmark normal"> <rect style="fill:none;stroke:white;stroke-width:10" width="198" height="118" x="5" y="5" ry="10" /> <path style="fill:white" d="m 30,98 0,-68 20,0 20,25 20,-25 20,0 0,68 -20,0 0,-39 -20,25 -20,-25 0,39 z" /> <path style="fill:white" d="m 155,98 -30,-33 20,0 0,-35 20,0 0,35 20,0 z" /> </svg>';
  524. markdownmark_solid = '<?xml version="1.0" encoding="utf-8"?> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="14" viewBox="0 0 208 128" style="vertical-align: text-bottom;" class="markdownmark solid"> <path d="M 15,0 C 6.7764862,0 0,6.7764862 0,15 l 0,98 c 0,8.22351 6.7764862,15 15,15 l 178,0 c 8.22351,0 15,-6.77649 15,-15 l 0,-98 C 208,6.7764862 201.22351,0 193,0 L 15,0 z m 15,30 20,0 20,25 20,-25 20,0 0,68 -20,0 0,-39 -20,25 -20,-25 0,39 -20,0 0,-68 z m 115,0 20,0 0,35 20,0 -30,33 -30,-33 20,0 0,-35 z" style="fill:white;" /> </svg>';
  525. // create a toggle "button" for switching between "on" and "all off"
  526. md_button = $('<a class="menuSection" id="md_button"><span class="state"></span>md<span id="mduser"></span></a>');
  527. md_button.html(markdownmark_normal);
  528. // add it a list called "menu"
  529. menu = $('<li id="md"></li>').append(md_button);
  530. // put it before the user menu in the navigation bar
  531. $('#user_menu > ul').prepend(menu);
  532. // the toggle function
  533. md_button.click(function () {
  534. console.log('md_button click');
  535. // get saved variables
  536. markdownusers = GM_getValue('markdownusers');
  537. markdownusers = markdownusers || default_markdownusers;
  538. markdownusers = JSON.parse(markdownusers);
  539. console.log('markdownusers: ' + JSON.stringify(markdownusers));
  540. // the '#' variable represents the on or all-off toggle
  541. // if the current state was "on" switch to "all-off"
  542. if (markdownusers['#'] == true) {
  543. console.log('all-off');
  544. // hide all parsed stuff in "all-off" state
  545. $('.parsedmarkdown, .markedit-preview').hide();
  546. $('.unparsedmarkdown').show();
  547. // update the button
  548. $('.state').html(markdownmark_solid);
  549. $('#md_button').html(markdownmark_solid);
  550. // for saving the state
  551. markdownusers['#'] = false;
  552. }
  553. // if the current state was "all-off", or not set, switch to "on"
  554. else {
  555. console.log('on');
  556. // switch the parsing on according to the current mode
  557. if (markdownusers['_'] == true) {
  558. $('.md_force').toggle();
  559. } else if (markdownusers['_'] == false) {
  560. $('.md_force, .md_normal, .md_deny').toggle();
  561. } else {
  562. $('.md_force, .md_normal').toggle();
  563. }
  564. // the preview shows in all modes when state is on
  565. $('.markedit-preview').show();
  566. // update the button
  567. $('.state').html(markdownmark_normal);
  568. $('#md_button').html(markdownmark_normal);
  569. // for saving the state
  570. markdownusers['#'] = true;
  571. }
  572. // save the new state
  573. GM_setValue('markdownusers', JSON.stringify(markdownusers));
  574. });
  575.  
  576. // create the mode switcher links
  577. md_force = $('<li><a id="md_force"><span class="state"></span>force !</a> </li>');
  578. md_normal = $('<li><a id="md_normal"><span class="state"></span>normal .</a> </li>');
  579. md_deny = $('<li><a id="md_deny"><span class="state"></span>deny /</a> </li>');
  580.  
  581. // create the mode switch list
  582. list = $('<ul class="sub-menu"></ul>');
  583. // add the mode switcher links to the mode switch list and put it to the menu
  584. menu.append(list.append(md_force, md_normal, md_deny));
  585. // switch to "md_force" mode: only contributions by opt-in users will be parsed
  586. md_force.click(function () {
  587. console.log('md_force click');
  588. if (profile == true) {
  589. markdownusers[author] = true;
  590. } else {
  591. markdownusers['_'] = true;
  592. }
  593. // save the new mode
  594. GM_setValue('markdownusers', JSON.stringify(markdownusers));
  595. $('#md_normal, #md_normal, #md_deny').parent().show();
  596. $('#md_force').attr('disabled', 'disabled');
  597. $('#md_normal, #md_deny').removeAttr('disabled');
  598. $('#mduser').text("!");
  599. // click twice to unset and reset, so the navigation menu shows the right state
  600. md_button.click().click();
  601. });
  602. // switch to "md_normal" mode: all contributions except the opt-out users will be parsed
  603. md_normal.click(function () {
  604. console.log('md_normal click');
  605. if (profile == true) {
  606. delete markdownusers[author];
  607. } else {
  608. delete markdownusers['_'];
  609. }
  610. // save the new mode
  611. GM_setValue('markdownusers', JSON.stringify(markdownusers));
  612. $('#md_normal, #md_normal, #md_deny').parent().show();
  613. $('#md_normal').attr('disabled', 'disabled');
  614. $('#md_force, #md_deny').removeAttr('disabled');
  615. $('#mduser').text(".");
  616. // click twice to unset and reset, so the navigation menu shows the right state
  617. md_button.click().click();
  618. });
  619. // switch to "md_deny" mode: all contributions, even the opt-out users, will be parsed
  620. md_deny.click(function () {
  621. console.log('md_deny click');
  622. if (profile == true) {
  623. markdownusers[author] = false;
  624. } else {
  625. markdownusers['_'] = false;
  626. }
  627. // save the new mode
  628. GM_setValue('markdownusers', JSON.stringify(markdownusers));
  629. $('#md_normal, #md_normal, #md_deny').parent().show();
  630. $('#md_deny').attr('disabled', 'disabled');
  631. $('#md_force, #md_normal').removeAttr('disabled');
  632. $('#mduser').text("/");
  633. // click twice to unset and reset, so the navigation menu shows the right state
  634. md_button.click().click();
  635. });
  636.  
  637. }
  638. if(false){
  639.  
  640. if (profile == true) {
  641. if (markdownusers[author] === true) {
  642. md_force.click();
  643. } else if (markdownusers[author] === false) {
  644. md_deny.click();
  645. } else {
  646. md_normal.click();
  647. }
  648. $('#md_normal, #md_normal, #md_deny, #md_button').css({
  649. 'font-style': 'italic'
  650. });
  651. } else {
  652. if (markdownusers['_'] === true) {
  653. md_force.click();
  654. } else if (markdownusers['_'] === false) {
  655. md_deny.click();
  656. } else {
  657. md_normal.click();
  658. }
  659.  
  660. }
  661.  
  662.  
  663. }