// ==UserScript== // @name Markdown If Needed // @namespace wdssmq // @description 在需要的地方启用MarkDown语法,添加格式帮助链接及 Markdown 工具栏 // @version 1.0.1 // @link https://greasyfork.org/zh-CN/scripts/29203 // @author 沉冰浮水 // @contributor JixunMoe // @contributor wOxxOm // @license MIT License // @include https://* // @include http://* // @grant GM_addStyle // @downloadURL none // ==/UserScript== /* jshint multistr:true */ function $n(e) { return document.querySelector(e); } function $na(e) { return document.querySelectorAll(e); } function xml2md(xml) { var md = xml; if (xml.indexOf("isXML") > -1) { // 移除isXML md = md.replace(/\n?/g, ""); //行内 //链接 md = md.replace(/]*)>(.+)<\/a>/g,'[$4]($1 "$2"){$3}'); //图片 md = md.replace(/([^]*>/g,'![$2]($1)'); // 段落 md = md.replace(/

/g, ""); md = md.replace(/<\/p>/g, "\n\n"); // h1-h6 md = md.replace(/

(.+?)<\/h6>/g, "###### $1\n\n"); md = md.replace(/
(.+?)<\/h5>/g, "##### $1\n\n"); md = md.replace(/

(.+?)<\/h4>/g, "#### $1\n\n"); md = md.replace(/

(.+?)<\/h3>/g, "### $1\n\n"); md = md.replace(/

(.+?)<\/h2>/g, "## $1\n\n"); md = md.replace(/

(.+?)<\/h1>/g, "# $1\n\n"); // 格式化换行 md = md.replace(/\n\n+/g, "\n\n"); md = md.replace(/\n+$/g, ""); //修正 md = md.replace(/\){}/g, ")"); } return md; } function md2xml(md) { var xml = md; if (md.indexOf("isXML") == -1) { // 格式化换行 xml = xml.replace(/\n\n+/g, "\n\n"); xml = xml.replace(/\n+$/g, ""); // h1-h6 xml = xml.replace(/(^|\n)######\s*([^\n]+)/g, "$1

$2
"); xml = xml.replace(/(^|\n)#####\s*([^\n]+)/g, "$1
$2
"); xml = xml.replace(/(^|\n)####\s*([^\n]+)/g, "$1

$2

"); xml = xml.replace(/(^|\n)###\s*([^\n]+)/g, "$1

$2

"); xml = xml.replace(/(^|\n)##\s*([^\n]+)/g, "$1

$2

"); xml = xml.replace(/(^|\n)#\s*([^\n]+)/g, "$1

$2

