Markdown If Needed

在需要的地方启用MarkDown语法,添加格式帮助链接及 Markdown 工具栏

目前为 2017-06-16 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Markdown If Needed
  3. // @namespace wdssmq
  4. // @description 在需要的地方启用MarkDown语法,添加格式帮助链接及 Markdown 工具栏
  5. // @version 1.0.1
  6. // @link https://gf.qytechs.cn/zh-CN/scripts/29203
  7. // @author 沉冰浮水
  8. // @contributor JixunMoe
  9. // @contributor wOxxOm
  10. // @license MIT License
  11. // @include https://*
  12. // @include http://*
  13. // @grant GM_addStyle
  14. // ==/UserScript==
  15.  
  16. /* jshint multistr:true */
  17. function $n(e) {
  18. return document.querySelector(e);
  19. }
  20. function $na(e) {
  21. return document.querySelectorAll(e);
  22. }
  23.  
  24. function xml2md(xml) {
  25. var md = xml;
  26. if (xml.indexOf("isXML") > -1) {
  27. // 移除isXML
  28. md = md.replace(/\n?<!--isXML-->/g, "");
  29. //行内
  30.  
  31. //链接
  32. md = md.replace(/<a href="([^"]+)" title="([^"]+)"\s*([^>]*)>(.+)<\/a>/g,'[$4]($1 "$2"){$3}');
  33. //图片
  34. md = md.replace(/<img src="([^"]+)" alt="([^"]+)"[^>]*>/g,'![$2]($1)');
  35. // 段落
  36. md = md.replace(/<p>/g, "");
  37. md = md.replace(/<\/p>/g, "\n\n");
  38. // h1-h6
  39. md = md.replace(/<h6>(.+?)<\/h6>/g, "###### $1\n\n");
  40. md = md.replace(/<h5>(.+?)<\/h5>/g, "##### $1\n\n");
  41. md = md.replace(/<h4>(.+?)<\/h4>/g, "#### $1\n\n");
  42. md = md.replace(/<h3>(.+?)<\/h3>/g, "### $1\n\n");
  43. md = md.replace(/<h2>(.+?)<\/h2>/g, "## $1\n\n");
  44. md = md.replace(/<h1>(.+?)<\/h1>/g, "# $1\n\n");
  45. // 格式化换行
  46. md = md.replace(/\n\n+/g, "\n\n");
  47. md = md.replace(/\n+$/g, "");
  48. //修正
  49. md = md.replace(/\){}/g, ")");
  50. }
  51. return md;
  52. }
  53.  
  54. function md2xml(md) {
  55. var xml = md;
  56. if (md.indexOf("isXML") == -1) {
  57. // 格式化换行
  58. xml = xml.replace(/\n\n+/g, "\n\n");
  59. xml = xml.replace(/\n+$/g, "");
  60. // h1-h6
  61. xml = xml.replace(/(^|\n)######\s*([^\n]+)/g, "$1<h6>$2</h6>");
  62. xml = xml.replace(/(^|\n)#####\s*([^\n]+)/g, "$1<h5>$2</h5>");
  63. xml = xml.replace(/(^|\n)####\s*([^\n]+)/g, "$1<h4>$2</h4>");
  64. xml = xml.replace(/(^|\n)###\s*([^\n]+)/g, "$1<h3>$2</h3>");
  65. xml = xml.replace(/(^|\n)##\s*([^\n]+)/g, "$1<h2>$2</h2>");
  66. xml = xml.replace(/(^|\n)#\s*([^\n]+)/g, "$1<h1>$2</h1>");
  67. // 段落
  68. xml = xml.replace(/^(?!(<h|<p|<div))/g, "<p>");
  69. xml = xml.replace(/\n+(<h|<p|<div)/g, "</p>\n$1");
  70. xml = xml.replace(/\n\n/g, "</p>\n<p>");
  71. xml = xml.replace(/(p>|h\d>|div>)<\/p>/g, "$1");
  72. xml = xml.replace(/<p>$/g, "");
  73. xml = xml.replace(/<p>(?!<\/p>)(.+)$/g, "<p>$1</p>");
  74. // 行内标记
  75. xml = xml.replace(/([^\*]*)\*\*(.*)\*\*/g, "$1<b>$2</b>");
  76. xml = xml.replace(/([^\*]*)\*(.*)\*/g, "$1<i>$2</i>");
  77. //图片
  78. xml = xml.replace(/!\[([^\]]+)\]\(([^\s\)]+)[^\)]*\)/g, '<img src="$2" alt="$1" title="$1">');
  79. console.log(xml);
  80. //链接
  81. xml = xml.replace(/\[(.+)\]\(([^\s\)]+)\s*"?([^"]+)*"?\)(?:{([^}]+)})?/g, '<a href="$2" title="$3" $4>$1</a>');
  82. xml = xml.replace(/title=""/g,'title="点击链接查看"');
  83. // xml = xml.replace(/\[(.+)\]\(([^\s\)]+)\)/g, '<a href="$2">$1</a>');
  84.  
  85. //修正
  86. xml = xml.replace(/\s>/g,'>');
  87. xml = xml.replace(/2xml/g,"");
  88. // 添加 isXML
  89. xml += "\n<!--isXML-->";
  90. }
  91. return xml;
  92. }
  93.  
  94. window.addEventListener('DOMContentLoaded', function (e) {
  95. var domTxa = $n("textarea.md-needed");
  96.  
  97. if (!domTxa)
  98. return;
  99. domTxa.addEventListener('keyup', function () {
  100. if(domTxa.value.indexOf("2xml") > -1)
  101. domTxa.value = md2xml(domTxa.value);
  102. });
  103. $n("input[type=submit]").addEventListener('mouseenter', function () {
  104. domTxa.value = md2xml(domTxa.value);
  105. });
  106. $n("input[type=submit]").addEventListener('mouseout', function () {
  107. domTxa.value = xml2md(domTxa.value);
  108. });
  109. $n(".md-toolbar").innerHTML = "<i style=\"clear:both;display: table;\"></i>";
  110.  
  111. //添加工具栏
  112. addFeatures(domTxa);
  113.  
  114. GM_addStyle('\
  115. .md-button {\
  116. display: inline-block;\
  117. cursor: pointer;\
  118. margin: 0px;\
  119. font-size: 12px;\
  120. line-height: 1;\
  121. font-weight: bold;\
  122. padding: 4px 6px;\
  123. background: -moz-linear-gradient(center bottom , #CCC 0%, #FAFAFA 100%) repeat scroll 0% 0% #F8F8F8;\
  124. border: 1px solid #999;\
  125. border-radius: 2px;\
  126. white-space: nowrap;\
  127. text-shadow: 0px 1px 0px #FFF;\
  128. box-shadow: 0px 1px 0px #FFF inset, 0px -1px 2px #BBB inset;\
  129. color: #333;}\
  130. .md-toolbar {\
  131. clear: both;\
  132. padding: 0;\
  133. margin: 1px 1px 3px;\
  134. }');
  135. });
  136.  
  137. function addFeatures(n) {
  138. if (!n)
  139. return;
  140. // add buttons
  141. // btnMake(n, '<b>Test</b>', "test", function (e) {
  142. // n.value = md2xml(n.value)
  143. // });
  144. btnMake(n, '<b>' + __('B') + '</b>', __('Bold'), '**');
  145. btnMake(n, '<i>' + __('I') + '</i>', __('Italic'), '*');
  146. btnMake(n, '<u>' + __('U') + '</u>', __('Underline'), '<u>', '</u>');
  147. btnMake(n, '<s>' + __('S') + '</s>', __('Strikethrough'), '<s>', '</s>');
  148. btnMake(n, '&lt;br&gt;', __('Force line break'), '<br>', '', true);
  149. btnMake(n, '---', __('Horizontal line'), '\n\n---\n\n', '', true);
  150. btnMake(n, __('URL'), __('Add URL to selected text'),
  151. function (e) {
  152. try {
  153. edWrapInTag('[', '](' + prompt(__('URL') + ':') + ')', edInit(e.target));
  154. } catch (ex) {}
  155. });
  156. btnMake(n, __('Image (https)'), __('Convert selected https://url to inline image'), '![' + __('image') + '](', ')');
  157. btnMake(n, __('Table'), __('Insert table template'), __('\n| head1 | head2 |\n|-------|-------|\n| cell1 | cell2 |\n| cell3 | cell4 |\n'), '', true);
  158. btnMake(n, __('Code'), __('Apply CODE markdown to selected text'),
  159. function (e) {
  160. var ed = edInit(e.target);
  161. if (ed.sel.indexOf('\n') < 0)
  162. edWrapInTag('`', '`', ed);
  163. else
  164. edWrapInTag(((ed.sel1 === 0) || (ed.text.charAt(ed.sel1 - 1) == '\n') ? '' : '\n') + '```' + (ed.sel.charAt(0) == '\n' ? '' : '\n'),
  165. (ed.sel.substr(-1) == '\n' ? '' : '\n') + '```' + (ed.text.substr(ed.sel2, 1) == '\n' ? '' : '\n'),
  166. ed);
  167. });
  168. }
  169.  
  170. function btnMake(elTxa, label, title, tag1_or_cb, tag2, noWrap) {
  171. var a = document.createElement('a');
  172. a.className = 'md-button';
  173. a.innerHTML = label;
  174. a.title = title;
  175. a.style.setProperty('float', 'right');
  176. a.addEventListener('click',
  177. typeof(tag1_or_cb) == 'function' ? tag1_or_cb
  178. : noWrap ? function (e) {
  179. edInsertText(tag1_or_cb, edInit(e.target));
  180. }
  181. : function (e) {
  182. edWrapInTag(tag1_or_cb, tag2, edInit(e.target));
  183. });
  184. var elToolbar = elTxa.parentNode.querySelector('.md-toolbar');
  185. // console.log(elToolbar);
  186. a.textAreaNode = elTxa;
  187. elToolbar.insertBefore(a, elToolbar.firstElementChild);
  188. }
  189.  
  190. function edInit(btn) {
  191. var ed = {
  192. node: btn.textAreaNode
  193. };
  194. ed.sel1 = ed.node.selectionStart;
  195. ed.sel2 = ed.node.selectionEnd,
  196. ed.text = ed.node.value;
  197. ed.sel = ed.text.substring(ed.sel1, ed.sel2);
  198. return ed;
  199. }
  200.  
  201. function edWrapInTag(tag1, tag2, ed) {
  202. ed.node.value = ed.text.substr(0, ed.sel1) + tag1 + ed.sel + (tag2 ? tag2 : tag1) + ed.text.substr(ed.sel2);
  203. ed.node.setSelectionRange(ed.sel1 + tag1.length, ed.sel1 + tag1.length + ed.sel.length);
  204. ed.node.focus();
  205. }
  206.  
  207. function edInsertText(text, ed) {
  208. ed.node.value = ed.text.substr(0, ed.sel2) + text + ed.text.substr(ed.sel2);
  209. ed.node.setSelectionRange(ed.sel2 + text.length, ed.sel2 + text.length);
  210. ed.node.focus();
  211. }
  212.  
  213. var __ = (function (l, langs) {
  214. var lang = langs[l] || langs[l.replace(/-.+/, '')];
  215. return lang ? function (text) {
  216. return lang[text] || text;
  217. }
  218. : function (text) {
  219. return text;
  220. }; // No matching language, fallback to english
  221. })("zh-CN", {
  222. // Can be full name, or just the beginning part.
  223. 'zh-CN': {
  224. 'Bold': '粗体',
  225. 'Italic': '斜体',
  226. 'Underline': '下划线',
  227. 'Strikethrough': '删除线',
  228. 'Force line break': '强制换行',
  229. 'Horizontal line': '水平分割线',
  230. 'URL': '链接',
  231. 'Add URL to selected text': '为所选文字添加链接',
  232. 'Image (https)': '图片 (https)',
  233. 'Convert selected https://url to inline image': '将所选地址转换为行内图片',
  234. 'image': '图片描述', // Default image alt value
  235. 'Table': '表格',
  236. 'Insert table template': '插入表格模板',
  237. 'Code': '代码',
  238. 'Apply CODE markdown to selected text': '将选中代码围起来',
  239.  
  240. '\n| head1 | head2 |\n|-------|-------|\n| cell1 | cell2 |\n| cell3 | cell4 |\n':
  241. '\n| 表头 1 | 表头 2 |\n|-------|-------|\n| 表格 1 | 表格 2 |\n| 表格 3 | 表格 4 |\n'
  242. },
  243. 'ru': {
  244. 'B': 'Ж',
  245. 'I': 'К',
  246. 'U': 'Ч',
  247. 'S': 'П',
  248. 'Bold': 'Жирный',
  249. 'Italic': 'Курсив',
  250. 'Underline': 'Подчеркнутый',
  251. 'Strikethrough': 'Перечеркнутый',
  252. 'Force line break': 'Новая строка',
  253. 'Horizontal line': 'Горизонтальная линия',
  254. 'URL': 'ссылка',
  255. 'Add URL to selected text': 'Добавить ссылку к выделенному тексту',
  256. 'Image (https)': 'Картинка (https)',
  257. 'Convert selected https://url to inline image': 'Преобразовать выделенный https:// адрес в картинку',
  258. 'image': 'картинка', // Default image alt value
  259. 'Table': 'Таблица',
  260. 'Insert table template': 'Вставить шаблон таблицы',
  261. 'Code': 'Код',
  262. 'Apply CODE markdown to selected text': 'Пометить выделенный фрагмент как программный код',
  263.  
  264. '\n| head1 | head2 |\n|-------|-------|\n| cell1 | cell2 |\n| cell3 | cell4 |\n':
  265. '\n| заголовок1 | заголовок2 |\n|-------|-------|\n| ячейка1 | ячейка2 |\n| ячейка3 | ячейка4 |\n'
  266. },
  267. 'fr': {
  268. 'B': 'G',
  269. 'I': 'I',
  270. 'U': 'S',
  271. 'S': 'B',
  272. 'Bold': 'Gras',
  273. 'Italic': 'Italique',
  274. 'Underline': 'Souligné',
  275. 'Strikethrough': 'Barré',
  276. 'Force line break': 'Forcer le saut de ligne',
  277. 'Horizontal line': 'Ligne horizontale',
  278. 'URL': 'URL',
  279. 'Add URL to selected text': 'Ajouter URL au texte sélectionné',
  280. 'Image (https)': 'Image (https)',
  281. 'Convert selected https://url to inline image': 'Convertir https://url sélectionnés en images',
  282. 'image': 'image', // Default image alt value
  283. 'Table': 'Tableau',
  284. 'Insert table template': 'Insérer un modèle de table',
  285. 'Code': 'Code',
  286. 'Apply CODE markdown to selected text': 'Appliquer CODE markdown au texte sélectionné',
  287.  
  288. '\n| head1 | head2 |\n|-------|-------|\n| cell1 | cell2 |\n| cell3 | cell4 |\n':
  289. '\n| En-tête 1 | En-tête 2 |\n|-------|-------|\n| cellule 1 | cellule 2 |\n| cellule 3 | cellule 4 |\n'
  290. }
  291. });

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址