"); // 段落 xml = xml.replace(/^(?!("); xml = xml.replace(/\n+(\n$1"); xml = xml.replace(/\n\n/g, "

\n

"); xml = xml.replace(/(p>|h\d>|div>)<\/p>/g, "$1"); xml = xml.replace(/

$/g, ""); xml = xml.replace(/

(?!<\/p>)(.+)$/g, "

$1

"); // 行内标记 xml = xml.replace(/([^\*]*)\*\*(.*)\*\*/g, "$1$2"); xml = xml.replace(/([^\*]*)\*(.*)\*/g, "$1$2"); //图片 xml = xml.replace(/!\[([^\]]+)\]\(([^\s\)]+)[^\)]*\)/g, '$1'); console.log(xml); //链接 xml = xml.replace(/\[(.+)\]\(([^\s\)]+)\s*"?([^"]+)*"?\)(?:{([^}]+)})?/g, '
$1'); xml = xml.replace(/title=""/g,'title="点击链接查看"'); // xml = xml.replace(/\[(.+)\]\(([^\s\)]+)\)/g, '$1'); //修正 xml = xml.replace(/\s>/g,'>'); xml = xml.replace(/2xml/g,""); // 添加 isXML xml += "\n"; } return xml; } window.addEventListener('DOMContentLoaded', function (e) { var domTxa = $n("textarea.md-needed"); if (!domTxa) return; domTxa.addEventListener('keyup', function () { if(domTxa.value.indexOf("2xml") > -1) domTxa.value = md2xml(domTxa.value); }); $n("input[type=submit]").addEventListener('mouseenter', function () { domTxa.value = md2xml(domTxa.value); }); $n("input[type=submit]").addEventListener('mouseout', function () { domTxa.value = xml2md(domTxa.value); }); $n(".md-toolbar").innerHTML = ""; //添加工具栏 addFeatures(domTxa); GM_addStyle('\ .md-button {\ display: inline-block;\ cursor: pointer;\ margin: 0px;\ font-size: 12px;\ line-height: 1;\ font-weight: bold;\ padding: 4px 6px;\ background: -moz-linear-gradient(center bottom , #CCC 0%, #FAFAFA 100%) repeat scroll 0% 0% #F8F8F8;\ border: 1px solid #999;\ border-radius: 2px;\ white-space: nowrap;\ text-shadow: 0px 1px 0px #FFF;\ box-shadow: 0px 1px 0px #FFF inset, 0px -1px 2px #BBB inset;\ color: #333;}\ .md-toolbar {\ clear: both;\ padding: 0;\ margin: 1px 1px 3px;\ }'); }); function addFeatures(n) { if (!n) return; // add buttons // btnMake(n, 'Test', "test", function (e) { // n.value = md2xml(n.value) // }); btnMake(n, '' + __('B') + '', __('Bold'), '**'); btnMake(n, '' + __('I') + '', __('Italic'), '*'); btnMake(n, '' + __('U') + '', __('Underline'), '', ''); btnMake(n, '' + __('S') + '', __('Strikethrough'), '', ''); btnMake(n, '<br>', __('Force line break'), '
', '', true); btnMake(n, '---', __('Horizontal line'), '\n\n---\n\n', '', true); btnMake(n, __('URL'), __('Add URL to selected text'), function (e) { try { edWrapInTag('[', '](' + prompt(__('URL') + ':') + ')', edInit(e.target)); } catch (ex) {} }); btnMake(n, __('Image (https)'), __('Convert selected https://url to inline image'), '![' + __('image') + '](', ')'); btnMake(n, __('Table'), __('Insert table template'), __('\n| head1 | head2 |\n|-------|-------|\n| cell1 | cell2 |\n| cell3 | cell4 |\n'), '', true); btnMake(n, __('Code'), __('Apply CODE markdown to selected text'), function (e) { var ed = edInit(e.target); if (ed.sel.indexOf('\n') < 0) edWrapInTag('`', '`', ed); else edWrapInTag(((ed.sel1 === 0) || (ed.text.charAt(ed.sel1 - 1) == '\n') ? '' : '\n') + '```' + (ed.sel.charAt(0) == '\n' ? '' : '\n'), (ed.sel.substr(-1) == '\n' ? '' : '\n') + '```' + (ed.text.substr(ed.sel2, 1) == '\n' ? '' : '\n'), ed); }); } function btnMake(elTxa, label, title, tag1_or_cb, tag2, noWrap) { var a = document.createElement('a'); a.className = 'md-button'; a.innerHTML = label; a.title = title; a.style.setProperty('float', 'right'); a.addEventListener('click', typeof(tag1_or_cb) == 'function' ? tag1_or_cb : noWrap ? function (e) { edInsertText(tag1_or_cb, edInit(e.target)); } : function (e) { edWrapInTag(tag1_or_cb, tag2, edInit(e.target)); }); var elToolbar = elTxa.parentNode.querySelector('.md-toolbar'); // console.log(elToolbar); a.textAreaNode = elTxa; elToolbar.insertBefore(a, elToolbar.firstElementChild); } function edInit(btn) { var ed = { node: btn.textAreaNode }; ed.sel1 = ed.node.selectionStart; ed.sel2 = ed.node.selectionEnd, ed.text = ed.node.value; ed.sel = ed.text.substring(ed.sel1, ed.sel2); return ed; } function edWrapInTag(tag1, tag2, ed) { ed.node.value = ed.text.substr(0, ed.sel1) + tag1 + ed.sel + (tag2 ? tag2 : tag1) + ed.text.substr(ed.sel2); ed.node.setSelectionRange(ed.sel1 + tag1.length, ed.sel1 + tag1.length + ed.sel.length); ed.node.focus(); } function edInsertText(text, ed) { ed.node.value = ed.text.substr(0, ed.sel2) + text + ed.text.substr(ed.sel2); ed.node.setSelectionRange(ed.sel2 + text.length, ed.sel2 + text.length); ed.node.focus(); } var __ = (function (l, langs) { var lang = langs[l] || langs[l.replace(/-.+/, '')]; return lang ? function (text) { return lang[text] || text; } : function (text) { return text; }; // No matching language, fallback to english })("zh-CN", { // Can be full name, or just the beginning part. 'zh-CN': { 'Bold': '粗体', 'Italic': '斜体', 'Underline': '下划线', 'Strikethrough': '删除线', 'Force line break': '强制换行', 'Horizontal line': '水平分割线', 'URL': '链接', 'Add URL to selected text': '为所选文字添加链接', 'Image (https)': '图片 (https)', 'Convert selected https://url to inline image': '将所选地址转换为行内图片', 'image': '图片描述', // Default image alt value 'Table': '表格', 'Insert table template': '插入表格模板', 'Code': '代码', 'Apply CODE markdown to selected text': '将选中代码围起来', '\n| head1 | head2 |\n|-------|-------|\n| cell1 | cell2 |\n| cell3 | cell4 |\n': '\n| 表头 1 | 表头 2 |\n|-------|-------|\n| 表格 1 | 表格 2 |\n| 表格 3 | 表格 4 |\n' }, 'ru': { 'B': 'Ж', 'I': 'К', 'U': 'Ч', 'S': 'П', 'Bold': 'Жирный', 'Italic': 'Курсив', 'Underline': 'Подчеркнутый', 'Strikethrough': 'Перечеркнутый', 'Force line break': 'Новая строка', 'Horizontal line': 'Горизонтальная линия', 'URL': 'ссылка', 'Add URL to selected text': 'Добавить ссылку к выделенному тексту', 'Image (https)': 'Картинка (https)', 'Convert selected https://url to inline image': 'Преобразовать выделенный https:// адрес в картинку', 'image': 'картинка', // Default image alt value 'Table': 'Таблица', 'Insert table template': 'Вставить шаблон таблицы', 'Code': 'Код', 'Apply CODE markdown to selected text': 'Пометить выделенный фрагмент как программный код', '\n| head1 | head2 |\n|-------|-------|\n| cell1 | cell2 |\n| cell3 | cell4 |\n': '\n| заголовок1 | заголовок2 |\n|-------|-------|\n| ячейка1 | ячейка2 |\n| ячейка3 | ячейка4 |\n' }, 'fr': { 'B': 'G', 'I': 'I', 'U': 'S', 'S': 'B', 'Bold': 'Gras', 'Italic': 'Italique', 'Underline': 'Souligné', 'Strikethrough': 'Barré', 'Force line break': 'Forcer le saut de ligne', 'Horizontal line': 'Ligne horizontale', 'URL': 'URL', 'Add URL to selected text': 'Ajouter URL au texte sélectionné', 'Image (https)': 'Image (https)', 'Convert selected https://url to inline image': 'Convertir https://url sélectionnés en images', 'image': 'image', // Default image alt value 'Table': 'Tableau', 'Insert table template': 'Insérer un modèle de table', 'Code': 'Code', 'Apply CODE markdown to selected text': 'Appliquer CODE markdown au texte sélectionné', '\n| head1 | head2 |\n|-------|-------|\n| cell1 | cell2 |\n| cell3 | cell4 |\n': '\n| En-tête 1 | En-tête 2 |\n|-------|-------|\n| cellule 1 | cellule 2 |\n| cellule 3 | cellule 4 |\n' } });